From a6aa4b5523afe2ffcc8437fc37bb8f1f113b8302 Mon Sep 17 00:00:00 2001 From: Hakim Cassimally Date: Mon, 13 Jun 2022 17:59:55 +0100 Subject: [PATCH] Asciidoc markdown block MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Block extension to filter text like: [markdown] -- Filter some text with [Markdown](https://commonmark.org/help/) syntax. -- This is not implemented with a full Markdown parser. See https://github.com/asciidoctor/kramdown-asciidoc/issues/7 with a link to the "naive series of regexes" used as starting point. (And note that we use Open structural context https://docs.asciidoctor.org/asciidoc/latest/blocks/delimited/#summary-of-structural-containers with `--` delimiters, and headings don’t work inside these.) This feature is intended for handling OpenAPI specs, which can contain Markdown, however openapi-generator has poor Asciidoc handling https://github.com/OpenAPITools/openapi-generator/issues/11396 so instead we add the block delimiters in the template, and let the block filter handle it. Create a block with potentially multiple lines (sub-paragraphs) * Add extensions doc page --- antora-playbook.yml | 1 + home/modules/contribute/pages/extensions.adoc | 36 ++++++++++++++++ lib/markdown-block.js | 42 +++++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 home/modules/contribute/pages/extensions.adoc create mode 100644 lib/markdown-block.js diff --git a/antora-playbook.yml b/antora-playbook.yml index e819561b09..eccd42baa8 100644 --- a/antora-playbook.yml +++ b/antora-playbook.yml @@ -168,6 +168,7 @@ asciidoc: - ./lib/multirow-table-head-tree-processor.js - ./lib/swagger-ui-block-macro.js - ./lib/tabs-block.js + - ./lib/markdown-block.js - asciidoctor-kroki ui: bundle: diff --git a/home/modules/contribute/pages/extensions.adoc b/home/modules/contribute/pages/extensions.adoc new file mode 100644 index 0000000000..5a8302f8ff --- /dev/null +++ b/home/modules/contribute/pages/extensions.adoc @@ -0,0 +1,36 @@ += Site Extensions + +Test and document your Asciidoctor.js or Antora extensions here. + +== Markdown Block + +[source,asciidoc] +---- +[markdown] +-- +Filter some text with [Markdown](https://commonmark.org/help/) syntax. +-- +---- + +Results in: + +[markdown] +-- +Filter some text with [Markdown](https://commonmark.org/help/) syntax. +-- + + +[NOTE] +-- +This is not implemented with a full Markdown parser. +See link:https://github.com/asciidoctor/kramdown-asciidoc/issues/7[issue] +with a link to the "naive series of regexes" used as starting point. + +(And note that we use Open +link:https://docs.asciidoctor.org/asciidoc/latest/blocks/delimited/#summary-of-structural-containers[structural context], +with `--` delimiters, and headings don't work inside these.) + +This feature is intended for handling OpenAPI specs, which can contain Markdown, +however openapi-generator has link:https://github.com/OpenAPITools/openapi-generator/issues/11396[poor Asciidoc handling], +so instead we add the block delimiters in the template, and let the block filter handle it. +-- diff --git a/lib/markdown-block.js b/lib/markdown-block.js new file mode 100644 index 0000000000..6d8c1ebbea --- /dev/null +++ b/lib/markdown-block.js @@ -0,0 +1,42 @@ +// from https://github.com/dohliam/markdoctor/blob/master/js/mdtoadoc.js +function convMdAdoc(txt) { + // horizontal rules + txt = txt.replace(/^\-{3,}$/gm, "'''").replace(/^[\*_]{3,}/gm, "'''"); + + // general text formatting + txt = txt.replace(/^\*([^\s\*][^\*]+)\*/gm, "_$1_").replace(/\s\*([^\*\s]+)\*/g, " _$1_").replace(/\*\*_/g, "*_").replace(/_\*\*/g, "_*").replace(/^\*\*([^\*]+)\*\*/gm, "*$1*").replace(/\s\*\*([^\*]+)\*\*/g, " *$1*"); + + // headings + txt = txt.replace(/^#*/gm, (x) => '='.repeat(x.length)) + + // images + txt = txt.replace(/\[\!\[([^\]]*)\]\(([^\)]+)\)\]\(([^\)]+)\)/g, "image::$2[$1, link=\"$3\"]").replace(/\!\[([^\]]*)\]\(([^\)]+)\)/g, "image::$2[$1]"); + + // links + txt = txt.replace(/\[([^\]]+)\]\(([a-z\.\/]+[^:\)]+)\)/g, "link:$2[$1]").replace(/\[([^\]]+)\]\(([a-z]+:\/\/[^\)]+)\)/g, "$2[$1]"); + + // unordered lists + txt = txt.replace(/^\s{2}[\*\-]\s/gm, "** ").replace(/^\s{4}[\*\-]\s/gm, "*** ").replace(/^\s{6}[\*\-]\s/gm, "**** ").replace(/^\s{8}[\*\-]\s/gm, "***** "); + + // ordered lists + txt = txt.replace(/^\d+\.\s/gm, ". ").replace(/^\s{2}\d+\.\s/gm, ".. ").replace(/^\s{4}\d+\.\s/gm, "... ").replace(/^\s{6}\d+\.\s/gm, ".... ").replace(/^\s{8}\d+\.\s/gm, "..... "); + + // tables + txt = txt.replace(/^\|*\s*(.*?)\s+\|\s+(.*?)\n\|*\s*\-+.*\n/gm, "[options=\"header\"]\n|===\n| $1 | $2\n").replace(/^\|*\s*(.*?\s+\|\s+.*?)\n\n/gm, "| $1\n|===\n\n").replace(/^([^\|]+\s+\|\s+.*$)/gm, "| $1"); + + return txt +} + +module.exports = function (registry) { + registry.block(function () { + var self = this + self.named('markdown') + self.onContext('open') + self.process(function (parent, reader) { + + var lines = reader.getLines().map(function (l) { return convMdAdoc(l) }) + const source = lines.join('\n') + return self.createOpenBlock(parent, source) + }) + }) +}