From d9070e669020ab7fd0c8dc4c24cc42a33545e135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-No=C3=ABl=20Avila?= <jn.avila@free.fr> Date: Sat, 30 Nov 2024 17:03:22 +0100 Subject: [PATCH 1/2] stylesheet: remove background and border from code spans MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new style makes the code spans lighter and more integrated into the text. The new style also makes the code spans more readable and less intrusive. Signed-off-by: Jean-Noël Avila <jn.avila@free.fr> --- assets/sass/application.scss | 2 +- assets/sass/typography.scss | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/assets/sass/application.scss b/assets/sass/application.scss index 7e352c3f30..638e47bde2 100644 --- a/assets/sass/application.scss +++ b/assets/sass/application.scss @@ -29,7 +29,7 @@ $baseurl: "{{ .Site.BaseURL }}{{ if (and (ne .Site.BaseURL "/") (ne .Site.BaseUR code { display: inline; - padding: 0 5px; + padding: 0 0; } pre { diff --git a/assets/sass/typography.scss b/assets/sass/typography.scss index 5e8a840906..bd598b99e8 100644 --- a/assets/sass/typography.scss +++ b/assets/sass/typography.scss @@ -251,7 +251,6 @@ blockquote { } code { - @include border-radius(3px); display: block; padding: 10px 15px 13px; margin-bottom: 1em; @@ -260,8 +259,6 @@ code { line-height: $fixed-width-line-height; font-variant-ligatures: none; color: $orange; - background-color: #fff; - border: solid 1px #efeee6; } // Quotes From 87aab82c6e263f15631de2423db0ad6a55783338 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-No=C3=ABl=20Avila?= <jn.avila@free.fr> Date: Sun, 17 Nov 2024 22:24:18 +0100 Subject: [PATCH 2/2] manpages: prepare for new manpage format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds a upcoming manpage format to the AsciiDoc backend. The new format changes are: * The synopsis is now a section with a dedicated style. This "synopsis" style allows to automatically format the keywords as monospaced and <placeholders> as italic. * the backticks are now used to format synopsis-like syntax in inline elements. The parsing of synopsis is done with a new AsciiDoc extension that makes use of the PEG parser parslet. All the asciidoc manpages sources are processed with this extension. It may upset the formatting for older manpages, making it not consistent across a page, but this will be a mild side effect, as this was not really consistent before. Signed-off-by: Jean-Noël Avila <jn.avila@free.fr> --- Gemfile | 1 + script/asciidoctor-extensions.rb | 129 +++++++++++++++++++++++++++++++ script/update-docs.rb | 1 + 3 files changed, 131 insertions(+) create mode 100644 script/asciidoctor-extensions.rb diff --git a/Gemfile b/Gemfile index 3ce8333751..2e9ac7e322 100644 --- a/Gemfile +++ b/Gemfile @@ -7,3 +7,4 @@ gem "rss" gem "asciidoctor", "~> 2.0.0" gem "nokogiri" gem "diffy" +gem "parslet" diff --git a/script/asciidoctor-extensions.rb b/script/asciidoctor-extensions.rb new file mode 100644 index 0000000000..54285f6a75 --- /dev/null +++ b/script/asciidoctor-extensions.rb @@ -0,0 +1,129 @@ +require 'asciidoctor' +require 'asciidoctor/extensions' +require 'asciidoctor/converter/html5' +require 'parslet' + +module Git + module Documentation + class AdocSynopsisQuote < Parslet::Parser + # parse a string like "git add -p [--root=<path>]" as series of tokens keywords, grammar signs and placeholders + # where placeholders are UTF-8 words separated by '-', enclosed in '<' and '>' + rule(:space) { match('[\s\t\n ]').repeat(1) } + rule(:space?) { space.maybe } + rule(:keyword) { match('[-a-zA-Z0-9:+=~@,\./_\^\$\'"\*%!{}#]').repeat(1) } + rule(:placeholder) { str('<') >> match('[[:word:]]|-').repeat(1) >> str('>') } + rule(:opt_or_alt) { match('[\[\] |()]') >> space? } + rule(:ellipsis) { str('...') >> match('\]|$').present? } + rule(:grammar) { opt_or_alt | ellipsis } + rule(:ignore) { match('[\'`]') } + + rule(:token) do + grammar.as(:grammar) | placeholder.as(:placeholder) | space.as(:grammar) | + ignore.as(:ignore) | keyword.as(:keyword) + end + rule(:tokens) { token.repeat(1) } + root(:tokens) + end + + class EscapedSynopsisQuote < Parslet::Parser + rule(:space) { match('[\s\t\n ]').repeat(1) } + rule(:space?) { space.maybe } + rule(:keyword) { match('[-a-zA-Z0-9:+=~@,\./_\^\$\'"\*%!{}#]').repeat(1) } + rule(:placeholder) { str('<') >> match('[[:word:]]|-').repeat(1) >> str('>') } + rule(:opt_or_alt) { match('[\[\] |()]') >> space? } + rule(:ellipsis) { str('...') >> match('\]|$').present? } + rule(:grammar) { opt_or_alt | ellipsis } + rule(:ignore) { match('[\'`]') } + + rule(:token) do + grammar.as(:grammar) | placeholder.as(:placeholder) | space.as(:grammar) | + ignore.as(:ignore) | keyword.as(:keyword) + end + rule(:tokens) { token.repeat(1) } + root(:tokens) + end + + class SynopsisQuoteToAdoc < Parslet::Transform + rule(grammar: simple(:grammar)) { grammar.to_s } + rule(keyword: simple(:keyword)) { "{empty}`#{keyword}`{empty}" } + rule(placeholder: simple(:placeholder)) { "__#{placeholder}__" } + rule(ignore: simple(:ignore)) { '' } + end + + class SynopsisQuoteToHtml5 < Parslet::Transform + rule(grammar: simple(:grammar)) { grammar.to_s } + rule(keyword: simple(:keyword)) { "<code>#{keyword}</code>" } + rule(placeholder: simple(:placeholder)) { "<em>#{placeholder}</em>" } + rule(ignore: simple(:ignore)) { '' } + end + + class SynopsisConverter + def convert(parslet_parser, parslet_transform, reader, logger = nil) + reader.lines.map do |l| + parslet_transform.apply(parslet_parser.parse(l)).join + end.join("\n") + rescue Parslet::ParseFailed + logger&.info "synopsis parsing failed for '#{reader.lines.join(' ')}'" + reader.lines.map do |l| + parslet_transform.apply(placeholder: l) + end.join("\n") + end + end + + class SynopsisBlock < Asciidoctor::Extensions::BlockProcessor + use_dsl + named :synopsis + parse_content_as :simple + + def process(parent, reader, attrs) + outlines = SynopsisConverter.new.convert( + AdocSynopsisQuote.new, + SynopsisQuoteToAdoc.new, + reader, + parent.document.logger + ) + create_block parent, :verse, outlines, attrs + 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 + SynopsisConverter.new.convert( + EscapedSynopsisQuote.new, + SynopsisQuoteToHtml5.new, + node.text, + node.document.logger + ) + 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 + block Git::Documentation::SynopsisBlock +end diff --git a/script/update-docs.rb b/script/update-docs.rb index 07c168fd1a..28223891ce 100644 --- a/script/update-docs.rb +++ b/script/update-docs.rb @@ -9,6 +9,7 @@ require 'yaml' require 'diffy' require_relative "version" +require_relative 'asciidoctor-extensions' SITE_ROOT = File.join(File.expand_path(File.dirname(__FILE__)), '../') DOCS_INDEX_FILE = "#{SITE_ROOT}external/docs/content/docs/_index.html"