Skip to content
Carsten Bormann edited this page Aug 26, 2023 · 16 revisions

Creating and Using SVG within kramdown-rfc

This wiki page collects some information on getting various additional tools to work that aid in creating and using SVG graphics with kramdown-rfc that are being generated from text-based specifications.

Please see below for how to include SVG graphics as is.

kramdown-rfc does not attempt to install any of the executables needed for this with its own installation. The below gives installation instructions. (These are heavily slanted to macOS, as that is what the author uses; additions for Debian, Ubuntu etc. welcome.)

For now, it is safe to assume that these additional tools are not available on the kramdown-rfc web service offered by the tools team. Most of them can be made to work with GitHub Actions, including via Martin Thomson's I-D-template distribution. When using this template on github, just add an m to:

uses: martinthomson/i-d-template@v1

yielding:

uses: martinthomson/i-d-template@v1m

in .github/workflows/ghpages.yml (v1m stands for Mega-image).

Overview

The basic idea is to mark an input code block with one of the labels discussed below (language types), yielding some plaintext form in the .TXT output and a graphical form in the .HTML output. In some cases, the .TXT plaintext is the input (e.g., ASCII art, mscgen), in other cases, the tool may be able to generate some plaintext rendition (e.g., plantuml-utxt).

As calling the external processes does take some time, kramdown-rfc caches the results (at the same place where references are cached, e.g., .refcache or, if configured so, ~/.caches/xml2rfc). The cached result is re-used until either the input (what is in the code block) changes or the version number of kramdown-rfc changes. After installing a new version of kramdown-rfc, a new invocation of kramdown-rfc will therefore run tools again, with messages that you haven't seen in a while; this alone is no cause for alarm.

Prerequisites

Most of the SVG tools are integrated via the svgcheck tool. Installation (depending on your environment, use pip if pip3 does not work:)

pip3 install svgcheck

This tool would do well with a bit of love, but is usable enough as is. Note that it usually spews a number of misleading error messages; these are relayed by kramdown-rfc in the event they can help with diagnosing an error, but usually can be ignored.

SVG creators supported by kramdown-rfc

The SVG tools support in kramdown-rfc is rapidly moving forward. In this evolution, we will attempt to not invalidate markdown source documents that already have worked. But there is less guarantee about this intention than in other parts of kramdown-rfc, and a bit more expectation of interaction between document and tool authors.

"ASCII art" to SVG

goataasvg, ditaa: ASCII (plaintext) art to SVG figure conversion

goat

A lean, golang-based "ASCII-art" to SVG converter.

Install via go get github.com/blampe/goat (you need an installation of the go language, e.g., via brew install go)

Set the executable lookup path in the environment ($PATH) to include the golang executable location, or simply:

ln -s $(brew --prefix)/.gocode/bin/goat $(brew --prefix)/bin/goat

aasvg

aasvg is a drop-in goat replacement that provides a more natural character spacing and may be easier to install that has been provided by Martin Thomson.

npm install -g aasvg

Two nice examples:

https://thomas-fossati.github.io/draft-psa-token/draft-tschofenig-rats-psa-token.html#figure-1 from https://github.com/thomas-fossati/draft-psa-token/blob/master/art/psa-attester.ascii-art

and

https://thomas-fossati.github.io/draft-psa-token/draft-tschofenig-rats-psa-token.html#figure-2 from https://github.com/thomas-fossati/draft-psa-token/blob/master/art/psa-lifecycle.ascii-art

generated from: https://raw.githubusercontent.com/thomas-fossati/draft-psa-token/master/draft-tschofenig-rats-psa-token.md (search for aasvg) in: https://github.com/thomas-fossati/draft-psa-token/

ditaa

Somewhat heavyweight, Java-based tool that used to be quite popular. Notable for its color support that unfortunately cannot be used in RFCXML.

Message Sequence Charts

mscgen

  • mscgen: Message Sequence Charts

brew install mscgen

UML-like diagrams

plantuml

  • plantuml: widely used multi-purpose diagram generator
  • plantuml-utxt: Like plantuml, except that a plantuml-generated plaintext form is used

plantuml can be set up to provide a UTF-8 based plaintext fallback; use plantuml-utxt to select that.

brew install plantuml

Syntax diagrams

kgt

