
After a38edab7c8
(Makefile: generate doc versions via GIT-VERSION-GEN,
2024-12-06), we no longer inject GIT_DATE when building with
Asciidoctor.
Replace the <date/> tag in the XML to inject the value of GIT_DATE.
Unlike <refmiscinfo/> as handled in a recent commit, we have no reason
to expect that this tag might be missing, so there's no need for "maybe
remove, then add" and we can just outright replace the one that
Asciidoctor has generated based on the mtime of the source file.
Compared to pre-a38edab7c8, we now end up injecting this also in the
build of Git.3pm, which until now has been using the mtime of Git.pm.
That is arguably even a good change since it results in more
reproducible builds.
Signed-off-by: Martin Ågren <martin.agren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
135 lines
5.2 KiB
Ruby
135 lines
5.2 KiB
Ruby
require 'asciidoctor'
|
|
require 'asciidoctor/extensions'
|
|
require 'asciidoctor/converter/docbook5'
|
|
require 'asciidoctor/converter/html5'
|
|
|
|
module Git
|
|
module Documentation
|
|
class LinkGitProcessor < Asciidoctor::Extensions::InlineMacroProcessor
|
|
use_dsl
|
|
|
|
named :chrome
|
|
|
|
def process(parent, target, attrs)
|
|
prefix = parent.document.attr('git-relative-html-prefix')
|
|
if parent.document.doctype == 'book'
|
|
"<ulink url=\"#{prefix}#{target}.html\">" \
|
|
"#{target}(#{attrs[1]})</ulink>"
|
|
elsif parent.document.basebackend? 'html'
|
|
%(<a href="#{prefix}#{target}.html">#{target}(#{attrs[1]})</a>)
|
|
elsif parent.document.basebackend? 'docbook'
|
|
"<citerefentry>\n" \
|
|
"<refentrytitle>#{target}</refentrytitle>" \
|
|
"<manvolnum>#{attrs[1]}</manvolnum>\n" \
|
|
"</citerefentry>"
|
|
end
|
|
end
|
|
end
|
|
|
|
class DocumentPostProcessor < Asciidoctor::Extensions::Postprocessor
|
|
def process document, output
|
|
if document.basebackend? 'docbook'
|
|
output = output.sub(/<refmiscinfo class="source">.*?<\/refmiscinfo>/, "")
|
|
output = output.sub(/<refmiscinfo class="manual">.*?<\/refmiscinfo>/, "")
|
|
output = output.sub(/<date>.*?<\/date>/, "<date>@GIT_DATE@</date>")
|
|
new_tags = "" \
|
|
"<refmiscinfo class=\"source\">Git @GIT_VERSION@</refmiscinfo>\n" \
|
|
"<refmiscinfo class=\"manual\">Git Manual</refmiscinfo>\n"
|
|
output = output.sub(/<\/refmeta>/, new_tags + "</refmeta>")
|
|
end
|
|
output
|
|
end
|
|
end
|
|
|
|
class SynopsisBlock < Asciidoctor::Extensions::BlockProcessor
|
|
|
|
use_dsl
|
|
named :synopsis
|
|
parse_content_as :simple
|
|
|
|
def process parent, reader, attrs
|
|
outlines = reader.lines.map do |l|
|
|
l.gsub(/(\.\.\.?)([^\]$.])/, '`\1`\2')
|
|
.gsub(%r{([\[\] |()>]|^)([-a-zA-Z0-9:+=~@,/_^\$]+)}, '\1{empty}`\2`{empty}')
|
|
.gsub(/(<[-a-zA-Z0-9.]+>)/, '__\\1__')
|
|
.gsub(']', ']{empty}')
|
|
end
|
|
create_block parent, :verse, outlines, attrs
|
|
end
|
|
end
|
|
|
|
class GitDBConverter < Asciidoctor::Converter::DocBook5Converter
|
|
|
|
extend Asciidoctor::Converter::Config
|
|
register_for 'docbook5'
|
|
|
|
def convert_inline_quoted node
|
|
if (type = node.type) == :asciimath
|
|
# NOTE fop requires jeuclid to process mathml markup
|
|
asciimath_available? ? %(<inlineequation>#{(::AsciiMath.parse node.text).to_mathml 'mml:', 'xmlns:mml' => 'http://www.w3.org/1998/Math/MathML'}</inlineequation>) : %(<inlineequation><mathphrase><![CDATA[#{node.text}]]></mathphrase></inlineequation>)
|
|
elsif type == :latexmath
|
|
# unhandled math; pass source to alt and required mathphrase element; dblatex will process alt as LaTeX math
|
|
%(<inlineequation><alt><![CDATA[#{equation = node.text}]]></alt><mathphrase><![CDATA[#{equation}]]></mathphrase></inlineequation>)
|
|
elsif type == :monospaced
|
|
node.text.gsub(/(\.\.\.?)([^\]$.])/, '<literal>\1</literal>\2')
|
|
.gsub(%r{([\[\s|()>.]|^|\]|>)(\.?([-a-zA-Z0-9:+=~@,/_^\$]+\.{0,2})+)}, '\1<literal>\2</literal>')
|
|
.gsub(/(<[-a-zA-Z0-9.]+>)/, '<emphasis>\1</emphasis>')
|
|
else
|
|
open, close, supports_phrase = QUOTE_TAGS[type]
|
|
text = node.text
|
|
if node.role
|
|
if supports_phrase
|
|
quoted_text = %(#{open}<phrase role="#{node.role}">#{text}</phrase>#{close})
|
|
else
|
|
quoted_text = %(#{open.chop} role="#{node.role}">#{text}#{close})
|
|
end
|
|
else
|
|
quoted_text = %(#{open}#{text}#{close})
|
|
end
|
|
node.id ? %(<anchor#{common_attributes node.id, nil, text}/>#{quoted_text}) : quoted_text
|
|
end
|
|
end
|
|
end
|
|
|
|
# register a html5 converter that takes in charge to convert monospaced text into Git style synopsis
|
|
class GitHTMLConverter < Asciidoctor::Converter::Html5Converter
|
|
|
|
extend Asciidoctor::Converter::Config
|
|
register_for 'html5'
|
|
|
|
def convert_inline_quoted node
|
|
if node.type == :monospaced
|
|
node.text.gsub(/(\.\.\.?)([^\]$.])/, '<code>\1</code>\2')
|
|
.gsub(%r{([\[\s|()>.]|^|\]|>)(\.?([-a-zA-Z0-9:+=~@,/_^\$]+\.{0,2})+)}, '\1<code>\2</code>')
|
|
.gsub(/(<[-a-zA-Z0-9.]+>)/, '<em>\1</em>')
|
|
|
|
else
|
|
open, close, tag = QUOTE_TAGS[node.type]
|
|
if node.id
|
|
class_attr = node.role ? %( class="#{node.role}") : ''
|
|
if tag
|
|
%(#{open.chop} id="#{node.id}"#{class_attr}>#{node.text}#{close})
|
|
else
|
|
%(<span id="#{node.id}"#{class_attr}>#{open}#{node.text}#{close}</span>)
|
|
end
|
|
elsif node.role
|
|
if tag
|
|
%(#{open.chop} class="#{node.role}">#{node.text}#{close})
|
|
else
|
|
%(<span class="#{node.role}">#{open}#{node.text}#{close}</span>)
|
|
end
|
|
else
|
|
%(#{open}#{node.text}#{close})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
Asciidoctor::Extensions.register do
|
|
inline_macro Git::Documentation::LinkGitProcessor, :linkgit
|
|
block Git::Documentation::SynopsisBlock
|
|
postprocessor Git::Documentation::DocumentPostProcessor
|
|
end
|