From c9139dfa1a001e32baa6fea9c9373d80c83e39e9 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Mon, 12 Jul 2021 15:54:14 +0200 Subject: doc: Add support for MyST roles Officially, only the manpage role is supported at the moment. Unlike in rST, the syntax uses braces instead of colons: {manpage}`nix.conf(5)` --- doc/Makefile | 4 +++ .../docbook-reader/citerefentry-to-rst-role.lua | 23 ++++++++++++++ .../pandoc-filters/docbook-writer/rst-roles.lua | 36 ++++++++++++++++++++++ doc/build-aux/pandoc-filters/myst-reader/roles.lua | 29 +++++++++++++++++ doc/build-aux/pandoc-filters/myst-writer/roles.lua | 25 +++++++++++++++ .../contributing-to-documentation.chapter.md | 5 +++ nixos/doc/manual/md-to-db.sh | 7 ++++- 7 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 doc/build-aux/pandoc-filters/docbook-reader/citerefentry-to-rst-role.lua create mode 100644 doc/build-aux/pandoc-filters/docbook-writer/rst-roles.lua create mode 100644 doc/build-aux/pandoc-filters/myst-reader/roles.lua create mode 100644 doc/build-aux/pandoc-filters/myst-writer/roles.lua diff --git a/doc/Makefile b/doc/Makefile index 6eeaeca303c..9bcd30c150a 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -6,8 +6,12 @@ pandoc_media_dir = media # NOTE: Keep in sync with NixOS manual (/nixos/doc/manual/md-to-db.sh). # TODO: Remove raw-attribute when we can get rid of DocBook altogether. pandoc_commonmark_enabled_extensions = +attributes+fenced_divs+footnotes+bracketed_spans+definition_lists+pipe_tables+raw_attribute +# Not needed: +# - docbook-reader/citerefentry-to-rst-role.lua (only relevant for DocBook → MarkDown/rST/MyST) pandoc_flags = --extract-media=$(pandoc_media_dir) \ --lua-filter=$(PANDOC_LUA_FILTERS_DIR)/diagram-generator.lua \ + --lua-filter=build-aux/pandoc-filters/myst-reader/roles.lua \ + --lua-filter=build-aux/pandoc-filters/docbook-writer/rst-roles.lua \ --lua-filter=build-aux/pandoc-filters/docbook-writer/labelless-link-is-xref.lua \ -f commonmark$(pandoc_commonmark_enabled_extensions)+smart diff --git a/doc/build-aux/pandoc-filters/docbook-reader/citerefentry-to-rst-role.lua b/doc/build-aux/pandoc-filters/docbook-reader/citerefentry-to-rst-role.lua new file mode 100644 index 00000000000..281e85af271 --- /dev/null +++ b/doc/build-aux/pandoc-filters/docbook-reader/citerefentry-to-rst-role.lua @@ -0,0 +1,23 @@ +--[[ +Converts Code AST nodes produced by pandoc’s DocBook reader +from citerefentry elements into AST for corresponding role +for reStructuredText. + +We use subset of MyST syntax (CommonMark with features from rST) +so let’s use the rST AST for rST features. + +Reference: https://www.sphinx-doc.org/en/master/usage/restructuredtext/roles.html#role-manpage +]] + +function Code(elem) + elem.classes = elem.classes:map(function (x) + if x == 'citerefentry' then + elem.attributes['role'] = 'manpage' + return 'interpreted-text' + else + return x + end + end) + + return elem +end diff --git a/doc/build-aux/pandoc-filters/docbook-writer/rst-roles.lua b/doc/build-aux/pandoc-filters/docbook-writer/rst-roles.lua new file mode 100644 index 00000000000..92dc6895750 --- /dev/null +++ b/doc/build-aux/pandoc-filters/docbook-writer/rst-roles.lua @@ -0,0 +1,36 @@ +--[[ +Converts AST for reStructuredText roles into corresponding +DocBook elements. + +Currently, only a subset of roles is supported. + +Reference: + List of roles: + https://www.sphinx-doc.org/en/master/usage/restructuredtext/roles.html + manpage: + https://tdg.docbook.org/tdg/5.1/citerefentry.html + file: + https://tdg.docbook.org/tdg/5.1/filename.html +]] + +function Code(elem) + if elem.classes:includes('interpreted-text') then + local tag = nil + local content = elem.text + if elem.attributes['role'] == 'manpage' then + tag = 'citerefentry' + local title, volnum = content:match('^(.+)%((%w+)%)$') + if title == nil then + -- No volnum in parentheses. + title = content + end + content = '' .. title .. '' .. (volnum ~= nil and ('' .. volnum .. '') or '') + elseif elem.attributes['role'] == 'file' then + tag = 'filename' + end + + if tag ~= nil then + return pandoc.RawInline('docbook', '<' .. tag .. '>' .. content .. '') + end + end +end diff --git a/doc/build-aux/pandoc-filters/myst-reader/roles.lua b/doc/build-aux/pandoc-filters/myst-reader/roles.lua new file mode 100644 index 00000000000..c33a688eeba --- /dev/null +++ b/doc/build-aux/pandoc-filters/myst-reader/roles.lua @@ -0,0 +1,29 @@ +--[[ +Replaces Str AST nodes containing {role}, followed by a Code node +by a Code node with attrs that would be produced by rST reader +from the role syntax. + +This is to emulate MyST syntax in Pandoc. +(MyST is a CommonMark flavour with rST features mixed in.) + +Reference: https://myst-parser.readthedocs.io/en/latest/syntax/syntax.html#roles-an-in-line-extension-point +]] + +function Inlines(inlines) + for i = #inlines-1,1,-1 do + local first = inlines[i] + local second = inlines[i+1] + local correct_tags = first.tag == 'Str' and second.tag == 'Code' + if correct_tags then + -- docutils supports alphanumeric strings separated by [-._:] + -- We are slightly more liberal for simplicity. + local role = first.text:match('^{([-._+:%w]+)}$') + if role ~= nil then + inlines:remove(i) + second.attributes['role'] = role + second.classes:insert('interpreted-text') + end + end + end + return inlines +end diff --git a/doc/build-aux/pandoc-filters/myst-writer/roles.lua b/doc/build-aux/pandoc-filters/myst-writer/roles.lua new file mode 100644 index 00000000000..0136bc55065 --- /dev/null +++ b/doc/build-aux/pandoc-filters/myst-writer/roles.lua @@ -0,0 +1,25 @@ +--[[ +Replaces Code nodes with attrs that would be produced by rST reader +from the role syntax by a Str AST node containing {role}, followed by a Code node. + +This is to emulate MyST syntax in Pandoc. +(MyST is a CommonMark flavour with rST features mixed in.) + +Reference: https://myst-parser.readthedocs.io/en/latest/syntax/syntax.html#roles-an-in-line-extension-point +]] + +function Code(elem) + local role = elem.attributes['role'] + + if elem.classes:includes('interpreted-text') and role ~= nil then + elem.classes = elem.classes:filter(function (c) + return c ~= 'interpreted-text' + end) + elem.attributes['role'] = nil + + return { + pandoc.Str('{' .. role .. '}'), + elem, + } + end +end diff --git a/doc/contributing/contributing-to-documentation.chapter.md b/doc/contributing/contributing-to-documentation.chapter.md index 2f7ae32259c..bf73a340bce 100644 --- a/doc/contributing/contributing-to-documentation.chapter.md +++ b/doc/contributing/contributing-to-documentation.chapter.md @@ -52,6 +52,11 @@ Additionally, the following syntax extensions are currently used: This syntax is taken from [MyST](https://myst-parser.readthedocs.io/en/latest/using/syntax.html#targets-and-cross-referencing). +- []{#ssec-contributing-markup-inline-roles} + If you want to link to a man page, you can use ``{manpage}`nix.conf(5)```, which will turn into {manpage}`nix.conf(5)`. + + This syntax is taken from [MyST](https://myst-parser.readthedocs.io/en/latest/syntax/syntax.html#roles-an-in-line-extension-point). Though, the feature originates from [reStructuredText](https://www.sphinx-doc.org/en/master/usage/restructuredtext/roles.html#role-manpage) with slightly different syntax. + - []{#ssec-contributing-markup-admonitions} **Admonitions**, set off from the text to bring attention to something. diff --git a/nixos/doc/manual/md-to-db.sh b/nixos/doc/manual/md-to-db.sh index dee92fc57fa..e5a1919baa2 100755 --- a/nixos/doc/manual/md-to-db.sh +++ b/nixos/doc/manual/md-to-db.sh @@ -12,7 +12,12 @@ pushd $DIR # TODO: Remove raw-attribute when we can get rid of DocBook altogether. pandoc_commonmark_enabled_extensions=+attributes+fenced_divs+footnotes+bracketed_spans+definition_lists+pipe_tables+raw_attribute pandoc_flags=( - # media extraction and diagram-generator.lua not needed + # Not needed: + # - diagram-generator.lua (we do not support that in NixOS manual to limit dependencies) + # - media extraction (was only required for diagram generator) + # - docbook-reader/citerefentry-to-rst-role.lua (only relevant for DocBook → MarkDown/rST/MyST) + "--lua-filter=$DIR/../../../doc/build-aux/pandoc-filters/myst-reader/roles.lua" + "--lua-filter=$DIR/../../../doc/build-aux/pandoc-filters/docbook-writer/rst-roles.lua" "--lua-filter=$DIR/../../../doc/build-aux/pandoc-filters/docbook-writer/labelless-link-is-xref.lua" -f "commonmark${pandoc_commonmark_enabled_extensions}+smart" -t docbook -- cgit 1.4.1