A CLI tool to embed interactive PUML diagrams to your github markdown files.

Overview

puml-for-markdown

Simple CLI Usage

Just run puml-for-markdown in any directory where you have markdown files and it will render links to PlantUML files in markdown comments. PlantUML files allow you to create diagrams that are defined using a simple and intuitive language. By default the entire directory is recursively searched, automatically ignoring anything in the gitignore file.

Examples

The following examples are of a project I worked on, yellow components will link you to another diagram. Obviously the diagram content has been obfuscated.

Embed a Diagram

You can easily add an embedded diagram to your markdown. Simply add a link to the puml file in a markdown comment like so:

<!--![Diagram Image Link](./puml/level_1_system_view.puml)-->

Here's the result. Try clicking on the yellow blocks.

Diagram Image Link

Link Only

To render a link to a puml diagram, do the same thing but exclude the !

<!--[Click to Open Interactive Diagram](./puml/level_1_system_view.puml)-->

which renders into

Click to Open Interactive Diagram

Goal

The goal is to make PlantUML diagrams easily accessible from markdown, specifically GitHub flavored.

  • Should work with both private and public repositories
  • Should not have to use tokens to get it to work with private repositories
  • Should support hyperlinking to other diagrams
  • Should support PlantUML !include
  • Should support PlantUML sprites (small graphic images)
  • Any time you make changes to diagrams you should be able to run the CLI tool to update the markdown links

Background

PlantUML allows you to create diagrams that are defined using a simple and intuitive language. PlantUML diagrams are great for designing new projects but they don't work very well in Github markdown preview. There are some workarounds, but I found these to be unstable and they have a lot of caveats.

Update: Github released support for embeddable Mermaid diagrams, but PlantUML is still unsupported, see here for more info.

Basic Usage

Whenever you run the CLI it will add a tinyurl link to the rendered SVG next to the markdown comments referencing a puml diagram. E.g.

<!--[Example With Only Link](./puml/level_1_system_view.puml)-->

will be replaced with

