From: "Jean-Noël Avila via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: "Eric Sunshine" <sunshine@sunshineco.com>,
"Josh Steadmon" <steadmon@google.com>,
"Chris Torek" <chris.torek@gmail.com>,
"Jean-Noël Avila" <jn.avila@free.fr>,
"Jean-Noël Avila" <jn.avila@free.fr>
Subject: [PATCH v5 1/3] doc: introduce a synopsis typesetting
Date: Tue, 24 Sep 2024 07:08:48 +0000 [thread overview]
Message-ID: <2946cc80314aa2b3f653c83e34ccb7aeb1db44d8.1727161730.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1766.v5.git.1727161730.gitgitgadget@gmail.com>
From: =?UTF-8?q?Jean-No=C3=ABl=20Avila?= <jn.avila@free.fr>
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>
---
Documentation/asciidoc.conf | 20 ++++++
Documentation/asciidoctor-extensions.rb | 87 +++++++++++++++++++++++++
ci/install-dependencies.sh | 1 +
t/t0450-txt-doc-vs-help.sh | 11 ++--
4 files changed, 112 insertions(+), 7 deletions(-)
diff --git a/Documentation/asciidoc.conf b/Documentation/asciidoc.conf
index 60f76f43eda..f6da6d1fbd2 100644
--- a/Documentation/asciidoc.conf
+++ b/Documentation/asciidoc.conf
@@ -28,6 +28,10 @@ ifdef::backend-docbook[]
{0#<citerefentry>}
{0#<refentrytitle>{target}</refentrytitle><manvolnum>{0}</manvolnum>}
{0#</citerefentry>}
+
+[literal-inlinemacro]
+{eval:re.sub(r'(<[-a-zA-Z0-9.]+>)', r'<emphasis>\1</emphasis>', re.sub(r'([\[\s|()>]|^|\]|>)(\.?([-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])))}
+
endif::backend-docbook[]
ifdef::backend-docbook[]
@@ -56,4 +60,20 @@ ifdef::backend-xhtml11[]
git-relative-html-prefix=
[linkgit-inlinemacro]
<a href="{git-relative-html-prefix}{target}.html">{target}{0?({0})}</a>
+
+[literal-inlinemacro]
+{eval:re.sub(r'(<[-a-zA-Z0-9.]+>)', r'<em>\1</em>', re.sub(r'([\[\s|()>]|^|\]|>)(\.?([-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])))}
+
+endif::backend-xhtml11[]
+
+ifdef::backend-docbook[]
+ifdef::doctype-manpage[]
+[paradef-default]
+synopsis-style=template="verseparagraph",filter="sed 's!…\\(\\]\\|$\\)!<phrase>\\0</phrase>!g;s!\\([\\[ |()]\\|^\\|\\]\\|>\\)\\([-=a-zA-Z0-9:+@,\\/_^\\$.]\\+\\|…\\)!\\1<literal>\\2</literal>!g;s!<[-a-zA-Z0-9.]\\+>!<emphasis>\\0</emphasis>!g'"
+endif::doctype-manpage[]
+endif::backend-docbook[]
+
+ifdef::backend-xhtml11[]
+[paradef-default]
+synopsis-style=template="verseparagraph",filter="sed 's!…\\(\\]\\|$\\)!<span>\\0</span>!g;s!\\([\\[ |()]\\|^\\|\\]\\|>\\)\\([-=a-zA-Z0-9:+@,\\/_^\\$.]\\+\\|…\\)!\\1<code>\\2</code>!g;s!<[-a-zA-Z0-9.]\\+>!<em>\\0</em>!g'"
endif::backend-xhtml11[]
diff --git a/Documentation/asciidoctor-extensions.rb b/Documentation/asciidoctor-extensions.rb
index d906a008039..cb24480b63d 100644
--- a/Documentation/asciidoctor-extensions.rb
+++ b/Documentation/asciidoctor-extensions.rb
@@ -1,5 +1,7 @@
require 'asciidoctor'
require 'asciidoctor/extensions'
+require 'asciidoctor/converter/docbook5'
+require 'asciidoctor/converter/html5'
module Git
module Documentation
@@ -39,10 +41,95 @@ module Git
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
diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh
index 4781cd20bb0..3e3ae39cbb1 100755
--- a/ci/install-dependencies.sh
+++ b/ci/install-dependencies.sh
@@ -107,6 +107,7 @@ Documentation)
test -n "$ALREADY_HAVE_ASCIIDOCTOR" ||
sudo gem install --version 1.5.8 asciidoctor
+ sudo gem install concurrent-ruby
;;
esac
diff --git a/t/t0450-txt-doc-vs-help.sh b/t/t0450-txt-doc-vs-help.sh
index 69917d7b845..f99a69ae1b7 100755
--- a/t/t0450-txt-doc-vs-help.sh
+++ b/t/t0450-txt-doc-vs-help.sh
@@ -56,14 +56,11 @@ txt_to_synopsis () {
fi &&
b2t="$(builtin_to_txt "$builtin")" &&
sed -n \
- -e '/^\[verse\]$/,/^$/ {
+ -E '/^\[(verse|synopsis)\]$/,/^$/ {
/^$/d;
- /^\[verse\]$/d;
- s/_//g;
- s/++//g;
- s/`//g;
- s/{litdd}/--/g;
- s/'\''\(git[ a-z-]*\)'\''/\1/g;
+ /^\[(verse|synopsis)\]$/d;
+ s/\{litdd\}/--/g;
+ s/'\''(git[ a-z-]*)'\''/\1/g;
p;
}' \
--
gitgitgadget
next prev parent reply other threads:[~2024-09-24 7:08 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-23 22:44 [PATCH 0/3] doc: introducing synopsis para Jean-Noël Avila via GitGitGadget
2024-07-23 22:44 ` [PATCH 1/3] doc: introduce a synopsis custom paragraph attribute Jean-Noël Avila via GitGitGadget
2024-07-23 23:36 ` Junio C Hamano
2024-07-23 22:44 ` [PATCH 2/3] doc: update the guidelines to reflect the current formatting rules Jean-Noël Avila via GitGitGadget
2024-07-23 23:37 ` Junio C Hamano
2024-07-23 22:44 ` [PATCH 3/3] doc: apply synopsis simplification on git-clone and git-init Jean-Noël Avila via GitGitGadget
2024-07-23 23:04 ` [PATCH 0/3] doc: introducing synopsis para Jean-Noël AVILA
2024-07-24 21:06 ` [PATCH v2 " Jean-Noël Avila via GitGitGadget
2024-07-24 21:06 ` [PATCH v2 1/3] doc: introduce a synopsis custom paragraph attribute Jean-Noël Avila via GitGitGadget
2024-07-24 21:06 ` [PATCH v2 2/3] doc: update the guidelines to reflect the current formatting rules Jean-Noël Avila via GitGitGadget
2024-07-24 21:06 ` [PATCH v2 3/3] doc: apply synopsis simplification on git-clone and git-init Jean-Noël Avila via GitGitGadget
2024-07-24 23:15 ` [PATCH v2 0/3] doc: introducing synopsis para Junio C Hamano
2024-07-25 12:15 ` Jean-Noël AVILA
2024-07-25 15:32 ` Junio C Hamano
2024-08-11 15:20 ` [PATCH v3 " Jean-Noël Avila via GitGitGadget
2024-08-11 15:20 ` [PATCH v3 1/3] doc: introduce a synopsis custom paragraph attribute Jean-Noël Avila via GitGitGadget
2024-08-11 15:20 ` [PATCH v3 2/3] doc: update the guidelines to reflect the current formatting rules Jean-Noël Avila via GitGitGadget
2024-08-11 23:56 ` Eric Sunshine
2024-08-12 6:18 ` Jean-Noël Avila
2024-08-11 15:20 ` [PATCH v3 3/3] doc: apply synopsis simplification on git-clone and git-init Jean-Noël Avila via GitGitGadget
2024-08-19 20:08 ` [PATCH v3 0/3] doc: introducing synopsis para Junio C Hamano
2024-08-21 21:05 ` Jean-Noël AVILA
2024-08-30 17:48 ` Junio C Hamano
2024-09-05 21:52 ` [PATCH v4 " Jean-Noël Avila via GitGitGadget
2024-09-05 21:52 ` [PATCH v4 1/3] doc: introduce a synopsis typesetting Jean-Noël Avila via GitGitGadget
2024-09-05 21:52 ` [PATCH v4 2/3] doc: update the guidelines to reflect the current formatting rules Jean-Noël Avila via GitGitGadget
2024-09-05 21:52 ` [PATCH v4 3/3] doc: apply synopsis simplification on git-clone and git-init Jean-Noël Avila via GitGitGadget
2024-09-13 18:15 ` [PATCH v4 0/3] doc: introducing synopsis para Junio C Hamano
2024-09-20 23:14 ` Josh Steadmon
2024-09-21 1:38 ` Junio C Hamano
2024-09-21 6:19 ` Junio C Hamano
2024-09-21 6:23 ` Junio C Hamano
2024-09-21 6:54 ` Chris Torek
2024-09-23 16:38 ` Junio C Hamano
[not found] ` <CAPig+cQgw8xf5bQaUEW=qvKQpnxrkiTrMsqa+VW9d_GX0au1sA@mail.gmail.com>
2024-09-24 22:03 ` Josh Steadmon
2024-09-24 23:34 ` Junio C Hamano
2024-09-24 7:08 ` [PATCH v5 " Jean-Noël Avila via GitGitGadget
2024-09-24 7:08 ` Jean-Noël Avila via GitGitGadget [this message]
2024-09-24 7:08 ` [PATCH v5 2/3] doc: update the guidelines to reflect the current formatting rules Jean-Noël Avila via GitGitGadget
2024-09-24 7:08 ` [PATCH v5 3/3] doc: apply synopsis simplification on git-clone and git-init Jean-Noël Avila via GitGitGadget
2024-09-24 17:16 ` [PATCH v5 0/3] doc: introducing synopsis para Junio C Hamano
2024-09-24 19:30 ` Torsten Bögershausen
2024-09-24 20:33 ` Junio C Hamano
2024-10-02 21:41 ` Josh Steadmon
2024-10-02 22:43 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2946cc80314aa2b3f653c83e34ccb7aeb1db44d8.1727161730.git.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=chris.torek@gmail.com \
--cc=git@vger.kernel.org \
--cc=jn.avila@free.fr \
--cc=steadmon@google.com \
--cc=sunshine@sunshineco.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).