Skip to content

Commit 7994503

Browse files
committed
Merge branch 'ja/doc-synopsis-markup'
The way AsciiDoc is used for SYNOPSIS part of the manual pages has been revamped. The sources, at least for the simple cases, got vastly pleasant to work with. * ja/doc-synopsis-markup: doc: apply synopsis simplification on git-clone and git-init doc: update the guidelines to reflect the current formatting rules doc: introduce a synopsis typesetting
2 parents 777489f + 2229389 commit 7994503

8 files changed

+209
-107
lines changed

Documentation/CodingGuidelines

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -828,78 +828,80 @@ Markup:
828828
_<new-branch-name>_
829829
_<template-directory>_
830830

831-
A placeholder is not enclosed in backticks, as it is not a literal.
832-
833831
When needed, use a distinctive identifier for placeholders, usually
834832
made of a qualification and a type:
835833
_<git-dir>_
836834
_<key-id>_
837835

838-
When literal and placeholders are mixed, each markup is applied for
839-
each sub-entity. If they are stuck, a special markup, called
840-
unconstrained formatting is required.
841-
Unconstrained formating for placeholders is __<like-this>__
842-
Unconstrained formatting for literal formatting is ++like this++
843-
`--jobs` _<n>_
844-
++--sort=++__<key>__
845-
__<directory>__++/.git++
846-
++remote.++__<name>__++.mirror++
836+
Git's Asciidoc processor has been tailored to treat backticked text
837+
as complex synopsis. When literal and placeholders are mixed, you can
838+
use the backtick notation which will take care of correctly typesetting
839+
the content.
840+
`--jobs <n>`
841+
`--sort=<key>`
842+
`<directory>/.git`
843+
`remote.<name>.mirror`
844+
`ssh://[<user>@]<host>[:<port>]/<path-to-git-repo>`
847845

848-
caveat: ++ unconstrained format is not verbatim and may expand
849-
content. Use Asciidoc escapes inside them.
846+
As a side effect, backquoted placeholders are correctly typeset, but
847+
this style is not recommended.
850848

851849
Synopsis Syntax
852850

853-
Syntax grammar is formatted neither as literal nor as placeholder.
851+
The synopsis (a paragraph with [synopsis] attribute) is automatically
852+
formatted by the toolchain and does not need typesetting.
854853

855854
A few commented examples follow to provide reference when writing or
856855
modifying command usage strings and synopsis sections in the manual
857856
pages:
858857

859858
Possibility of multiple occurrences is indicated by three dots:
860-
_<file>_...
859+
<file>...
861860
(One or more of <file>.)
862861

863862
Optional parts are enclosed in square brackets:
864-
[_<file>_...]
863+
[<file>...]
865864
(Zero or more of <file>.)
866865

867-
++--exec-path++[++=++__<path>__]
866+
An optional parameter needs to be typeset with unconstrained pairs
867+
[<repository>]
868+
869+
--exec-path[=<path>]
868870
(Option with an optional argument. Note that the "=" is inside the
869871
brackets.)
870872

871-
[_<patch>_...]
873+
[<patch>...]
872874
(Zero or more of <patch>. Note that the dots are inside, not
873875
outside the brackets.)
874876

875877
Multiple alternatives are indicated with vertical bars:
876-
[`-q` | `--quiet`]
877-
[`--utf8` | `--no-utf8`]
878+
[-q | --quiet]
879+
[--utf8 | --no-utf8]
878880

879881
Use spacing around "|" token(s), but not immediately after opening or
880882
before closing a [] or () pair:
881-
Do: [`-q` | `--quiet`]
882-
Don't: [`-q`|`--quiet`]
883+
Do: [-q | --quiet]
884+
Don't: [-q|--quiet]
883885

