Last active
September 22, 2020 06:04
-
-
Save rheinardkorf/95588360a25b516b528348d7f761e99d to your computer and use it in GitHub Desktop.
Alternate Remark-Mermaid Plugin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"sequence":{ | |
"diagramMarginY" :10, | |
"diagramMarginX" :50, | |
"actorMargin" :50, | |
"width" :150, | |
"height" :65, | |
"boxMargin" :10, | |
"boxTextMargin" :5, | |
"noteMargin" :10, | |
"messageMargin" :35, | |
"messageAlign" :"center", | |
"mirrorActors" :false, | |
"bottomMarginAdj" :1, | |
"useMaxWidth" :true, | |
"rightAngles" :false, | |
"showSequenceNumbers" :false | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"plugins": { | |
"./remark-mermaid-alt.js": { | |
"destination": "./docs/images", | |
"linkRoot": "./images/", | |
"mermaidArgs": { | |
"configFile": ".mermaidrc" | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const crypto = require( 'crypto' ); | |
const fs = require( 'fs-extra' ); | |
const path = require( 'path' ); | |
const visit = require( 'unist-util-visit' ); | |
const { execSync } = require( 'child_process' ); | |
const mmdc = require.resolve( '@mermaid-js/mermaid-cli/index.bundle.js' ); | |
const PLUGIN_NAME = 'remark-mermaid-alt'; | |
async function generateSVG( value, file, options ) { | |
const { destination = './images', mermaidArgs = {} } = options; | |
// Unique paths. | |
const unique = crypto | |
.createHmac( 'sha1', PLUGIN_NAME ) | |
.update( value ) | |
.digest( 'hex' ); | |
const inputFile = `${ unique }.mmd`; | |
const mmdPath = path.join( destination, inputFile ); | |
const outputFile = `${ unique }.svg`; | |
const svgPath = path.join( destination, outputFile ); | |
// Args for CLI. | |
mermaidArgs.input = mmdPath; | |
mermaidArgs.output = svgPath; | |
const args = [] | |
.concat( | |
...Object.keys( mermaidArgs ).map( ( k ) => [ | |
`--${ k }`, | |
mermaidArgs[ k ], | |
] ) | |
) | |
.join( ' ' ); | |
// Write temp file. | |
fs.outputFileSync( mmdPath, value, { encoding: 'utf8' } ); | |
// Execute mermaid. | |
execSync( `${ mmdc } ${ args }` ); | |
// Clean up. | |
fs.removeSync( mmdPath ); | |
return `${ outputFile }`; | |
} | |
async function transformMermaidNode( node, file, index, parent, options ) { | |
const { lang, value, position } = node; | |
try { | |
const { linkRoot = './' } = options; | |
const svgFile = await generateSVG( value, file, options ); | |
const message = `${ lang } code block replaced with rendered mermaid SVG`; | |
file.info( message, position, PLUGIN_NAME ); | |
const newNode = { | |
type: 'image', | |
title: '`mermaid` image', | |
url: `${ linkRoot }${ svgFile }`, | |
}; | |
parent.children.splice( index, 1, newNode ); | |
} catch ( error ) { | |
file.fail( error, position, PLUGIN_NAME ); | |
} | |
return node; | |
} | |
/** | |
* Remark plugin that converts mermaid codeblocks into SVG files. | |
* | |
* @param {Object} options | |
*/ | |
function mermaid( options = {} ) { | |
/** | |
* Look for all code nodes that have the language mermaid, | |
* generate SVGs and update the url. | |
* | |
* @param {Node} ast The Markdown Tree | |
* @param {Object} file The virtual file. | |
* @return {Promise<void>} The altered tree. | |
*/ | |
return async function ( ast, file ) { | |
const promises = []; // keep track of promises since visit isn't async | |
visit( ast, 'code', ( node, index, parent ) => { | |
// If this codeblock is not mermaid, bail. | |
if ( node.lang !== 'mermaid' ) { | |
return node; | |
} | |
promises.push( | |
transformMermaidNode( node, file, index, parent, options ) | |
); | |
} ); | |
await Promise.all( promises ); | |
}; | |
} | |
module.exports = mermaid; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Maybe turn into a package. Not a priority at this present time.