@mermaid-js/mermaid-cli 9.1.6 → 9.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -1
- package/{fontawesome/webfonts/fa-brands-400.svg → dist/assets/fa-brands-400.ce2af7e2.svg} +0 -0
- package/{fontawesome/webfonts/fa-regular-400.svg → dist/assets/fa-regular-400.e519b693.svg} +0 -0
- package/{fontawesome/webfonts/fa-solid-900.svg → dist/assets/fa-solid-900.3e918c25.svg} +0 -0
- package/dist/index.html +1398 -0
- package/package.json +12 -11
- package/src/index.js +203 -92
- package/fontawesome/css/fa-brands.css +0 -9
- package/fontawesome/css/fa-regular.css +0 -10
- package/fontawesome/css/fa-solid.css +0 -11
- package/fontawesome/css/fontawesome.css +0 -3173
- package/fontawesome/webfonts/fa-brands-400.eot +0 -0
- package/fontawesome/webfonts/fa-brands-400.ttf +0 -0
- package/fontawesome/webfonts/fa-brands-400.woff +0 -0
- package/fontawesome/webfonts/fa-brands-400.woff2 +0 -0
- package/fontawesome/webfonts/fa-regular-400.eot +0 -0
- package/fontawesome/webfonts/fa-regular-400.ttf +0 -0
- package/fontawesome/webfonts/fa-regular-400.woff +0 -0
- package/fontawesome/webfonts/fa-regular-400.woff2 +0 -0
- package/fontawesome/webfonts/fa-solid-900.eot +0 -0
- package/fontawesome/webfonts/fa-solid-900.ttf +0 -0
- package/fontawesome/webfonts/fa-solid-900.woff +0 -0
- package/fontawesome/webfonts/fa-solid-900.woff2 +0 -0
- package/index.html +0 -13
- package/mermaid.min.js +0 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mermaid-js/mermaid-cli",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.2.2",
|
|
4
4
|
"description": "Command-line interface for mermaid",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "git@github.com:mermaid-js/mermaid-cli.git",
|
|
@@ -14,9 +14,8 @@
|
|
|
14
14
|
},
|
|
15
15
|
"exports": "./src/index.js",
|
|
16
16
|
"scripts": {
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"prepack": "sh copy_modules.sh",
|
|
17
|
+
"prepare": "vite build",
|
|
18
|
+
"prepack": "vite build",
|
|
20
19
|
"test": "standard && yarn node --experimental-vm-modules $(yarn bin jest)",
|
|
21
20
|
"lint": "standard",
|
|
22
21
|
"lint-fix": "standard --fix"
|
|
@@ -24,20 +23,22 @@
|
|
|
24
23
|
"dependencies": {
|
|
25
24
|
"chalk": "^5.0.1",
|
|
26
25
|
"commander": "^9.0.0",
|
|
27
|
-
"puppeteer": "^
|
|
26
|
+
"puppeteer": "^19.0.0"
|
|
28
27
|
},
|
|
29
28
|
"devDependencies": {
|
|
30
29
|
"@fortawesome/fontawesome-free-webfonts": "^1.0.9",
|
|
31
|
-
"mermaid": "^9.
|
|
32
|
-
"
|
|
30
|
+
"@mermaid-js/mermaid-mindmap": "^9.2.2",
|
|
31
|
+
"mermaid": "^9.2.2",
|
|
32
|
+
"jest": "^29.0.1",
|
|
33
33
|
"standard": "^17.0.0",
|
|
34
|
+
"vite": "^3.2.3",
|
|
35
|
+
"vite-plugin-singlefile": "^0.13.1",
|
|
36
|
+
"vite-svg-loader": "^3.6.0",
|
|
34
37
|
"yarn-upgrade-all": "^0.7.0"
|
|
35
38
|
},
|
|
36
39
|
"files": [
|
|
37
40
|
"src/",
|
|
38
|
-
"
|
|
39
|
-
"index.html",
|
|
40
|
-
"fontawesome/*"
|
|
41
|
+
"dist/"
|
|
41
42
|
],
|
|
42
43
|
"jest": {
|
|
43
44
|
"moduleNameMapper": {
|
|
@@ -46,7 +47,7 @@
|
|
|
46
47
|
},
|
|
47
48
|
"standard": {
|
|
48
49
|
"ignore": [
|
|
49
|
-
"
|
|
50
|
+
"/dist/"
|
|
50
51
|
]
|
|
51
52
|
}
|
|
52
53
|
}
|
package/src/index.js
CHANGED
|
@@ -60,13 +60,7 @@ const getInputData = async inputFile => new Promise((resolve, reject) => {
|
|
|
60
60
|
})
|
|
61
61
|
})
|
|
62
62
|
|
|
63
|
-
const convertToValidXML = html => {
|
|
64
|
-
// <br> tags in valid HTML (from innerHTML) look like <br>, but they must look like <br/> to be valid XML (such as SVG)
|
|
65
|
-
return html.replace(/<br>/gi, '<br/>')
|
|
66
|
-
}
|
|
67
|
-
|
|
68
63
|
async function cli () {
|
|
69
|
-
// TODO: This is currently unindented to make `git diff` easier for PR reviewers.
|
|
70
64
|
const commander = new Command()
|
|
71
65
|
commander
|
|
72
66
|
.version(pkg.version)
|
|
@@ -75,6 +69,7 @@ async function cli () {
|
|
|
75
69
|
.option('-H, --height [height]', 'Height of the page. Optional. Default: 600', /^\d+$/, '600')
|
|
76
70
|
.option('-i, --input <input>', 'Input mermaid file. Files ending in .md will be treated as Markdown and all charts (e.g. ```mermaid (...)```) will be extracted and generated. Required.')
|
|
77
71
|
.option('-o, --output [output]', 'Output file. It should be either md, svg, png or pdf. Optional. Default: input + ".svg"')
|
|
72
|
+
.option('-e, --outputFormat <format>', 'Output format for the generated image. It should be either svg, png or pdf. Optional. Default: output file extension')
|
|
78
73
|
.option('-b, --backgroundColor [backgroundColor]', 'Background color for pngs/svgs (not pdfs). Example: transparent, red, \'#F0F0F0\'. Optional. Default: white')
|
|
79
74
|
.option('-c, --configFile [configFile]', 'JSON configuration file for mermaid. Optional')
|
|
80
75
|
.option('-C, --cssFile [cssFile]', 'CSS file for the page. Optional')
|
|
@@ -86,7 +81,7 @@ async function cli () {
|
|
|
86
81
|
|
|
87
82
|
const options = commander.opts()
|
|
88
83
|
|
|
89
|
-
let { theme, width, height, input, output, backgroundColor, configFile, cssFile, puppeteerConfigFile, scale, pdfFit, quiet } = options
|
|
84
|
+
let { theme, width, height, input, output, outputFormat, backgroundColor, configFile, cssFile, puppeteerConfigFile, scale, pdfFit, quiet } = options
|
|
90
85
|
|
|
91
86
|
// check input file
|
|
92
87
|
if (!(input || inputPipedFromStdin())) {
|
|
@@ -103,7 +98,11 @@ async function cli () {
|
|
|
103
98
|
// if an input file is defined, it should take precedence, otherwise, input is
|
|
104
99
|
// coming from stdin and just name the file out.svg, if it hasn't been
|
|
105
100
|
// specified with the '-o' option
|
|
106
|
-
|
|
101
|
+
if (outputFormat) {
|
|
102
|
+
output = input ? (`${input}.${outputFormat}`) : `out.${outputFormat}`
|
|
103
|
+
} else {
|
|
104
|
+
output = input ? (`${input}.svg`) : 'out.svg'
|
|
105
|
+
}
|
|
107
106
|
}
|
|
108
107
|
if (!/\.(?:svg|png|pdf|md)$/.test(output)) {
|
|
109
108
|
error('Output file must end with ".md", ".svg", ".png" or ".pdf"')
|
|
@@ -144,6 +143,7 @@ async function cli () {
|
|
|
144
143
|
input, output, {
|
|
145
144
|
puppeteerConfig,
|
|
146
145
|
quiet,
|
|
146
|
+
outputFormat,
|
|
147
147
|
parseMMDOptions: {
|
|
148
148
|
mermaidConfig, backgroundColor, myCSS, pdfFit, viewport: { width, height, deviceScaleFactor }
|
|
149
149
|
}
|
|
@@ -163,84 +163,172 @@ async function cli () {
|
|
|
163
163
|
/**
|
|
164
164
|
* Parse and render a mermaid diagram.
|
|
165
165
|
*
|
|
166
|
+
* @deprecated Prefer {@link renderMermaid}, as it also returns useful metadata.
|
|
167
|
+
*
|
|
166
168
|
* @param {puppeteer.Browser} browser - Puppeteer Browser
|
|
167
169
|
* @param {string} definition - Mermaid diagram definition
|
|
168
170
|
* @param {"svg" | "png" | "pdf"} outputFormat - Mermaid output format.
|
|
169
171
|
* @param {ParseMDDOptions} [opt] - Options, see {@link ParseMDDOptions} for details.
|
|
172
|
+
*
|
|
170
173
|
* @returns {Promise<Buffer>} The output file in bytes.
|
|
171
174
|
*/
|
|
172
|
-
async function parseMMD (
|
|
175
|
+
async function parseMMD (...args) {
|
|
176
|
+
const { data } = await renderMermaid(...args)
|
|
177
|
+
return data
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Render a mermaid diagram.
|
|
182
|
+
*
|
|
183
|
+
* @param {puppeteer.Browser} browser - Puppeteer Browser
|
|
184
|
+
* @param {string} definition - Mermaid diagram definition
|
|
185
|
+
* @param {"svg" | "png" | "pdf"} outputFormat - Mermaid output format.
|
|
186
|
+
* @param {ParseMDDOptions} [opt] - Options, see {@link ParseMDDOptions} for details.
|
|
187
|
+
* @returns {Promise<{title?: string, desc?: string, data: Buffer}>} The output file in bytes,
|
|
188
|
+
* with optional metadata.
|
|
189
|
+
*/
|
|
190
|
+
async function renderMermaid (browser, definition, outputFormat, { viewport, backgroundColor = 'white', mermaidConfig = {}, myCSS, pdfFit } = {}) {
|
|
173
191
|
const page = await browser.newPage()
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
192
|
+
page.on('console', (msg) => {
|
|
193
|
+
console.log(msg.text())
|
|
194
|
+
})
|
|
195
|
+
try {
|
|
196
|
+
if (viewport) {
|
|
197
|
+
await page.setViewport(viewport)
|
|
198
|
+
}
|
|
199
|
+
const mermaidHTMLPath = path.join(__dirname, '..', 'dist', 'index.html')
|
|
200
|
+
await page.goto(url.pathToFileURL(mermaidHTMLPath))
|
|
201
|
+
await page.$eval('body', (body, backgroundColor) => {
|
|
202
|
+
body.style.background = backgroundColor
|
|
203
|
+
}, backgroundColor)
|
|
204
|
+
const metadata = await page.$eval('#container', async (container, definition, mermaidConfig, myCSS, backgroundColor) => {
|
|
205
|
+
container.textContent = definition
|
|
206
|
+
|
|
207
|
+
/** @type {import("mermaid")} Already imported mermaid instance */
|
|
208
|
+
const mermaid = globalThis.mermaid
|
|
209
|
+
/** @type {import("@mermaid-js/mermaid-mindmap")} */
|
|
210
|
+
const mermaidMindmap = globalThis.mermaidMindmap
|
|
211
|
+
|
|
212
|
+
await mermaid.registerExternalDiagrams([mermaidMindmap])
|
|
213
|
+
|
|
214
|
+
mermaid.initialize(mermaidConfig)
|
|
215
|
+
// should throw an error if mmd diagram is invalid
|
|
216
|
+
try {
|
|
217
|
+
await mermaid.initThrowsErrorsAsync(undefined, container)
|
|
218
|
+
} catch (error) {
|
|
219
|
+
if (error instanceof Error) {
|
|
220
|
+
// mermaid-js doesn't currently throws JS Errors, but let's leave this
|
|
221
|
+
// here in case it does in the future
|
|
222
|
+
throw error
|
|
223
|
+
} else {
|
|
224
|
+
throw new Error(error?.message ?? 'Unknown mermaid render error')
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const svg = container.getElementsByTagName?.('svg')?.[0]
|
|
229
|
+
if (svg?.style) {
|
|
230
|
+
svg.style.backgroundColor = backgroundColor
|
|
193
231
|
} else {
|
|
194
|
-
|
|
232
|
+
warn('svg not found. Not applying background color.')
|
|
233
|
+
}
|
|
234
|
+
if (myCSS) {
|
|
235
|
+
// add CSS as a <svg>...<style>... element
|
|
236
|
+
// see https://developer.mozilla.org/en-US/docs/Web/API/SVGStyleElement
|
|
237
|
+
const style = document.createElementNS('http://www.w3.org/2000/svg', 'style')
|
|
238
|
+
style.appendChild(document.createTextNode(myCSS))
|
|
239
|
+
svg.appendChild(style)
|
|
195
240
|
}
|
|
196
|
-
}
|
|
197
241
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
242
|
+
// Finds SVG metadata for accessibility purposes
|
|
243
|
+
/** SVG title */
|
|
244
|
+
let title = null
|
|
245
|
+
// If <title> exists, it must be the first child Node,
|
|
246
|
+
// see https://www.w3.org/TR/SVG11/struct.html#DescriptionAndTitleElements
|
|
247
|
+
/* global SVGTitleElement, SVGDescElement */ // These exist in browser-based code
|
|
248
|
+
if (svg.firstChild instanceof SVGTitleElement) {
|
|
249
|
+
title = svg.firstChild.textContent
|
|
250
|
+
}
|
|
251
|
+
/** SVG description. According to SVG spec, we should use the first one we find */
|
|
252
|
+
let desc = null
|
|
253
|
+
for (const svgNode of svg.children) {
|
|
254
|
+
if (svgNode instanceof SVGDescElement) {
|
|
255
|
+
desc = svgNode.textContent
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return {
|
|
259
|
+
title, desc
|
|
260
|
+
}
|
|
261
|
+
}, definition, mermaidConfig, myCSS, backgroundColor)
|
|
213
262
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
return {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
if (pdfFit) {
|
|
263
|
+
if (outputFormat === 'svg') {
|
|
264
|
+
const svgXML = await page.$eval('svg', (svg) => {
|
|
265
|
+
// SVG might have HTML <foreignObject> that are not valid XML
|
|
266
|
+
// E.g. <br> must be replaced with <br/>
|
|
267
|
+
// Luckily the DOM Web API has the XMLSerializer for this
|
|
268
|
+
// eslint-disable-next-line no-undef
|
|
269
|
+
const xmlSerializer = new XMLSerializer()
|
|
270
|
+
return xmlSerializer.serializeToString(svg)
|
|
271
|
+
})
|
|
272
|
+
return {
|
|
273
|
+
...metadata,
|
|
274
|
+
data: Buffer.from(svgXML, 'utf8')
|
|
275
|
+
}
|
|
276
|
+
} else if (outputFormat === 'png') {
|
|
229
277
|
const clip = await page.$eval('svg', svg => {
|
|
230
278
|
const react = svg.getBoundingClientRect()
|
|
231
|
-
return { x: react.left, y: react.top, width: react.width, height: react.height }
|
|
232
|
-
})
|
|
233
|
-
return await page.pdf({
|
|
234
|
-
omitBackground: backgroundColor === 'transparent',
|
|
235
|
-
width: (Math.ceil(clip.width) + clip.x * 2) + 'px',
|
|
236
|
-
height: (Math.ceil(clip.height) + clip.y * 2) + 'px',
|
|
237
|
-
pageRanges: '1-1'
|
|
238
|
-
})
|
|
239
|
-
} else {
|
|
240
|
-
return await page.pdf({
|
|
241
|
-
omitBackground: backgroundColor === 'transparent'
|
|
279
|
+
return { x: Math.floor(react.left), y: Math.floor(react.top), width: Math.ceil(react.width), height: Math.ceil(react.height) }
|
|
242
280
|
})
|
|
281
|
+
await page.setViewport({ ...viewport, width: clip.x + clip.width, height: clip.y + clip.height })
|
|
282
|
+
return {
|
|
283
|
+
...metadata,
|
|
284
|
+
data: await page.screenshot({ clip, omitBackground: backgroundColor === 'transparent' })
|
|
285
|
+
}
|
|
286
|
+
} else { // pdf
|
|
287
|
+
if (pdfFit) {
|
|
288
|
+
const clip = await page.$eval('svg', svg => {
|
|
289
|
+
const react = svg.getBoundingClientRect()
|
|
290
|
+
return { x: react.left, y: react.top, width: react.width, height: react.height }
|
|
291
|
+
})
|
|
292
|
+
return {
|
|
293
|
+
...metadata,
|
|
294
|
+
data: await page.pdf({
|
|
295
|
+
omitBackground: backgroundColor === 'transparent',
|
|
296
|
+
width: (Math.ceil(clip.width) + clip.x * 2) + 'px',
|
|
297
|
+
height: (Math.ceil(clip.height) + clip.y * 2) + 'px',
|
|
298
|
+
pageRanges: '1-1'
|
|
299
|
+
})
|
|
300
|
+
}
|
|
301
|
+
} else {
|
|
302
|
+
return {
|
|
303
|
+
...metadata,
|
|
304
|
+
data: await page.pdf({
|
|
305
|
+
omitBackground: backgroundColor === 'transparent'
|
|
306
|
+
})
|
|
307
|
+
}
|
|
308
|
+
}
|
|
243
309
|
}
|
|
310
|
+
} finally {
|
|
311
|
+
await page.close()
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Creates a markdown image syntax.
|
|
317
|
+
*
|
|
318
|
+
* @param {object} params - Parameters.
|
|
319
|
+
* @param {string} params.url - Path to image.
|
|
320
|
+
* @param {string} params.alt - Image alt text, required.
|
|
321
|
+
* @param {string} [params.title] - Image title text.
|
|
322
|
+
* @returns {``} The markdown image text.
|
|
323
|
+
*/
|
|
324
|
+
function markdownImage ({ url, title, alt }) {
|
|
325
|
+
// we can't use String.prototype.replaceAll since it's not supported in Node v14
|
|
326
|
+
const altEscaped = alt.replace(/[[\]\\]/g, '\\$&')
|
|
327
|
+
if (title) {
|
|
328
|
+
const titleEscaped = title.replace(/["\\]/g, '\\$&')
|
|
329
|
+
return ``
|
|
330
|
+
} else {
|
|
331
|
+
return ``
|
|
244
332
|
}
|
|
245
333
|
}
|
|
246
334
|
|
|
@@ -254,57 +342,80 @@ async function parseMMD (browser, definition, outputFormat, { viewport, backgrou
|
|
|
254
342
|
* @param {Object} [opts] - Options
|
|
255
343
|
* @param {puppeteer.LaunchOptions} [opts.puppeteerConfig] - Puppeteer launch options.
|
|
256
344
|
* @param {boolean} [opts.quiet] - If set, suppress log output.
|
|
345
|
+
* @param {"svg" | "png" | "pdf"} [opts.outputFormat] - Mermaid output format.
|
|
346
|
+
* Defaults to `output` extension. Overrides `output` extension if set.
|
|
257
347
|
* @param {ParseMDDOptions} [opts.parseMMDOptions] - Options to pass to {@link parseMMDOptions}.
|
|
258
348
|
*/
|
|
259
|
-
async function run (input, output, { puppeteerConfig = {}, quiet = false, parseMMDOptions } = {}) {
|
|
349
|
+
async function run (input, output, { puppeteerConfig = {}, quiet = false, outputFormat, parseMMDOptions } = {}) {
|
|
260
350
|
const info = message => {
|
|
261
351
|
if (!quiet) {
|
|
262
352
|
console.info(message)
|
|
263
353
|
}
|
|
264
354
|
}
|
|
265
355
|
|
|
266
|
-
const mermaidChartsInMarkdown =
|
|
356
|
+
const mermaidChartsInMarkdown = /^\s*```(?:mermaid)(\r?\n([\s\S]*?))```\s*$/
|
|
267
357
|
const mermaidChartsInMarkdownRegexGlobal = new RegExp(mermaidChartsInMarkdown, 'gm')
|
|
268
|
-
const mermaidChartsInMarkdownRegex = new RegExp(mermaidChartsInMarkdown)
|
|
269
358
|
const browser = await puppeteer.launch(puppeteerConfig)
|
|
270
359
|
try {
|
|
271
|
-
|
|
360
|
+
if (!outputFormat) {
|
|
361
|
+
outputFormat = path.extname(output).replace('.', '')
|
|
362
|
+
}
|
|
363
|
+
if (outputFormat === 'md') {
|
|
364
|
+
// fallback to svg in case no outputFormat is given and output file is MD
|
|
365
|
+
outputFormat = 'svg'
|
|
366
|
+
}
|
|
367
|
+
if (!/(?:svg|png|pdf)$/.test(outputFormat)) {
|
|
368
|
+
throw new Error('Output format must be one of "svg", "png" or "pdf"')
|
|
369
|
+
}
|
|
370
|
+
|
|
272
371
|
const definition = await getInputData(input)
|
|
273
372
|
if (/\.md$/.test(input)) {
|
|
274
|
-
const
|
|
275
|
-
const
|
|
276
|
-
const
|
|
373
|
+
const imagePromises = []
|
|
374
|
+
for (const mermaidCodeblockMatch of definition.matchAll(mermaidChartsInMarkdownRegexGlobal)) {
|
|
375
|
+
const mermaidDefinition = mermaidCodeblockMatch[1]
|
|
277
376
|
|
|
278
377
|
// Output can be either a template image file, or a `.md` output file.
|
|
279
378
|
// If it is a template image file, use that to created numbered diagrams
|
|
280
379
|
// I.e. if "out.png", use "out-1.png", "out-2.png", etc
|
|
281
380
|
// If it is an output `.md` file, use that to base .svg numbered diagrams on
|
|
282
381
|
// I.e. if "out.md". use "out-1.svg", "out-2.svg", etc
|
|
283
|
-
const outputFile = output.replace(/(\.(md|png|svg|pdf))$/, `-${
|
|
382
|
+
const outputFile = output.replace(/(\.(md|png|svg|pdf))$/, `-${imagePromises.length + 1}$1`).replace(/(\.md)$/, `.${outputFormat}`)
|
|
284
383
|
const outputFileRelative = `./${path.relative(path.dirname(path.resolve(output)), path.resolve(outputFile))}`
|
|
285
|
-
diagrams.push([outputFile, md])
|
|
286
|
-
return ``
|
|
287
|
-
})
|
|
288
384
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
385
|
+
const imagePromise = (async () => {
|
|
386
|
+
const { title, desc, data } = await renderMermaid(browser, mermaidDefinition, outputFormat, parseMMDOptions)
|
|
387
|
+
await fs.promises.writeFile(outputFile, data)
|
|
388
|
+
info(` ✅ ${outputFileRelative}`)
|
|
389
|
+
|
|
390
|
+
return {
|
|
391
|
+
url: outputFileRelative,
|
|
392
|
+
title,
|
|
393
|
+
alt: desc
|
|
394
|
+
}
|
|
395
|
+
})()
|
|
396
|
+
imagePromises.push(imagePromise)
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
if (imagePromises.length) {
|
|
400
|
+
info(`Found ${imagePromises.length} mermaid charts in Markdown input`)
|
|
297
401
|
} else {
|
|
298
402
|
info('No mermaid charts found in Markdown input')
|
|
299
403
|
}
|
|
300
404
|
|
|
405
|
+
const images = await Promise.all(imagePromises)
|
|
406
|
+
|
|
301
407
|
if (/\.md$/.test(output)) {
|
|
408
|
+
const outDefinition = definition.replace(mermaidChartsInMarkdownRegexGlobal, (_mermaidMd) => {
|
|
409
|
+
// pop first image from front of array
|
|
410
|
+
const { url, title, alt } = images.shift()
|
|
411
|
+
return markdownImage({ url, title, alt: alt || 'diagram' })
|
|
412
|
+
})
|
|
302
413
|
await fs.promises.writeFile(output, outDefinition, 'utf-8')
|
|
303
414
|
info(` ✅ ${output}`)
|
|
304
415
|
}
|
|
305
416
|
} else {
|
|
306
417
|
info('Generating single mermaid chart')
|
|
307
|
-
const data = await parseMMD(browser, definition,
|
|
418
|
+
const data = await parseMMD(browser, definition, outputFormat, parseMMDOptions)
|
|
308
419
|
await fs.promises.writeFile(output, data)
|
|
309
420
|
}
|
|
310
421
|
} finally {
|
|
@@ -312,4 +423,4 @@ async function run (input, output, { puppeteerConfig = {}, quiet = false, parseM
|
|
|
312
423
|
}
|
|
313
424
|
}
|
|
314
425
|
|
|
315
|
-
export { run, parseMMD, cli, error }
|
|
426
|
+
export { run, renderMermaid, parseMMD, cli, error }
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
@font-face {
|
|
2
|
-
font-family: 'Font Awesome 5 Brands';
|
|
3
|
-
font-style: normal;
|
|
4
|
-
font-weight: normal;
|
|
5
|
-
src: url("../webfonts/fa-brands-400.eot");
|
|
6
|
-
src: url("../webfonts/fa-brands-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.woff") format("woff"), url("../webfonts/fa-brands-400.ttf") format("truetype"), url("../webfonts/fa-brands-400.svg#fontawesome") format("svg"); }
|
|
7
|
-
|
|
8
|
-
.fab {
|
|
9
|
-
font-family: 'Font Awesome 5 Brands'; }
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
@font-face {
|
|
2
|
-
font-family: 'Font Awesome 5 Free';
|
|
3
|
-
font-style: normal;
|
|
4
|
-
font-weight: 400;
|
|
5
|
-
src: url("../webfonts/fa-regular-400.eot");
|
|
6
|
-
src: url("../webfonts/fa-regular-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.woff") format("woff"), url("../webfonts/fa-regular-400.ttf") format("truetype"), url("../webfonts/fa-regular-400.svg#fontawesome") format("svg"); }
|
|
7
|
-
|
|
8
|
-
.far {
|
|
9
|
-
font-family: 'Font Awesome 5 Free';
|
|
10
|
-
font-weight: 400; }
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
@font-face {
|
|
2
|
-
font-family: 'Font Awesome 5 Free';
|
|
3
|
-
font-style: normal;
|
|
4
|
-
font-weight: 900;
|
|
5
|
-
src: url("../webfonts/fa-solid-900.eot");
|
|
6
|
-
src: url("../webfonts/fa-solid-900.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.woff") format("woff"), url("../webfonts/fa-solid-900.ttf") format("truetype"), url("../webfonts/fa-solid-900.svg#fontawesome") format("svg"); }
|
|
7
|
-
|
|
8
|
-
.fa,
|
|
9
|
-
.fas {
|
|
10
|
-
font-family: 'Font Awesome 5 Free';
|
|
11
|
-
font-weight: 900; }
|