kgt (Kate's Grammar Tool) is amazing, but unfortunately a bit hard to install. It requires a working pmake (or bmake).

Homebrew-style instructions that worked for me:

brew install bmake
git clone --recursive https://github.com/katef/kgt.git kgt-work
cd kgt-work
CC=clang PREFIX=$(brew --prefix) bmake -r install
## While you are at it, do this to get the amazing `re` tool:
cd ..
git clone --recursive https://github.com/katef/libfsm.git libfsm-work
cd libfsm-work
CC=clang PREFIX=$(brew --prefix) bmake -r install
...
$ re -l abnf "[A-Za-z]bc*"
➔ e = (%x41-5A / %x61-7A) %s"b" *%s"c"

kgt's railroad tool translates a single ABNF rule into a railroad (race-track) diagram, both in SVG and ASCII form. Use railroad to select this. This tool can also be set up to provide a slightly more polished looking UTF-8 based plaintext fallback; use railroad-utf8 to select that.

Other diagrams

mermaid

  • mermaid: Very experimental; the conversion to SVG is prone to generate black-on-black text in this version

Very useful for instance for Gantt charts. RFCXML integration via svgcheck does not work very well yet.

npm install -g mermaid.cli

math

  • math: display math using tex2svg for HTML/PDF and utftex for plaintext

npm install -g tex2svg

brew install utftex

Related tools

Besides the SVG-creating tools, there is a need to provide text/plain alternatives. In many cases, the SVG tool input is all we can get at the moment, in others the SVG tool has its own plaintext mode (e.g., plantuml). In some cases, additional tools need to be installed to get the text/plain output.

utftex (for math)

utftex (internally based on libtexprintf) can provide plain text (UTF-8) representations of many formulae.

Install via (in preparation, PR to be merged):

brew install utftex

Alternatively, installation instructions can be gleaned from https://github.com/martinthomson/i-d-template/blob/main/docker/math/Dockerfile

As a fallback if utftex is not available, kramdown-rfc can use asciitex (fork: asciiTeX), see below.

asciiTeX (for math)

Before 1.6.22, and still as a fallback when utftex is not available, kramdown-rfc can use asciiTeX for plaintext representation of formulae.

brew install asciitex

Lars Eggert has created an updated version of asciiTeX: https://github.com/larseggert/asciiTeX

Installation instructions can be gleaned from https://github.com/martinthomson/i-d-template/blob/main/docker/math/Dockerfile

protocol

protocol is a relatively obscure tool for creating ascii art box diagrams of protocol encodings, documented at http://www.luismg.com/protocol/ and installable from https://github.com/luismartingarcia/protocol.

This tool requires manual installation from its setup.py; note that this is different from what you get with pip3 install protocol.

It can be used standalone, e.g. in

~~~ protocol
Source:16
Reserved:40
TTL:8
~~~

to create the equivalent of

~~~~
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|             Source            |                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +-+-+-+-+-+-+-+-+
|                    Reserved                   |      TTL      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
~~~~

or in combination with goat or aasvg as in

~~~ protocol-aasvg
Source:16
Reserved:40
TTL:8
~~~
{: artwork-svg-options="--spaces=2"}

to create conventional ascii art box diagrams for text rendering in conjunction with SVG for the HTML rendering.

The previous example also shows how to provide command line options to the SVG-creating tool. An analogous example for providing command line options to the plaintext-creating tool (here: 16 bits per row, no bit numbers):

~~~ protocol-aasvg
Source:16
Reserved:40
TTL:8
~~~
{: artwork-txt-options="-b 16 -n"}

Pitfalls

SVG ID Collisions

Many of the tools that can be employed by kramdown-rfc will generate valid SVG output that can be included in an svg element in RFCXML. However, often a tool is employed for more than one figure. Unfortunately, some tools generate similar XML ID attribute values that then collide between the svg elements that have been generated by this tool.

If this is the case, when generating HTML or PDF xml2rfc then creates large numbers (often hundreds) of warnings that look like:

draft.xml(551): Warning: Duplicate attribute id="E1-STIXWEBNORMALI-1D45A" found after including svg from inline:b'<svg xmlns:xlink="http://www.w3' ....  This can cause problems with some browsers.

Since version 1.6.29, kramdown-rfc can modify the IDs used in RFCXML in such a way that the IDs no longer collide. However, this operation takes some CPU that appreciably adds to kramdown-rfc's processing time. The operation also is risky in that there may be cases where the result of the simple identifier replacement as implemented now is not fully correct.

Therefore, performing this operation has been made optional.

Enable with this line in the YAML header:

svg-id-cleanup: true

As an alternative, kramdown-rfc also includes a separate tool kramdown-rfc-clean-svg-ids that can be used to process an XML file already generated (possibly by some other tool than kramdown-rfc):

$ kramdown-rfc-clean-svg-ids draft-ietf-tcpm-rfc8312bis-15.xml >cleaned.xml

Note that the cleanup operation may report unused IDs emitted by some tools; these are indicative of some wastefulness in the generated SVG but do not by themselves cause a problem.

*** warning: unused ID: E1-STIXWEBMAIN-7B
*** warning: unused ID: E1-STIXWEBMAIN-7D
*** warning: unused ID: E1-STIXWEBMAIN-28, E1-STIXWEBMAIN-29

Including raw SVG

If you don't want to avail yourself of the support kramdown-rfc provides for generating dual-use text/graphics figures, you can simply use RFCXML to insert the SVG image and a placeholder for the plaintext version:

<figure>
<name>NMS View of Device State</name>
<artset>
<artwork type="svg" src="https://www.rfc-editor.org/materials/format/svg/stream.svg "/>
<artwork type="ascii-art">
Artwork only available as SVG (PDF and HTML)
</artwork>
</artset>
</figure>

Future versions of kramdown-rfc may support this more by running svgcheck on the included graphics and inserting this into the generated XML. Please open an issue on this github repo if you need such support.