mirror of
https://github.com/git/git.git
synced 2024-11-23 18:05:29 +08:00
974cdca345
In order to follow the common manpage usage, the synopsis of the commands needs to be heavily typeset. A first try was performed with using native markup, but it turned out to make the document source almost unreadable, difficult to write and prone to mistakes with unwanted Asciidoc's role attributes. In order to both simplify the writer's task and obtain a consistant typesetting in the synopsis, a custom 'synopsis' paragraph type is created and the processor for backticked text are modified. The backends of asciidoc and asciidoctor take in charge to correctly add the required typesetting. Signed-off-by: Jean-Noël Avila <jn.avila@free.fr> Signed-off-by: Junio C Hamano <gitster@pobox.com>
136 lines
5.2 KiB
Ruby
136 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'
|
|
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
|
|
|
|
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
|