Skip to content

Conversation

@danielfrey63
Copy link
Contributor

Summary

This PR fixes a Mermaid rendering issue caused by unescaped / unquoted node labels. The Mermaid component now preprocesses diagram text to safely quote labels and escape embedded quotes before rendering, preventing diagrams from failing to render or breaking when labels contain special characters.

Background / Problem

Mermaid diagrams can fail to render (or render inconsistently) when node or connection labels contain characters that Mermaid interprets as syntax—especially double quotes and certain label formats used inside:

  • |...|
  • (...)
  • [...]
  • {...}

In these cases, Mermaid parsing may throw errors and the UI ends up with a broken or missing diagram.

Fix / Approach

Changes in src/components/Mermaid.tsx:

  • Added a preprocessing step (preprocessMermaidLabels) that:

    • detects labels in common Mermaid node syntaxes,
    • wraps the label text in double quotes,
    • escapes any embedded " characters as ".
  • Rendering now uses the preprocessed chart text: mermaid.render(id, preprocessedChart)

  • Error output now displays the same preprocessed diagram text that was used for rendering, making failures easier to diagnose.

  • After rendering, mermaid.contentLoaded() is called (delayed) to ensure Mermaid completes initialization reliably.

Scope

  • Frontend-only change
  • Modified file: src/components/Mermaid.tsx
  • No new dependencies

How to Test

  • Open a page with Mermaid diagrams containing labels with quotes or special characters, e.g. labels like:
    • A[This is a label with a "quote"]
    • labels inside ( … ), [ … ], { … }, or | … |
  • Confirm diagrams render correctly.
  • Confirm that on invalid Mermaid input, the error view displays the preprocessed diagram text consistently.

Notes

This change is intentionally scoped to label preprocessing to avoid broader behavioral changes in Mermaid rendering.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @danielfrey63, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a common issue where Mermaid diagrams fail to render or display incorrectly due to unescaped or unquoted labels containing special characters. By introducing a preprocessing step, the system now intelligently quotes labels and escapes problematic characters before rendering, significantly enhancing the stability and reliability of Mermaid diagram display across the application.

Highlights

  • Mermaid Label Preprocessing: Introduced a new preprocessMermaidLabels function to automatically detect, quote, and escape special characters within Mermaid diagram labels, preventing rendering failures.
  • Enhanced Rendering Robustness: The Mermaid component now utilizes the preprocessed chart text for rendering, significantly improving the stability and reliability of diagram display, especially for labels with quotes or special characters.
  • Improved Error Diagnostics: When a Mermaid diagram fails to render, the error message now displays the preprocessed chart text, making it easier to diagnose and debug syntax issues.
  • Reliable Initialization: The mermaid.contentLoaded() function is now called after rendering to ensure Mermaid completes its initialization process reliably.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a preprocessing step to fix Mermaid rendering issues by quoting and escaping labels. The overall approach is sound and addresses the problem described. However, I've identified a couple of areas for improvement. The regular expression for finding labels does not correctly handle nested brackets, which could lead to malformed diagrams in some edge cases. Additionally, the logic for handling already-quoted labels can be simplified for better readability and maintainability. I've provided specific comments and suggestions to address these points.

import mermaid from 'mermaid';
// We'll use dynamic import for svg-pan-zoom

const MERMAID_LABELS_RE = /(\|)([^|\n]+)(\|)|(\()([^()\n]+)(\))|(\[)([^\[\]\n]+)(\])|(\{)([^{}\n]+)(\})/g;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The current regular expression does not handle nested brackets within labels. For example, for a label like (label with (nested) parens), the sub-expression (\()([^()\n]+)(\)) will incorrectly match up to the first closing parenthesis, resulting in (label with (nested). This leads to a malformed diagram string after processing. While handling balanced delimiters with regex is complex, this limitation could break diagrams that use such structures. The original diagram might have been invalid, but the transformation does not fix it and could make debugging harder. Please consider if a more robust parsing method is feasible or if this limitation should be documented.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we verify this before merging?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the hint. It was endeed a problem. I updated the PR.

Comment on lines 31 to 38
const trimmedInner = inner.trim();
const isAlreadyQuoted =
trimmedInner.length >= 2 &&
trimmedInner.startsWith('"') &&
trimmedInner.endsWith('"');

const quotedInnerMatch = inner.match(/^\s*"(.*)"\s*$/);
const unquotedInner = isAlreadyQuoted && quotedInnerMatch ? quotedInnerMatch[1] : inner;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The logic to determine if a label is already quoted and to extract its content can be simplified. The current implementation uses both a manual check (startsWith/endsWith) and a regex match, which is a bit complex. A single regex match can both check for quoting and extract the content more robustly.

This simplification improves readability and maintainability.

Suggested change
const trimmedInner = inner.trim();
const isAlreadyQuoted =
trimmedInner.length >= 2 &&
trimmedInner.startsWith('"') &&
trimmedInner.endsWith('"');
const quotedInnerMatch = inner.match(/^\s*"(.*)"\s*$/);
const unquotedInner = isAlreadyQuoted && quotedInnerMatch ? quotedInnerMatch[1] : inner;
const quotedInnerMatch = inner.match(/^\s*"(.*)"\s*$/);
const unquotedInner = quotedInnerMatch ? quotedInnerMatch[1] : inner;

@danielfrey63 danielfrey63 force-pushed the fix/mermaid-render-bug-fix branch from 5b23111 to 4ae86d9 Compare December 27, 2025 16:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants