diff --git a/server/modules/rendering/markdown-wireviz/README.md b/server/modules/rendering/markdown-wireviz/README.md new file mode 100644 index 00000000..f09b81ed --- /dev/null +++ b/server/modules/rendering/markdown-wireviz/README.md @@ -0,0 +1,41 @@ +# WireViz Renderer + +This provides a WireViz Markdown renderer plugin for Wiki.js, allowing you to embed WireViz diagrams directly in Wiki.js pages. Diagrams are rendered via a WireViz-Web server, either locally or remotely. + + +## Install + +* Install https://github.com/wireviz/wireviz-web +* Start wireviz-web server +* Configure Wiki.js WireViz plugin + * Set wirevizWebUrl to point to wireviz-web server URL + * Enable WireViz plugin + +## Test + +Add this to your Markdown page + +````markdown +```wireviz +connectors: + X1: + type: Molex 39-29-9042 + pinlabels: [GND, +12V] + X2: + type: Molex 39-29-9042 + pinlabels: [GND, +12V] + +cables: + W1: + gauge: 18 AWG3 + length: 1.5 + color_code: DIN + wirecount: 2 + shield: true + +connections: + - + - X1: [1,2] + - W1: [1,2] + - X2: [1,2] +``` diff --git a/server/modules/rendering/markdown-wireviz/definition.yml b/server/modules/rendering/markdown-wireviz/definition.yml new file mode 100644 index 00000000..9a3c3175 --- /dev/null +++ b/server/modules/rendering/markdown-wireviz/definition.yml @@ -0,0 +1,14 @@ +key: wireviz +title: WireViz Diagrams +description: Render WireViz cable/wire diagrams from inline syntax +author: Custom +icon: mdi-format-superscript +enabledDefault: false +dependsOn: markdownCore +props: + wirevizWebUrl: + type: String + title: WireViz Web URL + hint: URL of the WireViz Web service + default: http://localhost:3005 + order: 1 diff --git a/server/modules/rendering/markdown-wireviz/renderer.js b/server/modules/rendering/markdown-wireviz/renderer.js new file mode 100644 index 00000000..be5e8393 --- /dev/null +++ b/server/modules/rendering/markdown-wireviz/renderer.js @@ -0,0 +1,68 @@ +const { spawnSync } = require('child_process') + +module.exports = { + init(mdinst, conf = {}) { + this.md = mdinst + this.conf = conf + this.logger = (typeof WIKI !== 'undefined' && WIKI.logger) ? WIKI.logger : console + this.wirevizWebUrl = + conf.wirevizWebUrl || + 'http://localhost:3005' + + const originalFence = mdinst.renderer.rules.fence || null + + mdinst.renderer.rules.fence = (tokens, idx, options, env, slf) => { + const token = tokens[idx] + const info = (token.info || '').trim() + + if (!info || !info.startsWith('wireviz')) { + return originalFence + ? originalFence(tokens, idx, options, env, slf) + : `
${mdinst.utils.escapeHtml(token.content)}
` + } + + const wirevizCode = token.content || '' + + try { + const html = this.renderViaWirevizWebSync(wirevizCode) + return `
${html}
` + } catch (err) { + this.logger.error?.(`WireViz rendering error: ${err.message}`) + return `
WireViz Error: ${mdinst.utils.escapeHtml(err.message)}
` + } + } + }, + + renderViaWirevizWebSync(wirevizCode) { + // Use spawnSync to call curl synchronously and not add a new wikijs dependency + const curlArgs = [ + '-s', // silent + '-X', 'POST', + '-F', `yml_file=@-`, // read from stdin + '-H', 'Accept: text/html', + this.wirevizWebUrl.replace(/\/$/, '') + '/render' + ] + + const res = spawnSync('curl', curlArgs, { + input: wirevizCode, + encoding: 'utf8' + }) + + if (res.error) { + throw new Error(`curl failed: ${res.error.message}`) + } + + const stdout = res.stdout + const stderr = res.stderr + + if (stderr) { + this.logger.warn?.('curl stderr: ' + stderr) + } + + if (!stdout || !stdout.includes('