Problem/Motivation
The filter only recognises the [mermaid]...[/mermaid] shortcode, which is not a syntax any editor produces.
CKEditor 5's Code Block plugin, which is what Drupal core ships, emits <pre><code class="language-mermaid">. Every Markdown converter emits the same thing for a ```mermaid fence. So on a standard Drupal site an author has to switch to source view and hand-write a shortcode, and any content authored or imported as Markdown never renders at all.
The shortcode was added in #3468773, and nothing there suggests the code block form was considered and rejected. This issue proposes supporting both.
Proposed resolution
Match <pre><code class="language-mermaid"> (and the lang- shorthand) in addition to the shortcode, and route both through the existing processMermaid(). Both then produce the same <pre class="mermaid"> markup, so no JavaScript change is required.
Two related fixes are needed to make that work, and one improvement comes along with it:
- The
<code>element must not survive into the output. Sites that also run a highlight.js integration callhljs.highlightAll(), which walks everypre codein the document and auto-detects a language regardless of filter order. Leaving the<code>in place would syntax-highlight the diagram source underneath the rendered graph, and would make the highlighter request amermaidgrammar that highlight.js does not ship, producing a 404 on every page containing a diagram. Replacing the whole<pre><code>pair avoids both problems, and is what the current shortcode path effectively already does. processMermaid()needs a newline after the init directive. It currently concatenates%%{init: ...}%%straight onto the diagram source. That works by accident for the shortcode, whose captured text begins with the newline that follows[mermaid], but it breaks for a code block whose content starts at the diagram keyword: the directive and the keyword land on the same line and Mermaid fails to parse.- The libraries are attached unconditionally. Every page that renders text through a format with this filter enabled pulls the Mermaid bundle, roughly 1 MB, whether or not the text contains a diagram. Attaching only when a diagram was found is the pattern Highlight.js Input Filter uses, and it is a straightforward win.
Remaining tasks
- Review the merge request.
- Decide whether the
filter_html_helpandfilter_html_nofollowsettings, declared in the plugin annotation but never read, should be removed. They look copy-pasted fromfilter_html. Removing them is a config change for existing sites, so it is deliberately left out of this issue. See #3592975, which adds the config schema they currently lack.
User interface changes
The filter tips gain a line documenting the code block form alongside the shortcode. No configuration changes.
API changes
None. The shortcode continues to work exactly as before, and existing content is unaffected.
How it was verified
On Drupal 10.6, with both syntaxes rendering to SVG on the same page, a PHP code block on that page keeping its normal highlighting, no console errors, and no library attached on pages without a diagram.
Issue fork mermaid-3616088
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
introfini commentedMR !5 is up.
Flagging one behaviour change that goes beyond the feature itself: the libraries were attached unconditionally, and are now attached only when a diagram is actually found. Sites with this filter enabled will stop pulling the Mermaid bundle on pages that contain no diagram. That is the point of the change, but it is a change, so it should not arrive as a surprise in review.
Verified on Drupal 10.6, with the module installed alongside Highlight.js Input Filter so the interaction described in the summary was actually exercised: both syntaxes rendering to SVG on the same page, a PHP code block on that page keeping its normal syntax highlighting, no console errors, and no library attached on pages without a diagram.
Comment #4
cmlaraTested with the markdown module (commonmark parser) using the patch and this appears to not be detecting the mermaid block as the JS is not attached.
If I add a [mermaid][/mermaid] block the JS is attached to the page and one mermaid image renders, however the code fenced one is still not detected.
Note I'm using a plain text (non ckeditor) field. Markdown processor first followed by the mermaid processor.
Raw HTML appears to match the regex however haven't done a full debug.
Personal note: separating the two different changes (conditional JS attachment and new code block matching) might help other reviewers. This is not my project so I can't speak for the code owner, however if it were mine I know I would want the two separate.
Side item:
Read the blog post, had actually encountered most those issues a couple weeks ago as well however had not had time to circle around here so thanks for the starting point.
Comment #5
cmlaraApologizes, user error on #4, filter either was never saved in the correct order, or I was looking at the wrong filter from previous tests.
Correctly ordered filter does appear to work.