--- title: "Unified Modelling Language 🐬" date: 2021-10-30T15:42:47+02:00 draft: false toc: false images: tags: - svg - uml - code --- ## Mermaid CLI [Mermaid](https://mermaid-js.github.io/mermaid) is a JS based diagram and charting tool which aspires to generate diagrams in a markdown fashion. The main advantage here is that Mermaid is well integrated into quite a few editing and content management [packages](https://mermaid-js.github.io/mermaid/#/./integrations). There is command-line node-package that installs on both linux and WSL environments. You do need NPM version 10+ so installing in [Windows](https://docs.microsoft.com/en-us/windows/dev-environment/javascript/nodejs-on-wsl) takes a few extra steps in order to get the latest version. ```bash npm install @mermaid-js/mermaid-cli ``` Additionally this package will sandbox a instance of chromium which doesn't operate correctly with WLS version 1. Upgrading to WLS version 2 will allow you to run the following example using `mmdc -i input.mmd -o output.svg -c config.json`. ```text graph LR S[fa:fa-dot] --> A A{foo} A --> B(bar) A --> C(baz) style S fill:none, stroke:none ``` This example generates the diagram show below. {{< figure src="/images/posts/example_mermaid.svg" title="example_mermaid.svg" >}} There are four base themes: dark, default, forest, neutral. Additional [customization](https://mermaid-js.github.io/mermaid/#/theming) is possible. The `config.json` is shown below which sets similar styling as [before]({{< relref "building-svg.md" >}} "building svg") using the other command-line tools. ```json { "theme": "neutral", "themeVariables": { "fontFamily":"monospace", "fontSize":"14px", "classText" : "white", "nodeBorder" : "white", "nodeTextColor" : "white", "lineColor" : "white", "arrowheadColor" : "white", "mainBkg" : "none" } } ``` ## UML diagrams Mermaid is quite a bit more versatile and is geared towards making structured diagrams of classes and inter-related structures. For example the UML diagram below presents the overall composition of [pyviewer]({{< relref "pyside.md" >}} "pyside") which is image simple browsing utility for compressed archives. {{< figure src="/images/posts/example_pyviewer.svg" title="example_pyviewer.svg" >}} This does quite well at illustrating how classes are composed and which methods are available at various scopes. It also helps organizing and structuring a code-base when there means to reason in a visual way. The source code for this diagram is shown below for reference. ```text classDiagram class ApplicationWindow{ int[2] layout int max_count navigate(keyPress) update() } class PyViewer{ signal image_changed load_file_map(str path) load_archive(int index) set_max_count(int max_count) } class ArchiveLoader{ generate_map(str path) extract_current_index() check_media() } class ArchiveManager{ int max_count Qbyte[] images load_archive(str archive_path) } class TagManager{ int index dict media_map dict tag_filter list tag_history update_filter(str tag, bool state) undo_last_filter() adjust_index(int change) tag_at(int index) set_index(str tag_name) } ArchiveLoader <|-- TagManager ArchiveLoader <|-- ArchiveManager PyViewer <-- ArchiveLoader PyViewer <-- ApplicationWindow ``` ### Live viewer command line script The bash script below uses feh, an X11 image viewing utility, inotify-tools and ImageMagic from the command line to provide a live view of a mmd file that is built as changes are made to the file. ```bash #!/usr/bin/env bash function usage() { usage_str="$(basename "${BASH_SOURCE[0]}") IN_FILE OUT_FILE" usage_str+="[ --config= | -c ] " usage_str+="[ -h | --help ]" cat <<<" Usage: $usage_str Options: -c | --config: Specify CSS style for Mermaid diagram Default: None -h | --help: Displays this menu " exit 1 } function main() { local ARGS=("-i" "$1" "-o" "$2") case "$1" in -c) ARGS=("-i" "$3" "-o" "$4" "-c" "$2");; --config=*) ARGS=("-i" "$2" "-o" "$3" "-c" "${1#*=}");; -h|--help) usage;; -*) echo "Invalid Option: $1"; usage ;; esac # echo "IN:${ARGS[1]} OUT:${ARGS[3]}" mmdc ${ARGS[@]} &> /dev/null mogrify -trim "${ARGS[3]}" feh --reload 2 "${ARGS[3]}" & sleep 0.1 inotifywait -qm --event modify --format '%w' "${ARGS[1]}" | \ ( mmdc ${ARGS[@]} ; mogrify -trim "${ARGS[3]}" ) &> /dev/null } if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then if [ "$#" -lt 2 ] || [ "$#" -gt 4 ] ; then usage fi main "$@" fi ```