2017-01-26 00:13:44 +00:00
|
|
|
require 'asciidoctor'
|
|
|
|
require 'asciidoctor/extensions'
|
2024-09-24 07:08:48 +00:00
|
|
|
require 'asciidoctor/converter/docbook5'
|
|
|
|
require 'asciidoctor/converter/html5'
|
2017-01-26 00:13:44 +00:00
|
|
|
|
|
|
|
module Git
|
|
|
|
module Documentation
|
|
|
|
class LinkGitProcessor < Asciidoctor::Extensions::InlineMacroProcessor
|
|
|
|
use_dsl
|
|
|
|
|
|
|
|
named :chrome
|
|
|
|
|
|
|
|
def process(parent, target, attrs)
|
2019-09-22 11:57:58 +00:00
|
|
|
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'
|
asciidoctor-extensions: fix spurious space after linkgit
When we render, e.g., "linkgit:gitglossary[7]." with Asciidoctor, we get
"gitglossary(7) ." with a space between the linkgit macro expansion and
the punctuation. We can fix this by dropping the trailing newline after
we've turned `linkgit:foo[bar]` into `<citerefentry>..</citerefentry>`.
The diff produced by `USE_ASCIIDOCTOR=Yes ./doc-diff HEAD^ HEAD` is
almost 6000 lines large and shows how this fixes "git-foo(x) ,", "(see
git-bar(y) )" and so on. One might wonder whether this also turns, e.g.,
"see linkgit:foo[1] for more" into "see foo(1)for more", but no. We get
"...</citerefentry> for more" in the XML, see, e.g., git-am.xml, so the
space ends up in git-am.1 just fine. The same is true for the HTML output.
Signed-off-by: Martin Ågren <martin.agren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-02-27 18:17:54 +00:00
|
|
|
%(<a href="#{prefix}#{target}.html">#{target}(#{attrs[1]})</a>)
|
2017-01-26 00:13:44 +00:00
|
|
|
elsif parent.document.basebackend? 'docbook'
|
|
|
|
"<citerefentry>\n" \
|
|
|
|
"<refentrytitle>#{target}</refentrytitle>" \
|
|
|
|
"<manvolnum>#{attrs[1]}</manvolnum>\n" \
|
asciidoctor-extensions: fix spurious space after linkgit
When we render, e.g., "linkgit:gitglossary[7]." with Asciidoctor, we get
"gitglossary(7) ." with a space between the linkgit macro expansion and
the punctuation. We can fix this by dropping the trailing newline after
we've turned `linkgit:foo[bar]` into `<citerefentry>..</citerefentry>`.
The diff produced by `USE_ASCIIDOCTOR=Yes ./doc-diff HEAD^ HEAD` is
almost 6000 lines large and shows how this fixes "git-foo(x) ,", "(see
git-bar(y) )" and so on. One might wonder whether this also turns, e.g.,
"see linkgit:foo[1] for more" into "see foo(1)for more", but no. We get
"...</citerefentry> for more" in the XML, see, e.g., git-am.xml, so the
space ends up in git-am.1 just fine. The same is true for the HTML output.
Signed-off-by: Martin Ågren <martin.agren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-02-27 18:17:54 +00:00
|
|
|
"</citerefentry>"
|
2017-01-26 00:13:44 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
asciidoctor-extensions: provide `<refmiscinfo/>`
As can be seen from the previous commit, there are three attributes that
we provide to AsciiDoc through asciidoc.conf. Asciidoctor ignores that
file. After that patch, newer versions of Asciidoctor pick up the
`manmanual` and `mansource` attributes as we invoke `asciidoctor`, but
they don't pick up `manversion`. ([1] says: "Not used by Asciidoctor.")
Older versions (<1.5.7) don't handle these attributes at all. As a
result, we are missing one or three `<refmiscinfo/>` tags in each
xml-file produced when we build with Asciidoctor.
Because of this, xmlto doesn't include the Git version number in the
rendered manpages. And in particular, with versions <1.5.7, the manpage
footers instead contain the fairly ugly "[FIXME: source]".
That Asciidoctor ignores asciidoc.conf is nothing new. This is why we
implement the `linkgit:` macro in asciidoc.conf *and* in
asciidoctor-extensions.rb. Follow suit and provide these tags in
asciidoctor-extensions.rb, using a "postprocessor" extension where we
just search and replace in the XML, treated as text.
We may consider a few alternatives:
* Inject these lines into the xml-files from the *Makefile*, e.g.,
using `sed`. That would reduce repetition, but it feels wrong to
impose another step and another risk on the AsciiDoc-processing only
to benefit the Asciidoctor-one.
* I tried providing a "docinfo processor" to inject these tags, but
could not figure out how to "merge" the two <refmeta/> sections that
resulted. To avoid xmlto barfing on the result, I needed to use
`xmlto --skip-validation ...`, which seems unfortunate.
Let's instead inject the missing tags using a postprocessor. We'll make
it fairly obvious that we aim to inject the exact same three lines of
`<refmiscinfo/>` that asciidoc.conf provides. We inject them in
*post*-processing so we need to do the variable expansion ourselves. We
do introduce the bug that asciidoc.conf already has in that we won't do
any escaping, e.g., of funky versions like "some v <2.25, >2.20".
The postprocessor we add here works on the XML as raw text and doesn't
really use the full potential of XML to do a more structured injection.
This is actually precisely what the Asciidoctor User Manual does in its
postprocessor example [2]. I looked into two other approaches:
1. The nokogiri library is apparently the "modern" way of doing XML
in ruby. I got it working fairly easily:
require 'nokogiri'
doc = Nokogiri::XML(output)
doc.search("refmeta").each { |n| n.add_child(new_tags) }
output = doc.to_xml
However, this adds another dependency (e.g., the "ruby-nokogiri"
package on Ubuntu). Using Asciidoctor is not our default, but it
will probably need to become so soon. Let's avoid adding a
dependency just so that we can say "search...add_child" rather than
"sub(regex...)".
2. The older REXML is apparently always(?) bundled with ruby, but I
couldn't even parse the original document:
require 'rexml/document'
doc = REXML::Document.new(output)
...
The error was "no implicit conversion of nil into String" and I
stopped there.
I don't think it's unlikely that doing a plain old search-and-replace
will work just as fine or better compared to parsing XML and worrying
about libraries and library versions.
[1] https://asciidoctor.org/docs/user-manual/#builtin-attributes
[2] https://asciidoctor.org/docs/user-manual/#postprocessor-example
Signed-off-by: Martin Ågren <martin.agren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-09-16 19:00:27 +00:00
|
|
|
|
|
|
|
class DocumentPostProcessor < Asciidoctor::Extensions::Postprocessor
|
|
|
|
def process document, output
|
|
|
|
if document.basebackend? 'docbook'
|
|
|
|
mansource = document.attributes['mansource']
|
|
|
|
manversion = document.attributes['manversion']
|
|
|
|
manmanual = document.attributes['manmanual']
|
|
|
|
new_tags = "" \
|
|
|
|
"<refmiscinfo class=\"source\">#{mansource}</refmiscinfo>\n" \
|
|
|
|
"<refmiscinfo class=\"version\">#{manversion}</refmiscinfo>\n" \
|
|
|
|
"<refmiscinfo class=\"manual\">#{manmanual}</refmiscinfo>\n"
|
|
|
|
output = output.sub(/<\/refmeta>/, new_tags + "</refmeta>")
|
|
|
|
end
|
|
|
|
output
|
|
|
|
end
|
|
|
|
end
|
2024-09-24 07:08:48 +00:00
|
|
|
|
|
|
|
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
|
2017-01-26 00:13:44 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
Asciidoctor::Extensions.register do
|
|
|
|
inline_macro Git::Documentation::LinkGitProcessor, :linkgit
|
2024-09-24 07:08:48 +00:00
|
|
|
block Git::Documentation::SynopsisBlock
|
asciidoctor-extensions: provide `<refmiscinfo/>`
As can be seen from the previous commit, there are three attributes that
we provide to AsciiDoc through asciidoc.conf. Asciidoctor ignores that
file. After that patch, newer versions of Asciidoctor pick up the
`manmanual` and `mansource` attributes as we invoke `asciidoctor`, but
they don't pick up `manversion`. ([1] says: "Not used by Asciidoctor.")
Older versions (<1.5.7) don't handle these attributes at all. As a
result, we are missing one or three `<refmiscinfo/>` tags in each
xml-file produced when we build with Asciidoctor.
Because of this, xmlto doesn't include the Git version number in the
rendered manpages. And in particular, with versions <1.5.7, the manpage
footers instead contain the fairly ugly "[FIXME: source]".
That Asciidoctor ignores asciidoc.conf is nothing new. This is why we
implement the `linkgit:` macro in asciidoc.conf *and* in
asciidoctor-extensions.rb. Follow suit and provide these tags in
asciidoctor-extensions.rb, using a "postprocessor" extension where we
just search and replace in the XML, treated as text.
We may consider a few alternatives:
* Inject these lines into the xml-files from the *Makefile*, e.g.,
using `sed`. That would reduce repetition, but it feels wrong to
impose another step and another risk on the AsciiDoc-processing only
to benefit the Asciidoctor-one.
* I tried providing a "docinfo processor" to inject these tags, but
could not figure out how to "merge" the two <refmeta/> sections that
resulted. To avoid xmlto barfing on the result, I needed to use
`xmlto --skip-validation ...`, which seems unfortunate.
Let's instead inject the missing tags using a postprocessor. We'll make
it fairly obvious that we aim to inject the exact same three lines of
`<refmiscinfo/>` that asciidoc.conf provides. We inject them in
*post*-processing so we need to do the variable expansion ourselves. We
do introduce the bug that asciidoc.conf already has in that we won't do
any escaping, e.g., of funky versions like "some v <2.25, >2.20".
The postprocessor we add here works on the XML as raw text and doesn't
really use the full potential of XML to do a more structured injection.
This is actually precisely what the Asciidoctor User Manual does in its
postprocessor example [2]. I looked into two other approaches:
1. The nokogiri library is apparently the "modern" way of doing XML
in ruby. I got it working fairly easily:
require 'nokogiri'
doc = Nokogiri::XML(output)
doc.search("refmeta").each { |n| n.add_child(new_tags) }
output = doc.to_xml
However, this adds another dependency (e.g., the "ruby-nokogiri"
package on Ubuntu). Using Asciidoctor is not our default, but it
will probably need to become so soon. Let's avoid adding a
dependency just so that we can say "search...add_child" rather than
"sub(regex...)".
2. The older REXML is apparently always(?) bundled with ruby, but I
couldn't even parse the original document:
require 'rexml/document'
doc = REXML::Document.new(output)
...
The error was "no implicit conversion of nil into String" and I
stopped there.
I don't think it's unlikely that doing a plain old search-and-replace
will work just as fine or better compared to parsing XML and worrying
about libraries and library versions.
[1] https://asciidoctor.org/docs/user-manual/#builtin-attributes
[2] https://asciidoctor.org/docs/user-manual/#postprocessor-example
Signed-off-by: Martin Ågren <martin.agren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-09-16 19:00:27 +00:00
|
|
|
postprocessor Git::Documentation::DocumentPostProcessor
|
2017-01-26 00:13:44 +00:00
|
|
|
end
|