Skip to content

Commit

Permalink
fix: use mermaid.render() instead of .run()
Browse files Browse the repository at this point in the history
Currently, `mermaid-cli` renders mermaid diagrams by:

mmd code → HTML `<div>` contexts → mermaid.run() → HTML `<svg>`

However, when converting the mmd code to HTML `<div>`, newlines and
whitespace formatting may get removed. For the majority of diagrams,
this is no issue, but for some diagrams (e.g. classDiagram), whitespace
does matter.

The mermaid API has a `mermaid.render()` function that we can use
instead, which parses in mmd code directly, without having to go
through a HTML element first:

mmd code →  mermaid.render() →  SVG →  HTML `<svg>`

As an aditional benefit, we get better error messages from Mermaid too!

Fixes: mermaid-js#532
  • Loading branch information
aloisklink committed May 4, 2023
1 parent dc4c4ca commit 69c5fc7
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 36 deletions.
2 changes: 1 addition & 1 deletion src-test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ describe("NodeJS API (import ... from '@mermaid-js/mermaid-cli')", () => {
const invalidMMDInput = 'this is not a valid mermaid file'
expect(
parseMMD(browser, invalidMMDInput, 'svg')
).rejects.toThrow('Evaluation failed: Error: No diagram type detected matching given configuration for text: this is not a valid mermaid file')
).rejects.toThrow('Evaluation failed: UnknownDiagramError: No diagram type detected matching given configuration for text: this is not a valid mermaid file')
})

describe.each(workflows)('testing workflow %s', (workflow) => {
Expand Down
37 changes: 2 additions & 35 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,20 +239,6 @@ async function renderMermaid (browser, definition, outputFormat, { viewport, bac
body.style.background = backgroundColor
}, backgroundColor)
const metadata = await page.$eval('#container', async (container, definition, mermaidConfig, myCSS, backgroundColor) => {
/**
* Checks to see if the given object is one of Mermaid's DetailedErrors.
*
* @param {unknown} error - The error to check
* @returns {error is import("mermaid").DetailedError} Returns `true` is the `error`
* is a `Mermaid.DetailedError`.
* @see https://github.com/mermaid-js/mermaid/blob/v10.0.1/packages/mermaid/src/utils.ts#L927-L930
*/
function isDetailedError (error) {
return typeof error === 'object' && error !== null && 'str' in error
}

container.textContent = definition

/**
* @typedef {Object} GlobalThisWithMermaid
* We've already imported these modules in our `index.html` file, so that they
Expand All @@ -263,27 +249,8 @@ async function renderMermaid (browser, definition, outputFormat, { viewport, bac

mermaid.initialize(mermaidConfig)
// should throw an error if mmd diagram is invalid
try {
await mermaid.run({
nodes: [
/**
* @type {HTMLElement} We know this is a `HTMLElement`, since we
* control the input HTML file
*/ (container)
],
suppressErrors: false
})
} catch (error) {
if (error instanceof Error) {
// mermaid-js doesn't currently throws JS Errors, but let's leave this
// here in case it does in the future
throw error
} else if (isDetailedError(error)) {
throw new Error(error.message)
} else {
throw new Error(`Unknown mermaid render error: ${error}`)
}
}
const { svg: svgText } = await mermaid.render('my-svg', definition, container)
container.innerHTML = svgText

const svg = container.getElementsByTagName?.('svg')?.[0]
if (svg?.style) {
Expand Down
9 changes: 9 additions & 0 deletions test-positive/classDiagram-v2.mmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
# This test is for issue https://github.com/mermaid-js/mermaid-cli/issues/532
title: Empty class diagram v2 structs
---
classDiagram-v2
class Pancake {
}
class Waffle {
}

0 comments on commit 69c5fc7

Please sign in to comment.