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:

  1. The <code> element must not survive into the output. Sites that also run a highlight.js integration call hljs.highlightAll(), which walks every pre code in 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 a mermaid grammar 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.
  2. 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.
  3. 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_help and filter_html_nofollow settings, declared in the plugin annotation but never read, should be removed. They look copy-pasted from filter_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

Command icon 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

introfini created an issue. See original summary.

introfini’s picture

Status: Active » Needs review

MR !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.

cmlara’s picture

Status: Needs review » Needs work

Tested 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.

cmlara’s picture

Status: Needs work » Reviewed & tested by the community

Apologizes, 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.