mermaid-js / mermaid-cli

Command line tool for the Mermaid library
MIT License
2.36k stars 227 forks source link

Empty diagram generation. #724

Open arthurbrenno opened 1 month ago

arthurbrenno commented 1 month ago

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.

Mo-way commented 1 month ago

I think this is a duplicate of: https://github.com/mermaid-js/mermaid-cli/issues/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.