[Example With Only Link](https://tinyurl.com/yfpclfpp)<!--[Example With Only Link](./puml/level_1_system_view.puml)-->

When ! is included in front of the markdown link, it will render the diagram image in the markdown. If the image is clicked it will open up the diagram. E.g.

<!--![Example With Graph Image](./puml/level_1_system_view.puml)-->

will be replaced with

[![Example With Graph Image](https://tinyurl.com/yfpclfpp)](https://tinyurl.com/yfpclfpp)<!--![Example With Graph Image](./puml/level_1_system_view.puml)-->

If you want to update the link text or switch it between image and link, just update the comment and rerun the CLI. You don't need to delete the rendered image or link.

Installation

npm i -g puml-for-markdown

Advanced Usage

Here are some other features supported

  • You can specify the CLI to output the diagram images as png and/or svg see --output-images and --image-formats. For an example of outputted images, checkout dist_puml/puml. These images were created by the pre-commit hook.
  • You can specify the PUML server used to render the diagrams see --puml-server-url

All CLI Options

Usage: puml-for-markdown [options]

An application to add interactive PUML diagrams to your github markdown files. If running with default arguments, run in project root directory.

Options:
  -s, --puml-server-url <url>      This is the base URL used to render diagrams. Defaults to the public plantuml server. (default: "https://www.plantuml.com/plantuml")
  -x, --root-directory <path>      The path to your project (default: CWD)
  -r, --hot-reload                 Rerun markdown generator every `interval` seconds, determined by interval option
  -v, --interval-seconds <number>  If --hot-reload is set, how often should it reload (default: 2)
  -p, --puml-directory <path>      Path to directory containing puml files which are referenced in markdown files (default: rootDirectory)
  -m, --markdown-directory <path>  Path to directory containing markdown files referencing puml files (default: rootDirectory)
  -g, --ignore-gitignore           Don't use .gitignore to skip PUML and MD
  -i, --gitignore-path <path>      Use this as path to .gitignore file. (default: rootDirectory/.gitignore)
  -d, --output-images              If set, will output images of diagrams to the dist directory
  -b, --dist-directory <path>      If --output-images is set, path to output diagram images (default: rootDirectory/dist_puml)
  -f, --image-formats <format>     If --output-images is set, sets the output image format (choices: "png", "svg", "both", default: "png")
  -t, --turn-off-link-shortening   Use the full puml server link instead of the tiny url, if your diagrams are too big this won't work
  -h, --help                       display help for command

Notes

  • Comments within inline or multiline code styling will be ignored
  • Currently doesn't support cyclic graph references, i.e. a diagram can't reference any diagrams which reference back to it
  • See the pre-commit hook to see how to add a git hook
  • If you are saving diagram images and have puml files which only define constants or settings (i.e. example) you'll see a warning in the console saying it failed to save the image to file because these aren't renderable on their own (since there is nothing to render)
  • Anything inside inline code or code blocks will be excluded from rendering

How It Works

Using PlantUML Web Service to Render PUML Diagrams

You can use PlantUML using the online web service to generate images on-the-fly. A online demonstration is available at http://www.plantuml.com/plantuml. You can pass the encoded text of your diagrams to the web service in the url path and it will generate an SVG or PNG for you. Here's a simple HelloWorld example http://www.plantuml.com/plantuml/uml/Aov9B2hXil98pSd9LoZFByf9iUOgBial0000. Large diagrams will have very long encoding strings, they can exceed maximum url length. They also don't look very good in markdown files. By default the CLI will use the tinyurl.com service to shorten the link to the diagram.

Encoding PUML Diagrams for the Web Service

The CLI will use the plantuml-encoder package to encode puml files. To support hyperlinking diagrams we need to parse all hyperlinks in the puml files. A dependency graph is created for the files and a DFS is performed where we create links for the leaf nodes first, then replace the links in the parent nodes with the links to the leaf nodes. The puml files are not actually modified, only the puml files content in memory is modified. By default the tinyurl free service is used to shorten the links.

In order to support !include we parse puml files and replace any !include with the contents of the file referenced.

Parsing Markdown

The markdown files are then parsed for markdown comments. If the comments reference a PlantUML file, a link to the web service url will be added next to the comment. Because these links contain the full PlantUML diagram encoding in it, there are no issues using them in private repositories.

Testing

Currently there is no TDD, for now I've just been using the example diagrams to test. The examples are pretty extensive though.

Other Helpful Links

  • C4-Puml: A collection of PlantUML diagrams for use in C4, you'll see me using this in my examples

More Examples

ERD

Container View

Component View - Label Retrieval Job

Component View - Pipeline Component

Activity Diagram - Sampler A

Activity Diagram - Sampler B

Comments
  • .gitignore is required

    .gitignore is required

    It seems the software currently requires the existence of a .gitignore file:

    Running puml-for-markdown yields:

    FATAL EXCEPTION
    Error: ENOENT: no such file or directory, open '/Users/dsk/FT/test/.gitignore'
        at Object.openSync (node:fs:599:3)
        at Object.readFileSync (node:fs:467:35)
        at parse (/usr/local/lib/node_modules/puml-for-markdown/node_modules/gitignore-globs/index.js:65:22)
        at runOnce (/usr/local/lib/node_modules/puml-for-markdown/index.js:208:39)
        at run (/usr/local/lib/node_modules/puml-for-markdown/index.js:230:69)
        at Command.<anonymous> (/usr/local/lib/node_modules/puml-for-markdown/bin/index.js:81:16)
        at Command.listener [as _actionHandler] (/usr/local/lib/node_modules/puml-for-markdown/node_modules/commander/lib/command.js:488:17)
        at /usr/local/lib/node_modules/puml-for-markdown/node_modules/commander/lib/command.js:1207:65
        at Command._chainOrCall (/usr/local/lib/node_modules/puml-for-markdown/node_modules/commander/lib/command.js:1124:12)
        at Command._parseCommand (/usr/local/lib/node_modules/puml-for-markdown/node_modules/commander/lib/command.js:1207:27)
        at Command.parse (/usr/local/lib/node_modules/puml-for-markdown/node_modules/commander/lib/command.js:878:10)
        at Object.<anonymous> (/usr/local/lib/node_modules/puml-for-markdown/bin/index.js:86:6)
        at Module._compile (node:internal/modules/cjs/loader:1112:14)
        at Module._extensions..js (node:internal/modules/cjs/loader:1166:10)
        at Module.load (node:internal/modules/cjs/loader:988:32)
        at Module._load (node:internal/modules/cjs/loader:834:12) {
      errno: -2,
      syscall: 'open',
      code: 'ENOENT',
      path: '/Users/dsk/FT/test/.gitignore'
    }
    

    Since a repository doesn't need a .gitignore to function properly, i think this software should cope with that.

    opened by skrach 3
  • Error: getaddrinfo ENOTFOUND tinyurl.com

    Error: getaddrinfo ENOTFOUND tinyurl.com

    After generating an empty .gitignore file in order to skip the first issue already under investigation, I got this FATAL EXCEPTION Error: getaddrinfo ENOTFOUND tinyurl.com at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:111:26) { errno: -3008, code: 'ENOTFOUND', syscall: 'getaddrinfo', hostname: 'tinyurl.com' }

    for puml-for-markdown -t in the puml-for-markdown folder: Processing md file at C:/Users/xxxxx/AppData/Roaming/npm/node_modules/puml-for-markdown/CONTRIBUTING.md Processing md file at C:/Users/xxxxx/AppData/Roaming/npm/node_modules/puml-for-markdown/LICENSE.md ... FATAL EXCEPTION Error: Could not find puml for md link path = ./puml/level_1_system_view.puml, absolute path = C:\Users\xxxxx\AppData\Roaming\npm\node_modules\puml-for-markdown\puml\level_1_system_view.puml at C:\Users\xxxxx\AppData\Roaming\npm\node_modules\puml-for-markdown\index.js:171:23 at String.replace () at C:\Users\xxxxx\AppData\Roaming\npm\node_modules\puml-for-markdown\index.js:167:20 at C:\Users\xxxxx\AppData\Roaming\npm\node_modules\puml-for-markdown\index.js:38:16 at Array.map () at replaceIgnore (C:\Users\xxxxx\AppData\Roaming\npm\node_modules\puml-for-markdown\index.js:36:45) at replaceMdIgnoringInlineCode (C:\Users\xxxxx\AppData\Roaming\npm\node_modules\puml-for-markdown\index.js:44:12) at C:\Users\xxxxx\AppData\Roaming\npm\node_modules\puml-for-markdown\index.js:52:57 at C:\Users\xxxxx\AppData\Roaming\npm\node_modules\puml-for-markdown\index.js:38:16 at Array.map () at replaceIgnore (C:\Users\xxxxx\AppData\Roaming\npm\node_modules\puml-for-markdown\index.js:36:45) at replaceMdIgnoringCodeBlocks (C:\Users\xxxxx\AppData\Roaming\npm\node_modules\puml-for-markdown\index.js:48:12) at replaceMdIgnoringCode (C:\Users\xxxxx\AppData\Roaming\npm\node_modules\puml-for-markdown\index.js:52:12) at processMdFile (C:\Users\xxxxx\AppData\Roaming\npm\node_modules\puml-for-markdown\index.js:166:36) at runOnce (C:\Users\xxxxx\AppData\Roaming\npm\node_modules\puml-for-markdown\index.js:216:34)

    opened by balladav 1
  • Add configurable plantuml server

    Add configurable plantuml server

    See: https://github.com/danielyaa5/puml-for-markdown/issues/2 I was able to test this with a docker instance https://github.com/plantuml/plantuml-server.

    Here's what I ran

    docker run -d -p 8080:8080 plantuml/plantuml-server:jetty
    node bin/index.js --puml-server-url http://localhost:8080
    

    Just note this server url would need to be public not localhost for rendering the inline images in markdown but if you just want to use links should still work fine with localhost

    opened by danielyaa5 0
  • Enable using polr shortener instead tinyurl

    Enable using polr shortener instead tinyurl

    Added an option to specify polr shortner url in which case polr shortener API will be called to shorten url instead using tinyurl.

    I'd like to use polr since it's open source and am able to run it locally which allows me, together with running plantuml server locally, not to send diagrams to 3rd party services but keep everything in-house.

    Quick test: ./index.js --polr-url https://demo.polr.me/

    opened by mzagar 4
  • Broken on windows

    Broken on windows

    I get this error:

    C:\..\..\..\..\src\main\java\be\..\ce\..\docs   structurizr +3 | ?33 ~5  puml-for-markdown
    Processing md file at C:/javadev/workspace/ce-calendar-timespend-backend/structurizr/src/main/java/be/acerta/ce/calendar/docs/01-context.md
    FATAL EXCEPTION
    Error: Could not find puml for md link path = ./puml/a.puml, absolute path = C:\javadev\workspace\ce-calendar-timespend-backend\structurizr\src\main\java\be\acerta\ce\calendar\docs\puml\a.puml
        at C:\Users\cbonami\scoop\persist\nodejs\bin\node_modules\puml-for-markdown\index.js:171:23
        at String.replace (<anonymous>)
        at C:\Users\cbonami\scoop\persist\nodejs\bin\node_modules\puml-for-markdown\index.js:167:20
        at C:\Users\cbonami\scoop\persist\nodejs\bin\node_modules\puml-for-markdown\index.js:38:16
        at Array.map (<anonymous>)
        at replaceIgnore (C:\Users\cbonami\scoop\persist\nodejs\bin\node_modules\puml-for-markdown\index.js:36:45)
        at replaceMdIgnoringInlineCode (C:\Users\cbonami\scoop\persist\nodejs\bin\node_modules\puml-for-markdown\index.js:44:12)
        at C:\Users\cbonami\scoop\persist\nodejs\bin\node_modules\puml-for-markdown\index.js:52:57
        at C:\Users\cbonami\scoop\persist\nodejs\bin\node_modules\puml-for-markdown\index.js:38:16
        at Array.map (<anonymous>)
        at replaceIgnore (C:\Users\cbonami\scoop\persist\nodejs\bin\node_modules\puml-for-markdown\index.js:36:45)
        at replaceMdIgnoringCodeBlocks (C:\Users\cbonami\scoop\persist\nodejs\bin\node_modules\puml-for-markdown\index.js:48:12)
        at replaceMdIgnoringCode (C:\Users\cbonami\scoop\persist\nodejs\bin\node_modules\puml-for-markdown\index.js:52:12)
        at processMdFile (C:\Users\cbonami\scoop\persist\nodejs\bin\node_modules\puml-for-markdown\index.js:166:36)
        at runOnce (C:\Users\cbonami\scoop\persist\nodejs\bin\node_modules\puml-for-markdown\index.js:216:34)
    

    But the puml file is there, it's in the path C:\javadev\workspace\ce-calendar-timespend-backend\structurizr\src\main\java\be\acerta\ce\calendar\docs\puml\a.puml.

    The .../docs folder contains the file 01-context.md:

    <!--![TimespendLapse](./puml/a.puml) -->
    

    The .../docs/puml folder contains the file a.puml:

    @startuml
    class User {
      -String id
      -String name
      +String name()
    }
    User <|-- SpecificUser
    @enduml
    

    Plz note that I am on Windows. Placing the file in the same folder than the md file doesn't help. It doesn't find the puml-file while it is right there where it expects it !

    I think it is the same issue than https://github.com/danielyaa5/puml-for-markdown/issues/5 but the error msg is a bit different.

    opened by cbonami 6
Owner
Daniel
Daniel
Plugin that lets you create diagrams from textual representation (aka 'Diagrams as Code') within Logseq

Logseq - Diagrams as Code Plugin that lets you create diagrams (and other visualizations) from textual representation (aka 'Diagrams as Code') within

Nicolai P. Großer 80 Dec 21, 2022
A lightweight SolidJS component for building interactive node-based diagrams and graphs.

Convert Your Ideas To Graphs With Solid Graph! Solid Graph A lightweight and minimal Solid component for building interactive graphs and node-based ed

Ali Sal 26 Dec 8, 2022
A lightweight SolidJS component for building interactive node-based diagrams and graphs.

Convert Your Ideas To A Simple And Excitig Journay With Odysea! Odysea A lightweight and minimal Solid component for building interactive graphs and n

Ali Sal 21 Aug 15, 2022
Markdown Transformer. Transform markdown files to different formats

Mdtx Inspired by generative programming and weed :). So I was learning Elm language at home usually in the evening and now I am missing all this gener

Aexol 13 Jan 2, 2023
A CLI tool to create a NodeJS project with TypeScript CTSP is a CLI tool to make easier to start a new NodeJS project and configure Typescript on it.

CTSP- Create TS Project A CLI tool to create a NodeJS project with TypeScript CTSP is a CLI tool to make easier to start a new NodeJS project and conf

Jean Rodríguez 7 Sep 13, 2022
🌸 A cli can automatically generate files from Excel files.

unxlsx A cli can automatically generate files from Excel files. Why We often need to export some information from XLSX to generate our files, such as

Frozen FIsh 24 Aug 22, 2022
JavaScript library for parsing Dirtywave M8 files, complete with a CLI for interacting with M8 files.

m8-js This repository contains a JavaScript library for parsing Dirtywave M8 files, as well as a CLI for interacting with M8 files. The hopes are not

Jeremy Whitlock 20 Dec 17, 2022
Pintora is an extensible javascript text-to-diagrams library that works in both browser and Node.js.

Pintora Documentation | Live Editor Pintora is an extensible javascript text-to-diagrams library that works in both browser and Node.js. Expressing yo

hikerpig 652 Dec 30, 2022
A JavaScript library for visualizing Sankey diagrams.

SanKEY.js v1.0.0 last updated: 20.07.2022 Getting started SanKEY.js is a JavaScript data visualization library that provides a simple object-oriented

Krzysztof Zdąbłasz 12 Nov 8, 2022
Render (GitHub Flavoured with syntax highlighting) Markdown, and generate CSS for each of GitHub’s themes.

render-gfm Render (GitHub Flavoured with syntax highlighting) Markdown, and generate CSS for each of GitHub’s themes. GitHub Repository npm Package Do

Shaun Bharat 12 Oct 10, 2022
A refined tool for exploring open-source projects on GitHub with a file tree, rich Markdown and image previews, multi-pane multi-tab layouts and first-class support for Ink syntax highlighting.

Ink codebase browser, "Kin" ?? The Ink codebase browser is a tool to explore open-source code on GitHub, especially my side projects written in the In

Linus Lee 20 Oct 30, 2022
CLI tool that converts rgb(), rgba(), hex, hsl() and hsla() colors to oklch() in specified CSS files.

convert-to-oklch CLI tool that converts rgb(), rgba(), hex, hsl() and hsla() colors to oklch() in specified CSS files. npx convert-to-oklch ./src/**/*

Fedya Petrakov 43 Dec 20, 2022
A plugin for the Obsidian markdown note application, adding functionality to render markdown documents with multiple columns of text.

Multi-Column Markdown Take your boring markdown document and add some columns to it! With Multi Column Markdown rather than limiting your document lay

Cameron Robinson 91 Jan 2, 2023
A markdown-it plugin that process images through the eleventy-img plugin. Can be used in any projects that uses markdown-it.

markdown-it-eleventy-img A markdown-it plugin that process images through the eleventy-img plugin. Can be used in any projects that use markdown-it. F

null 25 Dec 20, 2022
An obsidian plugin for uploading local images embedded in markdown to remote store and export markdown for publishing to static site.

Obsidian Publish This plugin cloud upload all local images embedded in markdown to specified remote image store (support imgur only, currently) and ex

Addo.Zhang 7 Dec 13, 2022
Chat View let's you quickly and easily create elegant Chat UIs in your Markdown Files.

Obsidian Chat View Plugin Chat View let's you quickly and easily create elegant Chat UIs in your Markdown Files. Usage Every chat message must be pref

Adifyr 96 Dec 27, 2022
This extension allows you to create Markdown files which are automatically transformed to in-game documentation for your Add-On.

Markdown Doc Generator An extension for bridge editor which makes creating docs in minecraft easier, by generating json-ui from markdown View extensio

Freddie 7 Dec 31, 2022
Embed panorama photos on your website with Panorama Viewer

#Panorama Viewer by Pete R. Embed interactive Panorama Pictures on your site with this simple plugin. Created by Pete R., Founder of Travelistly and B

Pete R. 474 Oct 8, 2022