884886
Don't use spacing around "|" tokens when they're used to separate the
885887
alternate arguments of an option:
886-
Do: ++--track++[++=++(`direct`|`inherit`)]`
887-
Don't: ++--track++[++=++(`direct` | `inherit`)]
888+
Do: --track[=(direct|inherit)]
889+
Don't: --track[=(direct | inherit)]
888890

889891
Parentheses are used for grouping:
890-
[(_<rev>_ | _<range>_)...]
892+
[(<rev>|<range>)...]
891893
(Any number of either <rev> or <range>. Parens are needed to make
892894
it clear that "..." pertains to both <rev> and <range>.)
893895

894-
[(`-p` _<parent>_)...]
896+
[(-p <parent>)...]
895897
(Any number of option -p, each with one <parent> argument.)
896898

897-
`git remote set-head` _<name>_ (`-a` | `-d` | _<branch>_)
899+
git remote set-head <name> (-a|-d|<branch>)
898900
(One and only one of "-a", "-d" or "<branch>" _must_ (no square
899901
brackets) be provided.)
900902

901903
And a somewhat more contrived example:
902-
`--diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]]`
904+
--diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]]
903905
Here "=" is outside the brackets, because "--diff-filter=" is a
904906
valid usage. "*" has its own pair of brackets, because it can
905907
(optionally) be specified only when one or more of the letters is

Documentation/asciidoc.conf

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ ifdef::backend-docbook[]
2828
{0#<citerefentry>}
2929
{0#<refentrytitle>{target}</refentrytitle><manvolnum>{0}</manvolnum>}
3030
{0#</citerefentry>}
31+
32+
[literal-inlinemacro]
33+
{eval:re.sub(r'(&lt;[-a-zA-Z0-9.]+&gt;)', r'<emphasis>\1</emphasis>', re.sub(r'([\[\s|()>]|^|\]|&gt;)(\.?([-a-zA-Z0-9:+=~@,\/_^\$]+\.?)+)',r'\1<literal>\2</literal>', re.sub(r'(\.\.\.?)([^\]$.])', r'<literal>\1</literal>\2', macros.passthroughs[int(attrs['passtext'][1:-1])] if attrs['passtext'][1:-1].isnumeric() else attrs['passtext'][1:-1])))}
34+
3135
endif::backend-docbook[]
3236

3337
ifdef::backend-docbook[]
@@ -56,4 +60,20 @@ ifdef::backend-xhtml11[]
5660
git-relative-html-prefix=
5761
[linkgit-inlinemacro]
5862
<a href="{git-relative-html-prefix}{target}.html">{target}{0?({0})}</a>
63+
64+
[literal-inlinemacro]
65+
{eval:re.sub(r'(&lt;[-a-zA-Z0-9.]+&gt;)', r'<em>\1</em>', re.sub(r'([\[\s|()>]|^|\]|&gt;)(\.?([-a-zA-Z0-9:+=~@,\/_^\$]+\.?)+)',r'\1<code>\2</code>', re.sub(r'(\.\.\.?)([^\]$.])', r'<code>\1</code>\2', macros.passthroughs[int(attrs['passtext'][1:-1])] if attrs['passtext'][1:-1].isnumeric() else attrs['passtext'][1:-1])))}
66+
67+
endif::backend-xhtml11[]
68+
69+
ifdef::backend-docbook[]
70+
ifdef::doctype-manpage[]
71+
[paradef-default]
72+
synopsis-style=template="verseparagraph",filter="sed 's!&#8230;\\(\\]\\|$\\)!<phrase>\\0</phrase>!g;s!\\([\\[ |()]\\|^\\|\\]\\|&gt;\\)\\([-=a-zA-Z0-9:+@,\\/_^\\$.]\\+\\|&#8230;\\)!\\1<literal>\\2</literal>!g;s!&lt;[-a-zA-Z0-9.]\\+&gt;!<emphasis>\\0</emphasis>!g'"
73+
endif::doctype-manpage[]
74+
endif::backend-docbook[]
75+
76+
ifdef::backend-xhtml11[]
77+
[paradef-default]
78+
synopsis-style=template="verseparagraph",filter="sed 's!&#8230;\\(\\]\\|$\\)!<span>\\0</span>!g;s!\\([\\[ |()]\\|^\\|\\]\\|&gt;\\)\\([-=a-zA-Z0-9:+@,\\/_^\\$.]\\+\\|&#8230;\\)!\\1<code>\\2</code>!g;s!&lt;[-a-zA-Z0-9.]\\+&gt;!<em>\\0</em>!g'"
5979
endif::backend-xhtml11[]

Documentation/asciidoctor-extensions.rb

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
require 'asciidoctor'
22
require 'asciidoctor/extensions'
3+
require 'asciidoctor/converter/docbook5'
4+
require 'asciidoctor/converter/html5'
35

46
module Git
57
module Documentation
@@ -39,10 +41,95 @@ def process document, output
3941
output
4042
end
4143
end
44+
45+
class SynopsisBlock < Asciidoctor::Extensions::BlockProcessor
46+
47+
use_dsl
48+
named :synopsis
49+
parse_content_as :simple
50+
51+
def process parent, reader, attrs
52+
outlines = reader.lines.map do |l|
53+
l.gsub(/(\.\.\.?)([^\]$.])/, '`\1`\2')
54+
.gsub(%r{([\[\] |()>]|^)([-a-zA-Z0-9:+=~@,/_^\$]+)}, '\1{empty}`\2`{empty}')
55+
.gsub(/(<[-a-zA-Z0-9.]+>)/, '__\\1__')
56+
.gsub(']', ']{empty}')
57+
end
58+
create_block parent, :verse, outlines, attrs
59+
end
60+
end
61+
62+
class GitDBConverter < Asciidoctor::Converter::DocBook5Converter
63+
64+
extend Asciidoctor::Converter::Config
65+
register_for 'docbook5'
66+
67+
def convert_inline_quoted node
68+
if (type = node.type) == :asciimath
69+
# NOTE fop requires jeuclid to process mathml markup
70+
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>)
71+
elsif type == :latexmath
72+
# unhandled math; pass source to alt and required mathphrase element; dblatex will process alt as LaTeX math
73+
%(<inlineequation><alt><![CDATA[#{equation = node.text}]]></alt><mathphrase><![CDATA[#{equation}]]></mathphrase></inlineequation>)
74+
elsif type == :monospaced
75+
node.text.gsub(/(\.\.\.?)([^\]$.])/, '<literal>\1</literal>\2')
76+
.gsub(%r{([\[\s|()>.]|^|\]|&gt;)(\.?([-a-zA-Z0-9:+=~@,/_^\$]+\.{0,2})+)}, '\1<literal>\2</literal>')
77+
.gsub(/(&lt;[-a-zA-Z0-9.]+&gt;)/, '<emphasis>\1</emphasis>')
78+
else
79+
open, close, supports_phrase = QUOTE_TAGS[type]
80+
text = node.text
81+
if node.role
82+
if supports_phrase
83+
quoted_text = %(#{open}<phrase role="#{node.role}">#{text}</phrase>#{close})
84+
else
85+
quoted_text = %(#{open.chop} role="#{node.role}">#{text}#{close})
86+
end
87+
else
88+
quoted_text = %(#{open}#{text}#{close})
89+
end
90+
node.id ? %(<anchor#{common_attributes node.id, nil, text}/>#{quoted_text}) : quoted_text
91+
end
92+
end
93+
end
94+
95+
# register a html5 converter that takes in charge to convert monospaced text into Git style synopsis
96+
class GitHTMLConverter < Asciidoctor::Converter::Html5Converter
97+
98+
extend Asciidoctor::Converter::Config
99+
register_for 'html5'
100+
101+
def convert_inline_quoted node
102+
if node.type == :monospaced
103+
node.text.gsub(/(\.\.\.?)([^\]$.])/, '<code>\1</code>\2')
104+
.gsub(%r{([\[\s|()>.]|^|\]|&gt;)(\.?([-a-zA-Z0-9:+=~@,/_^\$]+\.{0,2})+)}, '\1<code>\2</code>')
105+
.gsub(/(&lt;[-a-zA-Z0-9.]+&gt;)/, '<em>\1</em>')
106+
107+
else
108+
open, close, tag = QUOTE_TAGS[node.type]
109+
if node.id
110+
class_attr = node.role ? %( class="#{node.role}") : ''
111+
if tag
112+
%(#{open.chop} id="#{node.id}"#{class_attr}>#{node.text}#{close})
113+
else
114+
%(<span id="#{node.id}"#{class_attr}>#{open}#{node.text}#{close}</span>)
115+
end
116+
elsif node.role
117+
if tag
118+
%(#{open.chop} class="#{node.role}">#{node.text}#{close})
119+
else
120+
%(<span class="#{node.role}">#{open}#{node.text}#{close}</span>)
121+
end
122+
else
123+
%(#{open}#{node.text}#{close})
124+
end
125+
end
126+
end
127+
end
42128
end
43129
end
44130

45131
Asciidoctor::Extensions.register do
46132
inline_macro Git::Documentation::LinkGitProcessor, :linkgit
133+
block Git::Documentation::SynopsisBlock
47134
postprocessor Git::Documentation::DocumentPostProcessor
48135
end

0 commit comments

Comments
 (0)