WWW::MermaidInk Raku package
The function mermaid-ink
of the Raku package "WWW::MermaidInk"
gets images corresponding to Mermaid-js specifications via the web Mermaid-ink interface of Mermaid-js.
For a "full set" of examples see the file
MermaidInk_woven.html.
Usage
use WWW::MermaidInk
loads the package.
mermaid-ink($spec)
retrieves an image defined by the spec $spec
from Mermaid's Ink Web interface.
mermaid-ink($spec format => 'md-image')
returns a string that is a Markdown image specification in Base64 format.
mermaid-ink($spec format => 'md-url')
returns a string that is a Markdown image link specification.
mermaid-ink($spec format => 'svg')
returns a string that is a Scalable Vector Graphics (SVG) code.
mermaid-ink($spec format => 'hash')
returns a Hash object (the result of HTTP::Tiny.get
.)
mermaid-ink($spec file => fileName)
exports the retrieved image into a specified PNG file.
mermaid-ink($spec file => Whatever)
exports the retrieved image into the file $*CMD ~ /out.png
.
Details & Options
Mermaid lets you create diagrams and visualizations using text and code.
Mermaid has different types of diagrams: Flowchart, Sequence Diagram, Class Diagram, State Diagram, Entity Relationship Diagram, User Journey, Gantt, Pie Chart, Requirement Diagram, and others. It is a JavaScript based diagramming and charting tool that renders Markdown-inspired text definitions to create and modify diagrams dynamically.
mermaid-ink
uses the Mermaid's functionalities via the Web interface "https://mermaid.ink/img".
The first argument can be a string (that is, a mermaid-js specification) or a list of pairs.
The option "directive" can be used to control the layout of Mermaid diagrams if the first argument is a list of pairs.
mermaid-ink
produces images or Hash objects (the result of HTTP::Tiny.get
.)
Examples
Basic Examples
Generate a flowchart from a Mermaid specification:
use WWW::MermaidInk;
'graph TD
WL --> |ZMQ|Python --> |ZMQ|WL'
==> mermaid-ink(format=>'md-url')
Create a Markdown image expression from a class diagram:
my $spec = q:to/END/;
classDiagram
Animal <|-- Duck
Animal <|-- Fish
Animal <|-- Zebra
Animal : +int age
Animal : +String gender
Animal: +isMammal()
Animal: +mate()
class Duck{
+String beakColor
+swim()
+quack()
}
class Fish{
-int sizeInFeet
-canEat()
}
class Zebra{
+bool is_wild
+run()
}
END
mermaid-ink($spec, format=>'md-url')
Scope
The first argument can be a list of pairs -- the corresponding Mermaid-js graph is produced.
Here are the edges of directed graph:
my @edges = ['1' => '3', '3' => '1', '1' => '4', '2' => '3', '2' => '4', '3' => '4'];
[1 => 3 3 => 1 1 => 4 2 => 3 2 => 4 3 => 4]
Here is the corresponding mermaid-js image:
mermaid-ink(@edges, format=>'md-url')
Scalable Vector Graphics (SVG) code can be generated with format => 'svg'
:
mermaid-ink(@edges, format=>'svg')
# <svg id="mermaid-svg" width="100%" xmlns="http://www.w3.org/2000/svg" style="max-width: 124.205px; background-color: rgb(255, 255, 255);" viewBox="-9.423566102981567 -8 124.20481872558594 218" role="graphics-document document" aria-roledescription="flowchart-v2" xmlns:xlink="http://www.w3.org/1999/xlink"><style>#mermaid-svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg .error-icon{fill:#552222;}#mermaid-svg .error-text{fill:#552222;stroke:#552222;}#mermaid-svg .edge-thickness-normal{stroke-width:2px;}#mermaid-svg .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg .marker{fill:#333333;stroke:#333333;}#mermaid-svg .marker.cross{stroke:#333333;}#mermaid-svg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg .cluster-label text{fill:#333;}#mermaid-svg .cluster-label span,#mermaid-svg p{color:#333;}#mermaid-svg .label text,#mermaid-svg span,#mermaid-svg p{fill:#333;color:#333;}#mermaid-svg .node rect,#mermaid-svg .node circle,#mermaid-svg .node ellipse,#mermaid-svg .node polygon,#mermaid-svg .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg .flowchart-label text{text-anchor:middle;}#mermaid-svg .node .label{text-align:center;}#mermaid-svg .node.clickable{cursor:pointer;}#mermaid-svg .arrowheadPath{fill:#333333;}#mermaid-svg .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg .cluster text{fill:#333;}#mermaid-svg .cluster span,#mermaid-svg p{color:#333;}#mermaid-svg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style><g><marker id="mermaid-svg_flowchart-pointEnd" class="marker flowchart" viewBox="0 0 10 10" refX="6" refY="5" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker><marker id="mermaid-svg_flowchart-pointStart" class="marker flowchart" viewBox="0 0 10 10" refX="4.5" refY="5" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto"><path d="M 0 5 L 10 10 L 10 0 z" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker><marker id="mermaid-svg_flowchart-circleEnd" class="marker flowchart" viewBox="0 0 10 10" refX="11" refY="5" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></circle></marker><marker id="mermaid-svg_flowchart-circleStart" class="marker flowchart" viewBox="0 0 10 10" refX="-1" refY="5" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></circle></marker><marker id="mermaid-svg_flowchart-crossEnd" class="marker cross flowchart" viewBox="0 0 11 11" refX="12" refY="5.2" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><path d="M 1,1 l 9,9 M 10,1 l -9,9" class="arrowMarkerPath" style="stroke-width: 2; stroke-dasharray: 1, 0;"></path></marker><marker id="mermaid-svg_flowchart-crossStart" class="marker cross flowchart" viewBox="0 0 11 11" refX="-1" refY="5.2" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><path d="M 1,1 l 9,9 M 10,1 l -9,9" class="arrowMarkerPath" style="stroke-width: 2; stroke-dasharray: 1, 0;"></path></marker><g class="root"><g class="clusters"></g><g class="edgePaths"><path d="M3.6,34L1.616,38.167C-0.368,42.333,-4.336,50.667,2.099,60.135C8.534,69.604,25.372,80.207,33.791,85.509L42.21,90.811" id="L-1-3-0" class=" edge-thickness-normal edge-pattern-solid flowchart-link LS-1 LE-3" style="fill:none;" marker-end="url(#mermaid-svg_flowchart-pointEnd)"></path><path d="M52.988,84L51.664,79.833C50.34,75.667,47.691,67.333,43.308,59.313C38.924,51.294,32.805,43.587,29.746,39.734L26.686,35.881" id="L-3-1-0" class=" edge-thickness-normal edge-pattern-solid flowchart-link LS-3 LE-1" style="fill:none;" marker-end="url(#mermaid-svg_flowchart-pointEnd)"></path><path d="M11.695,34L11.695,38.167C11.695,42.333,11.695,50.667,11.695,61.833C11.695,73,11.695,87,11.695,101C11.695,115,11.695,129,14.755,139.853C17.814,150.706,23.933,158.413,26.993,162.266L30.052,166.119" id="L-1-4-0" class=" edge-thickness-normal edge-pattern-solid flowchart-link LS-1 LE-4" style="fill:none;" marker-end="url(#mermaid-svg_flowchart-pointEnd)"></path><path d="M85.636,34L83.319,38.167C81.003,42.333,76.371,50.667,72.998,58.158C69.625,65.65,67.512,72.299,66.455,75.624L65.398,78.949" id="L-2-3-0" class=" edge-thickness-normal edge-pattern-solid flowchart-link LS-2 LE-3" style="fill:none;" marker-end="url(#mermaid-svg_flowchart-pointEnd)"></path><path d="M99.134,34L100.126,38.167C101.118,42.333,103.102,50.667,104.094,61.833C105.086,73,105.086,87,105.086,101C105.086,115,105.086,129,97.752,141.13C90.418,153.26,75.749,163.521,68.415,168.651L61.081,173.781" id="L-2-4-0" class=" edge-thickness-normal edge-pattern-solid flowchart-link LS-2 LE-4" style="fill:none;" marker-end="url(#mermaid-svg_flowchart-pointEnd)"></path><path d="M58.391,118L58.391,122.167C58.391,126.333,58.391,134.667,57.334,142.158C56.277,149.65,54.164,156.299,53.107,159.624L52.051,162.949" id="L-3-4-0" class=" edge-thickness-normal edge-pattern-solid flowchart-link LS-3 LE-4" style="fill:none;" marker-end="url(#mermaid-svg_flowchart-pointEnd)"></path></g><g class="edgeLabels"><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node default default flowchart-label" id="flowchart-1-0" transform="translate(11.6953125, 17)"><rect class="basic label-container" style="" rx="0" ry="0" x="-11.6953125" y="-17" width="23.390625" height="34"></rect><g class="label" style="" transform="translate(-4.1953125, -9.5)"><rect></rect><foreignObject width="8.390625" height="19"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="nodeLabel">1</span></div></foreignObject></g></g><g class="node default default flowchart-label" id="flowchart-2-6" transform="translate(95.0859375, 17)"><rect class="basic label-container" style="" rx="0" ry="0" x="-11.6953125" y="-17" width="23.390625" height="34"></rect><g class="label" style="" transform="translate(-4.1953125, -9.5)"><rect></rect><foreignObject width="8.390625" height="19"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="nodeLabel">2</span></div></foreignObject></g></g><g class="node default default flowchart-label" id="flowchart-3-1" transform="translate(58.390625, 101)"><rect class="basic label-container" style="" rx="0" ry="0" x="-11.6953125" y="-17" width="23.390625" height="34"></rect><g class="label" style="" transform="translate(-4.1953125, -9.5)"><rect></rect><foreignObject width="8.390625" height="19"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="nodeLabel">3</span></div></foreignObject></g></g><g class="node default default flowchart-label" id="flowchart-4-5" transform="translate(45.04296875, 185)"><rect class="basic label-container" style="" rx="0" ry="0" x="-11.6953125" y="-17" width="23.390625" height="34"></rect><g class="label" style="" transform="translate(-4.1953125, -9.5)"><rect></rect><foreignObject width="8.390625" height="19"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="nodeLabel">4</span></div></foreignObject></g></g></g></g></g><style>@import url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css");</style></svg>
Options
When format => 'svg'
and subdomain => Whatever
, then subdomain
is automatically determined to be "svg".
The argument subdomain
can take the values "base64", "hash", "md-image", "md-url", "svg", Whatever
.
Background color can be specified with the optional argument background
.
Here is an example of using "md-url" as a format and background "Cornsilk":
'graph LR
CompSci[Computational Science] --> Physics
CompSci --> Math[Mathematics]
Physics --> Philosophy
Math --> Philosophy'
==> mermaid-ink(format=>'md-url', background=>'Cornsilk')
Command Line Interface (CLI)
The package provides the CLI script mermaid-ink
. Here is its help message:
mermaid-ink --help
# Usage:
# mermaid-ink <spec> [-o|--file=<Str>] [--format=<Str>] -- Diagram image for Mermaid-JS spec (via mermaid.ink).
# mermaid-ink [<words> ...] [-o|--file=<Str>] [--format=<Str>] -- Command given as a sequence of words.
#
# <spec> Mermaid-JS spec.
# -o|--file=<Str> File to export the image to. [default: '']
# --format=<Str> Format of the result; one of "asis", "base64", "md-image", or "none". [default: 'md-image']
Flowchart
This flowchart summarizes the execution path of obtaining Mermaid images in a Markdown document:
graph TD
UI[/User input/]
MS{{Mermaid-ink server}}
Raku{{Raku}}
MDnb>Markdown document]
MDIC[[Input cell]]
MDOC[[Output cell]]
MI[mermaid-ink]
TCP[[Text::CodeProcessing]]
UI --> MDIC -.- MDnb
MDIC --> MI -.- TCP
MI --> |spec|MS
MS --> |image|MI
MI --> MDOC -.- MDnb
MDnb -.- TCP -.- Raku
References
Articles
[AA1] Anton Antonov,
"Interactive Mermaid diagrams generation via Markdown evaluation",
(2022),
RakuForPrediction at WordPress.
Functions and packages
[AAf1] Anton Antonov,
MermaidInk Mathematica resource function,
(2022-2023),
Wolfram Function Repository.
Mermaid resources