This is a small js library for generating railroad diagrams (like what JSON.org uses) using SVG.
Railroad diagrams are a way of visually representing a grammar in a form that is more readable than using regular expressions or BNF. I think (though I haven't given it a lot of thought yet) that if it's easy to write a context-free grammar for the language, the corresponding railroad diagram will be easy as well.
There are several railroad-diagram generators out there, but none of them had the visual appeal I wanted. Here's an example of how they look! And here's an online generator for you to play with and get SVG code from!
The library now exists in a Python port as well! See the information further down.
To use the library, just include the js and css files, and then call the Diagram() function. Its arguments are the components of the diagram (Diagram is a special form of Sequence). An alternative to Diagram() is ComplexDiagram() which is used to describe a complex type diagram. Components are either leaves or containers.
Choice(1, [Skip(), child]). If the optional
skipparameter has the value
"skip", it instead puts the Skip() in the straight-line path, for when the "normal" behavior is to omit the item.
Optional(OneOrMore(child, repeat)). The optional
skipparameter is identical to Optional().
For convenience, each component can be called with or without
If called without
the container components become n-ary;
that is, you can say either
new Sequence([A, B]) or just
After constructing a Diagram, call
.format(...padding) on it, specifying 0-4 padding values (just like CSS) for some additional "breathing space" around the diagram (the paddings default to 20px).
The result can either be
.toString()'d for the markup, or
.toSVG()'d for an
<svg> element, which can then be immediately inserted to the document. As a convenience, Diagram also has an
.addTo(element) method, which immediately converts it to SVG and appends it to the referenced element with default paddings.
element defaults to
There are a few options you can tweak, at the bottom of the file. Just tweak either until the diagram looks like what you want. You can also change the CSS file - feel free to tweak to your heart's content. Note, though, that if you change the text sizes in the CSS, you'll have to go adjust the metrics for the leaf nodes as well.
<svg>element of each diagram, for use in the CSS stylesheet.
At this early stage, the generator is feature-complete and works as intended, but still has several TODOs:
In addition to the canonical JS version, the library now exists as a Python library as well.
Using it is basically identical. The config variables are globals in the file, and so may be adjusted either manually or via tweaking from inside your program.
The main difference from the JS port is how you extract the string from the Diagram. You'll find a
writeSvg(writerFunc) method on
Diagram, which takes a callback of one argument and passes it the string form of the diagram. For example, it can be used like
Diagram(...).writeSvg(sys.stdout.write) to write to stdout. Note: the callback will be called multiple times as it builds up the string, not just once with the whole thing. If you need it all at once, consider something like a
StringIO as an easy way to collect it into a single string.
This document and all associated files in the github project are licensed under CC0 . This means you can reuse, remix, or otherwise appropriate this project for your own use without restriction. (The actual legal meaning can be found at the above link.) Don't ask me for permission to use any part of this project, just use it. I would appreciate attribution, but that is not required by the license.