mermaid-js/mermaid-cli

Empty diagram generation.

Opened this issue · 3 comments

Describe the bug
I'm trying to generate a mermaid diagram from an ouput. The output generates valid mermaid diagram in mermaid.live, but the generated output using the cli just gives me a diagram with no text.

To Reproduce
Execute this function:

def mermaid_to_base64(
    mermaid_string: str,
    width: int = 2048,
    height: int = 2048,
    scale: float = 3.0,
    background_color: str = "transparent",
) -> str:
    def preprocess_mermaid_string(mermaid_string: str) -> str:
        """
        Preprocesses the Mermaid string to handle quote escaping and remove accents.
        """
        try:
            data = json.loads(mermaid_string)
            mermaid_string = data
        except json.JSONDecodeError:
            pass

        mermaid_string = mermaid_string.replace('\\"', '"')

        # Remove accents
        mermaid_string = "".join(
            c
            for c in unicodedata.normalize("NFD", mermaid_string)
            if unicodedata.category(c) != "Mn"
        )

        return mermaid_string

    logger.debug("Original mermaid string: %s", mermaid_string)
    mermaid_string = preprocess_mermaid_string(mermaid_string)
    logger.debug("Preprocessed mermaid string: %s", mermaid_string)

    # Create temporary files for input and output
    with tempfile.NamedTemporaryFile(
        mode="w", suffix=".mmd", delete=False
    ) as input_file, tempfile.NamedTemporaryFile(
        mode="wb", suffix=".png", delete=False
    ) as output_file:
        # Write the Mermaid string to the input file
        input_file.write(mermaid_string)
        input_file.flush()

        # Close the files to ensure all data is written
        input_file.close()
        output_file.close()

        try:
            # Run mmdc (Mermaid CLI) command with additional parameters
            subprocess.run(
                [
                    "mmdc",
                    "-i",
                    input_file.name,
                    "-o",
                    output_file.name,
                    "-b",
                    background_color,
                    "-w",
                    str(width),
                    "-H",
                    str(height),
                    "-s",
                    str(scale),
                ],
                check=True,
                capture_output=True,
                text=True,
            )

            # Read the output PNG file and encode it to base64
            with open(output_file.name, "rb") as f:
                image_data = f.read()
                base64_encoded = base64.b64encode(image_data).decode("utf-8")

            return base64_encoded

        except subprocess.CalledProcessError as e:
            logger.error(f"Error running Mermaid CLI: {e.stderr}")
            raise
        finally:
            # Clean up temporary files
            os.unlink(input_file.name)
            os.unlink(output_file.name)

    return ""

Expected behavior
To generate a mermaid diagram with the original text in it.

Screenshots
any diagram will look like this:
image

I'm using mmdc 10.3.1, NixOS (Google IDX) with pkgs.mermaid-cli.

Additional context
Add any other context about the problem here.

I think this is a duplicate of: #691

TLDR:

It looks like this is an issue with mermaid-cli after all:
[Mermaid's] SVG uses foreignObject to embed HTML text. Supporting this would basically involve having a whole HTML renderer inside librsvg. Please tell mermaid-cli to use SVG text elements instead.

Sorry, I still don't understand, @Mo-way. Is this a solution?

Please tell mermaid-cli to use SVG text elements instead.

In this case, how can I instruct mermaid-cli to do this?

Hi @pbittencourt, you might have some luck by following mermaid-js/mermaid#2688 (comment)

Some diagrams have a htmlLabels: false config setting that you can pass that might stop them from using <foreignObject>/embedded HTML.

However, even if you do do this, some Mermaid diagrams still use CSS which is valid in the SVG 2.0, but isn't valid in SVG 1.1 that many libraries like librsvg (see mermaid-js/mermaid#2102)

As a work-around, you could try asking mermaid-cli to make a PDF file, then using a tool like pdf2svg to create an SVG file from that PDF: mermaid-js/mermaid#2102 (comment)