Feat: add wireviz-web based wireviz syntax renderer

Add a renderer for wireviz syntax.

This renderer requires a wireviz-web server running / reachable via plugin definable url.

The renderer sends then the wireviz code to it and receives html which is inlined in the markdown code.

See README.md for more details.
pull/7811/head
petrosilius 2 months ago
parent b49c00226c
commit 57d80e25b7

@ -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]
```

@ -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

@ -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)
: `<pre><code>${mdinst.utils.escapeHtml(token.content)}</code></pre>`
}
const wirevizCode = token.content || ''
try {
const html = this.renderViaWirevizWebSync(wirevizCode)
return `<div class="wireviz-diagram">${html}</div>`
} catch (err) {
this.logger.error?.(`WireViz rendering error: ${err.message}`)
return `<pre>WireViz Error: ${mdinst.utils.escapeHtml(err.message)}</pre>`
}
}
},
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('<svg')) {
throw new Error(stdout)
}
return stdout
}
}
Loading…
Cancel
Save