Using pyrailroad as a library¶
Building a diagram¶
If you are familiar with tabatkins' railroad-diagrams, building a diagram should be a straightforward task, with a few differences for two elements (Optional and ZeroOrMore).
A really simple diagram would be:
To write it out as SVG, do:
or# Write an SVG file with a CSS styleshzeet included
with open('foo.svg', 'w') as f:
d.write_standalone(f.write)
To crate a text-format diagram instead, do:
Summary of elements used in a diagram¶
Base elements¶
Diagram¶
The constructor for Diagram
takes any element, a dictionary of parameters (to override the diagram class) and an optional type.
By default, a Diagram
will always include a Start and an End when printed even if they were omitted.
Examples
-
Text element
-
A Terminal again (explicitly called), with the sql type
-
Multiple diagram elements, with the complex type and a parameter override
Start¶
This is the element that starts a diagram at the top left, you'd usually only use one. The constructor for Start
takes a type (same as Diagram), an optional label and an optional dictionary of parameters to override char_width
.
Examples
-
Simple
-
Customized
End¶
This is the opposite end of the diagram. The constructor is similar to Start but doesn't have a label. You can pass a dictionary of parameters, but they have no effect on End (this is kept for practical coding reasons so that all elements can take the full parameters dictionary recursively and use only what they need).
Examples
-
Simple
-
Customized
Text elements¶
Terminal¶
In a grammar, a Terminal is a symbol that cannot be replaced by other symbols of the vocabulary. Typically, this will be keywords for your language/tool, or literals.
The constructor for Terminal
takes a text, an optional href that will be converted to a link in SVG only, an optional title, a optional class for SVG styling and an optional dictionary of parameters to override char_width
.
Examples
-
Simple
-
Customized
NonTerminal¶
By opposition, a NonTerminal is a symbol that is replaceable (and likely defined in another diagram).
The constructor for NonTerminal
takes a text, an optional href that will be converted to a link in SVG only, an optional title, a optional class for SVG styling and an optional dictionary of parameters to override char_width
.
-
Simple
-
Customized
Comment¶
A comment is a neutral element that is best used to label branches in some of the block elements (repeat lines for example).
The constructor for Comment
takes a text, an optional href that will be converted to a link in SVG only, an optional title, a optional class for SVG styling and an optional dictionary of parameters to override comment_char_width
.
-
Simple
-
Customized
Arrow¶
The arrow element is an addition in pyrailroad over railroad-diagram that lets you add an arrow to a line to help read a longer or more complex diagram.
The constructor for Arrow
takes an optional direction (and like End, a parameters dictionary that has no effect).
Examples
-
Arrow to the right
-
Arrow to the left
-
Undirected (similar to a Skip)
Skip¶
This element lets you add spacing in your diagram by adding an empty line (in aStack, typically).
The constructor only takes an optional parameters dictionary.
Example
-
One Skip
-
Three Skips
Expression¶
The expression element is an addition in pyrailroad over railroad-diagram. It was added to deal with EBNF grammars having ambiguities in their notations which means the parser has to guess for some elements and it can't decide how to represent it other than as an expression. The best example is when a grammar contains a regular expression.
The constructor for Expression
takes a text, an optional href that will be converted to a link in SVG only, an optional title, a optional class for SVG styling and an optional dictionary of parameters to override char_width
.
Examples
-
Simple
-
Customized
Block elements¶
Sequence¶
As the name says, this is a sequence of elements. This is a useful container when you build more complex diagrams that use the other block elements (like Stack, for example).
The constructor for Sequence
takes one or more elements and an optional parameter dictionary.
Example
Stack¶
This allows you to stack elements vertically.
The constructor for Stack
takes one or more elements and an optional parameter dictionary (to modify the arc radius of curves).
Examples
-
A simple stack
-
A customized stack with more elements
OptionalSequence¶
This block is a sequence of elements where you must choose at least one element among the elements passed to it. If only one element is provided, it is turned into a Sequence.
The constructor for OptionalSequence
takes one or more elements and an optional parameter dictionary (to modify the arc radius of curves).
Examples
-
A simple optional sequence
-
A customized optional sequence with more elements
AlternatingSequence¶
This block means that the two arguments may repeat any number of times, by alternating between the two. You have to take at least one of the two elements.
The constructor for AlternatingSequence
takes exactly two elements and an optional parameter dictionary (to modify the arc radius of curves).
Examples
-
A simple alternating sequence
-
A customized alternating sequence with more elements
Choice¶
This block lets you choose one element among multiple elements.
The constructor for Choice
takes one integer (index for the default element, starting at 0), one or more elements and an optional parameter dictionary (to modify the arc radius of curves or the vertical seperation between lines).
Examples
-
A simple choice
-
A customized choice with more elements
MultipleChoice¶
This block lets you choose one or more elements among multiple elements. Unlike Choice, more than one branch can be taken.
The constructor for MultipleChoice
takes one integer (index for the default element, starting at 0), one of "any" (at least one branch must be taken) or "all" (all branches must be taken), one or more elements and an optional parameter dictionary (to modify the arc radius of curves or the vertical seperation between lines).
Examples
-
A simple alternating sequence
-
A customized alternating sequence with more elements
HorizontalChoice¶
This block lets you choose one element among multiple elements. Unlike Choice, items are stacked horizontally, there is no default choice.
The constructor for HorizontalChoice
takes one or more elements and an optional parameter dictionary (to modify the arc radius of curves or the vertical seperation between lines).
Examples
-
A simple choice
-
A customized choice with more elements
optional¶
This pseudo-block is a shortcut for Choice(skip?, Skip(), element)
.
optional
takes one element, an optional boolean (default: False
) indicating if skipping is the default, and an optional parameter dictionary (to modify the arc radius of curves or the vertical seperation between lines).
Examples
-
optional with skip = False
-
optional with skip = True and customization
OneOrMore¶
This lets you repeat an element.
The contructor for OneOrMore
takes one item, an optional repeated item (for example a comment) and an optional parameter dictionary (to modify the arc radius of curves or the vertical seperation between lines).
Examples
-
OneOrMore with no repeat item
-
OneOrMore with a repeat item and customization
zero_or_more¶
This pseudo block is a shortcut for optional(OneOrMore(child, repeat), skip)
.
zero_or_more
takes one element, an optional repeated item, an optional boolean (default: False) indicating if skipping is the default, and an optional parameter dictionary (to modify the arc radius of curves or the vertical seperation between lines).
Examples
-
zero_or_more with no repeat item
-
zero_or_more with a repeat item and customization
Group¶
This lets you highlight an element with a dashed outline.
The constructor for Group
takes an element, an optioanl label and an optional parameter dictionary (to modify the arc radius of curves or the vertical seperation between lines).
Examples
-
A group with no label
-
A group with a label and customization