././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 010212 x ustar 00 28 mtime=1676409805.3813572
railroad-diagrams-3.0.1/ 0000755 0321014 0257523 00000000000 00000000000 016411 5 ustar 00tabatkins primarygroup ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1642540072.0
railroad-diagrams-3.0.1/LICENSE 0000640 0321014 0257523 00000002057 00000000000 017416 0 ustar 00tabatkins primarygroup MIT License
Copyright (c) 2021 Tab Atkins Jr.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1636495991.0
railroad-diagrams-3.0.1/MANIFEST.in 0000644 0321014 0257523 00000000105 00000000000 020143 0 ustar 00tabatkins primarygroup railroad.py
test.py
railroad-diagrams.css
include *.md
include *.txt
././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 010212 x ustar 00 28 mtime=1676409805.3813572
railroad-diagrams-3.0.1/PKG-INFO 0000644 0321014 0257523 00000026264 00000000000 017520 0 ustar 00tabatkins primarygroup Metadata-Version: 2.1
Name: railroad-diagrams
Version: 3.0.1
Summary: Generate SVG railroad syntax diagrams, like on JSON.org.
Home-page: https://github.com/tabatkins/railroad-diagrams
Author: Tab Atkins
Author-email: jackalmage@gmail.com
License: UNKNOWN
Keywords: diagrams,syntax,grammar,railroad diagrams
Platform: UNKNOWN
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Railroad-Diagram Generator, Python Version
==========================================
This is a small library for generating railroad diagrams
(like what [JSON.org](http://json.org) uses)
using SVG, with both JS and Python ports.
[Here's an online dingus for you to play with and get SVG code from!](https://tabatkins.github.io/railroad-diagrams/generator.html)
(This is the README for the Python port;
see the [main README](https://github.com/tabatkins/railroad-diagrams) for other ports,
and for more non-Python-specific information.)
Diagrams
--------
Constructing a diagram is a set of nested calls:
```python
from railroad import Diagram, Choice
d = Diagram("foo", Choice(0, "bar", "baz"))
d.writeSvg(sys.stdout.write)
```
A railroad diagram must be started as a `Diagram` object,
which takes a list of diagram items,
defined below.
The `Diagram()` constructor also optionally takes some keyword arguments:
* `css`: If passed, is the CSS you would like the diagram to include.
If you don't pass anything, it defaults to including `railroad.DEFAULT_STYLE`.
If you don't want it to include any css at all in the diagram
(perhaps because you're including the `railroad.css` file manually in your page, and don't need each diagram to duplicate the CSS in itself),
pass `css=None`.
* `type`: JSON.org, the inspiration for these diagram's styling, technically has two varieties of Diagrams: a "simple" kind it uses for "leaf" types like numbers, and a "complex" kind which is used for container types like arrays. The only difference is the shape of the start/end indicators of the diagram.
Diagrams default to being "simple", but you can manually choose by passing `type="simple"` or `type="complex"`.
After constructing a Diagram, you can 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).
To output the diagram, call `.writeSvg(cb)` on it, passing a function that'll get called repeatedly to produce the SVG markup. `sys.stdout.write` (or the `.write` property of any file object) is a great value to pass if you're directly outputting it; if you need it as a plain string, a `StringIO` can be used.
This method produces an SVG fragment appropriate to include directly in HTML.
Alternately, you can call `.writeStandalone(cb, css?)`,
which'll format the SVG as a standalone document
rather than as an HTML fragment.
If you don't pass any `css`,
it'll automatically include the `DEFAULT_STYLE`;
you can include your own CSS instead by passing it as a string
(or an empty string to include no CSS at all).
If you need to walk the component tree of a diagram for some reason, `Diagram` has a `.walk(cb)` method as well, which will call your callback on every node in the diagram, in a "pre-order depth-first traversal" (the node first, then each child).
Components
----------
Components are either leaves (containing only text or similar)
or containers (containing other components).
The leaves:
* Terminal(text, href?, title?, cls?) or a bare string - represents literal text.
All arguments past the first are optional:
* 'href' makes the text a hyperlink with the given URL
* 'title' adds an SVG `
` element to the element,
giving it "hover text"
and a description for screen-readers and other assistive tech
* 'cls' is additional classes to apply to the element,
beyond the default `'terminal'`
* NonTerminal(text, href) - represents an instruction or another production.
The optional arguments have the same meaning as for Terminal,
except that the default class is `'non-terminal'`.
* Comment(text, href) - a comment.
The optional arguments have the same meaning as for Terminal,
except that the default class is `'non-terminal'`.
* Skip() - an empty line
* Start(type, label) and End(type) - the start/end shapes. These are supplied by default, but if you want to supply a label to the diagram, you can create a Start() explicitly (as the first child of the Diagram!). The "type" attribute takes either "simple" (the default) or "complex", a la Diagram() and ComplexDiagram(). All arguments are optional.
The containers:
* Sequence(...children) - like simple concatenation in a regex.
")
* Stack(...children) - identical to a Sequence, but the items are stacked vertically rather than horizontally. Best used when a simple Sequence would be too wide; instead, you can break the items up into a Stack of Sequences of an appropriate width.
")
* OptionalSequence(...children) - a Sequence where every item is *individually* optional, but at least one item must be chosen
")
* Choice(index, ...children) - like `|` in a regex. The index argument specifies which child is the "normal" choice and should go in the middle (starting from 0 for the first child).
")
* MultipleChoice(index, type, ...children) - like `||` or `&&` in a CSS grammar; it's similar to a Choice, but more than one branch can be taken. The index argument specifies which child is the "normal" choice and should go in the middle, while the type argument must be either "any" (1+ branches can be taken) or "all" (all branches must be taken).
")
* HorizontalChoice(...children) - Identical to Choice, but the items are stacked horizontally rather than vertically. There's no "straight-line" choice, so it just takes a list of children. Best used when a simple Choice would be too tall; instead, you can break up the items into a HorizontalChoice of Choices of an appropriate height.
, Choice(2, '5', '6', '7', '8', '9'))")
* Optional(child, skip?) - like `?` in a regex. A shorthand for `Choice(1, Skip(), child)`. If the optional `skip` parameter is `True`, it instead puts the Skip() in the straight-line path, for when the "normal" behavior is to omit the item.
, Optional('bar', 'skip')")
* OneOrMore(child, repeat?) - like `+` in a regex. The 'repeat' argument is optional, and specifies something that must go between the repetitions (usually a `Comment()`, but sometimes things like `","`, etc.)
)")
* AlternatingSequence(option1, option2) - similar to a OneOrMore, where you must alternate between the two choices, but allows you to start and end with either element. (OneOrMore requires you to start and end with the "child" node.)
")
* ZeroOrMore(child, repeat?, skip?) - like `*` in a regex. A shorthand for `Optional(OneOrMore(child, repeat), skip)`. Both `repeat` (same as in `OneOrMore()`) and `skip` (same as in `Optional()`) are optional.
), ZeroOrMore('foo', Comment('bar'), 'skip')")
* Group(child, label?) - highlights its child with a dashed outline, and optionally labels it. Passing a string as the label constructs a Comment, or you can build one yourself (to give an href or title).
, NonTerminal('or two')), 'label'), 'bar',)")
Options
-------
There are a few options you can tweak, living as UPPERCASE_CONSTANTS at the top of the module; these can be adjusted via `railroad.OPTION_NAME_HERE = "whatever"`.
Note that if you change the text sizes in the CSS,
you'll have to adjust the text metrics here as well.
* VS - sets the minimum amount of vertical separation between two items, in CSS px. Note that the stroke width isn't counted when computing the separation; this shouldn't be relevant unless you have a very small separation or very large stroke width. Defaults to `8`.
* AR - the radius of the arcs, in CSS px, used in the branching containers like Choice. This has a relatively large effect on the size of non-trivial diagrams. Both tight and loose values look good, depending on what you're going for. Defaults to `10`.
* DIAGRAM_CLASS - the class set on the root `