Hi devs,
I’d like to present the solution I’ve chosen for MARKDOWN-56 (“Add support for Group syntax”) in the Markdown Syntax extension. It’s already implemented and pushed (PR #7), but it hasn’t been released yet, so we can still change it. I’d like your feedback before the next release of the extension.
The problem
Markdown (CommonMark) has no equivalent of the XWiki Group block ((% class="..." %)(((...))) in XWiki Syntax 2.1). Until now, the Markdown renderer silently dropped Groups and their parameters. For example, an info box inserted with the WYSIWYG editor’s Styles dropdown (class="box infomessage") disappeared when saving a Markdown page.
Proposed syntax
A Group is written as a <div> that has a data-xwiki-group marker attribute, with the Group parameters as HTML attributes:
<div data-xwiki-group class="box infomessage">
This is an **info** box with:
* a list
* and a [link](https://www.xwiki.org)
</div>
This is equivalent to:
(% class="box infomessage" %)
(((
This is an **info** box with:
* a list
* and a [[link>>https://www.xwiki.org]]
)))
The opening and closing tags are each alone on their line and surrounded by blank lines. That’s valid CommonMark, so GitHub and other Markdown tools display it correctly. The blank lines are required: in CommonMark, an HTML block starting with <div only ends at a blank line, and its content is raw HTML. Without the blank line after the opening tag, the Group content wouldn’t be parsed as Markdown. The marker only identifies the Group after parsing, and doesn’t change how the Markdown is parsed.
Both directions are supported: the renderer produces this syntax for any Group, and the parser turns it back into a Group. This means Groups survive the WYSIWYG editor round trip. It works for both markdown/1.2 and markdown+github/1.0.
Why a marker attribute?
To not break backward compatibility. Existing Markdown pages can already contain hand-written <div> elements, which are parsed as HTML macros. Converting every <div> into a Group would change the XDOM of that content. With the marker, only a <div data-xwiki-group> that is alone in its HTML block and has a matching </div> at the same level becomes a Group. Any other <div> is still parsed exactly as before.
Alternatives considered
- Convert the whole Group to HTML: the Group content (lists, tables, etc.) would no longer be Markdown, which defeats the purpose of using Markdown.
- Pandoc-style fenced divs (
::: {.box .infomessage}…:::): readable, but not CommonMark (other Markdown tools would show it as text), and flexmark doesn’t support it, so we’d need to write and maintain our own flexmark extension. - Treat every
<div>as a Group, possibly in a new syntax version or behind a configuration flag: this either changes the meaning of existing content, or doesn’t fix the WYSIWYG editor use case by default.
Details and limitations
- Every Group is rendered with a
<div>, even without parameters, for an exact round trip. The only exception is the parameterless Group that the parser itself creates around an indented code block in a list item, so that the output of existing content doesn’t change. - Groups can be nested. Inside a list item, a Group is indented like the rest of the list item content.
- As in XWiki Syntax 2.1, a Group is always a block: a Group inside a paragraph is rendered on its own lines.
- Markdown tables can’t contain blocks, so a Group in a table cell is still rendered without its
<div>(same as before). - Parameter values are HTML-escaped. Parameters whose names aren’t valid HTML attribute names can’t be expressed and are dropped.
Questions
- Are you OK with this syntax, and more specifically with the
data-xwiki-groupmarker name? An alternative would bedata-xwiki-type="group", which could later be reused for other XWiki-specific blocks. - Do you see any problem with the backward compatibility choice (unmarked
<div>elements staying HTML macros)?
Thanks