### ----------------------------------------------------
### -- WWW::MermaidInk
### -- Licenses: Artistic-2.0
### -- Authors: Anton Antonov
### -- File: README.md
### ----------------------------------------------------
# WWW::MermaidInk Raku package

The function `mermaid-ink` of the Raku package ["WWW::MermaidInk"](https://github.com/antononcube/Raku-WWW-MermaidInk)
gets images corresponding to Mermaid-js specifications via the web [Mermaid-ink](https://mermaid.ink) interface of [Mermaid-js](https://mermaid.js.org).

For a "full set" of examples see the file
[MermaidInk_woven.html](https://htmlpreview.github.io/?https://github.com/antononcube/Raku-WWW-MermaidInk/blob/main/docs/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:

```raku, results=asis
use WWW::MermaidInk;

'graph TD 
   WL --> |ZMQ|Python --> |ZMQ|WL' 
 ==> mermaid-ink(format=>'md-url')
```
![](https://mermaid.ink/img/Z3JhcGggVEQgCiAgIFdMIC0tPiB8Wk1RfFB5dGhvbiAtLT4gfFpNUXxXTA==?bgColor=FFFFFF)


Create a Markdown image expression from a class diagram:

```raku, results=asis
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')    
```
![](https://mermaid.ink/img/Y2xhc3NEaWFncmFtCiAgICBBbmltYWwgPHwtLSBEdWNrCiAgICBBbmltYWwgPHwtLSBGaXNoCiAgICBBbmltYWwgPHwtLSBaZWJyYQogICAgQW5pbWFsIDogK2ludCBhZ2UKICAgIEFuaW1hbCA6ICtTdHJpbmcgZ2VuZGVyCiAgICBBbmltYWw6ICtpc01hbW1hbCgpCiAgICBBbmltYWw6ICttYXRlKCkKICAgIGNsYXNzIER1Y2t7CiAgICAgICAgK1N0cmluZyBiZWFrQ29sb3IKICAgICAgICArc3dpbSgpCiAgICAgICAgK3F1YWNrKCkKICAgIH0KICAgIGNsYXNzIEZpc2h7CiAgICAgICAgLWludCBzaXplSW5GZWV0CiAgICAgICAgLWNhbkVhdCgpCiAgICB9CiAgICBjbGFzcyBaZWJyYXsKICAgICAgICArYm9vbCBpc193aWxkCiAgICAgICAgK3J1bigpCiAgICB9Cg==?bgColor=FFFFFF)


### Scope

The first argument can be a list of pairs -- the corresponding Mermaid-js graph is produced.
Here are the edges of directed graph:

```raku, results=asis
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:

```raku, results=asis
mermaid-ink(@edges, format=>'md-url')
```
![](https://mermaid.ink/img/Z3JhcGgKMSAtLT4gMwozIC0tPiAxCjEgLS0+IDQKMiAtLT4gMwoyIC0tPiA0CjMgLS0+IDQ=?bgColor=FFFFFF)


Scalable Vector Graphics (SVG) code can be generated with `format => 'svg'`:

```raku
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":

```raku, results=asis
'graph LR
   CompSci[Computational Science] --> Physics
   CompSci --> Math[Mathematics]
   Physics --> Philosophy 
   Math --> Philosophy'
 ==> mermaid-ink(format=>'md-url', background=>'Cornsilk') 
```
![](https://mermaid.ink/img/Z3JhcGggTFIKICAgQ29tcFNjaVtDb21wdXRhdGlvbmFsIFNjaWVuY2VdIC0tPiBQaHlzaWNzCiAgIENvbXBTY2kgLS0+IE1hdGhbTWF0aGVtYXRpY3NdCiAgIFBoeXNpY3MgLS0+IFBoaWxvc29waHkgCiAgIE1hdGggLS0+IFBoaWxvc29waHk=?bgColor=!Cornsilk)



------

## Command Line Interface (CLI)

The package provides the CLI script `mermaid-ink`. Here is its help message:

```shell
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:  

```mermaid
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"](https://rakuforprediction.wordpress.com/2022/11/22/interactive-mermaid-diagrams-generation-via-markdown-evaluation/),
(2022),
[RakuForPrediction at WordPress](https://rakuforprediction.wordpress.com).

### Functions and packages

[AAf1] Anton Antonov,
[MermaidInk Mathematica resource function](https://www.wolframcloud.com/obj/antononcube/DeployedResources/Function/MermaidInk/),
(2022-2023),
[Wolfram Function Repository](https://resources.wolframcloud.com/FunctionRepository/).

### Mermaid resources

- [GitHub - mermaid-js/mermaid: Generation of diagram and flowchart from text in a similar manner as markdown](https://github.com/mermaid-js/mermaid)

- [mermaid - Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.](https://mermaid-js.github.io/mermaid)

- [GitHub - mermaid-js/mermaid-cli: Command line tool for the Mermaid library](https://github.com/mermaid-js/mermaid-cli)

- [Online FlowChart & Diagrams Editor - Mermaid Live Editor](https://mermaid.live/)


