Describing diagrams¶
Using YAML or Python literals¶
Diagram elements are described as simple types suitable for encoding in JSON-like formats. The specific representation was chosen to be ergonomic when writing diagrams in YAML syntax.
- type syntax_diagrams.Element[T]¶
Describes an element of a syntax diagram.
If element is
None
, it’s rendered as a simple line with no additional content. This can be used to create optional elements usingChoice
.If element is a list, it’s rendered as a
Sequence
.If element is a string, it’s rendered as a
Terminal
.Otherwise, an element should be a dict containing one of the following keys:
terminal
,non_terminal
,comment
,sequence
,stack
,no_break
,choice
,optional
,one_or_more
,zero_or_more
,barrier
,group
.
Example:
- choice: - "lexer" - - "parser" default: 1 - grammar - non_terminal: "identifier" - ";"
diagram = sequence( choice( terminal("lexer"), skip(), terminal("parser"), ), terminal("grammar"), non_terminal("identifier"), terminal(";"), )
lexer parser grammar identifier ;
- type syntax_diagrams.Terminal[T]¶
Describes a terminal node with optional additional settings.
Dict keys:
terminal: str
, requiredText of the terminal, required.
href: str
Makes text node into a hyperlink.
title: str
Title for hyperlink.
css_class: str
Adds CSS class to node’s
<g>
element.resolve: bool
If set to
False
, this node will not be passed toHrefResolver
before rendering.resolver_data: T
Additional data for
HrefResolver
.
Example:
terminal: "INT" href: "#syntax_diagrams.Terminal"
diagram = terminal("INT", href="#syntax_diagrams.Terminal")
Terminal nodes without settings can be encoded as simple strings:
"INT"
INT
- type syntax_diagrams.NonTerminal[T]¶
Describes a non-terminal node with optional additional settings.
Dict keys:
non_terminal: str
, requiredText of the non-terminal, required.
href: str
Makes text node into a hyperlink.
title: str
Title for hyperlink.
css_class: str
Adds CSS class to node’s
<g>
element.resolve: bool
If set to
False
, this node will not be passed toHrefResolver
before rendering.resolver_data: T
Additional data for
HrefResolver
.
Example:
non_terminal: "expr" href: "#syntax_diagrams.NonTerminal"
diagram = non_terminal("expr", href="#syntax_diagrams.NonTerminal")
- type syntax_diagrams.Comment[T]¶
Describes a comment node with optional additional settings.
Dict keys:
comment: str
, requiredText of the terminal, required.
href: str
Makes text node into a hyperlink.
title: str
Title for hyperlink.
css_class: str
Adds CSS class to node’s
<g>
element.resolve: bool
If set to
False
, this node will not be passed toHrefResolver
before rendering.resolver_data: T
Additional data for
HrefResolver
.
Example:
comment: "escaped literal" href: "#syntax_diagrams.Comment"
diagram = comment("escaped literal", href="#syntax_diagrams.Comment")
- type syntax_diagrams.Sequence[T]¶
Describes an automatically wrapped sequence of elements.
Dict keys:
sequence: list[Element[T]]
, requiredElements in the sequence.
linebreaks: _t.Literal["HARD", "SOFT", "DEFAULT"] | list[_t.Literal["HARD", "SOFT", "DEFAULT"]]
Specifies line breaks after each element of the sequence.
If given as a string or a
LineBreak
, this line break will be used after each of the sequence’s elements.If given as a list of line breaks, each of list’s element determines line break after each of the sequence’s elements. This list must be one item shorter than number of elements in the sequence.
Example:
sequence: - comment: "escaped literal" - "ESC" - "CHAR" linebreaks: - "NO_BREAK" - "DEFAULT"
diagram = sequence( comment("escaped literal"), terminal("ESC"), terminal("CHAR"), linebreaks=[ LineBreak.NO_BREAK, LineBreak.DEFAULT, ], )
escaped literal ESC CHAR Sequences without settings can also be encoded as simple lists:
- comment: "escaped literal" - "ESC" - "CHAR"
escaped literal ESC CHAR
- type syntax_diagrams.Stack[T]¶
Describes a sequence of elements that wraps after each element.
This is a shortcut for creating a
Sequence
withlinebreaks
set toHARD
.Dict keys:
stack: list[Element[T]]
, requiredElements in the stack.
Example:
stack: - comment: "escaped literal" - "ESC" - "CHAR"
diagram = stack( comment("escaped literal"), terminal("ESC"), terminal("CHAR"), )
escaped literal ESC CHAR
- type syntax_diagrams.NoBreak[T]¶
Describes a sequence of elements that doesn’t wrap.
This is a shortcut for creating a
Sequence
withlinebreaks
set toNO_BREAK
.Dict keys:
no_break: list[Element[T]]
, requiredElements in the no-break sequence.
Example:
no_break: - comment: "escaped literal" - "ESC" - "CHAR"
diagram = no_break( comment("escaped literal"), terminal("ESC"), terminal("CHAR"), )
escaped literal ESC CHAR
- type syntax_diagrams.Choice[T]¶
Describes a choice between several elements.
Dict keys:
choice: list[Element[T]]
, requiredElements to choose from.
default: int
Index of item that will be placed on the main line.
Should be less then number of choice elements.
Example:
choice: - "INT" - "STR" - sequence: - "(" - non_terminal: "expr" - ")" default: 1
diagram = choice( terminal("INT"), terminal("STR"), sequence( terminal("("), non_terminal("expr"), terminal(")"), ), default=1, )
INT STR ( expr )
- type syntax_diagrams.Optional[T]¶
Describes an optional element.
This is a shortcut for creating a
Choice
with askip()
and a single element.Dict keys:
optional: Element[T]
, requiredElement that will be made optional.
skip: bool
If set to
True
, the optional element will be rendered off the main line.skip_bottom: bool
If set to
True
, the skip line will be rendered below the skipped element.
Example:
optional: - non_terminal: "annotation" skip: true
diagram = optional( non_terminal("annotation"), skip=True, )
annotation
- type syntax_diagrams.OneOrMore[T]¶
Describes a repeated element.
Dict keys:
one_or_more: Element[T]
, requiredElement that will be repeated.
repeat: Element[T]
An element that will be placed on the backwards path.
Example:
one_or_more: non_terminal: "expr" repeat: "COMMA"
diagram = one_or_more( non_terminal("expr"), repeat=terminal("COMMA"), )
expr COMMA
- type syntax_diagrams.ZeroOrMore[T]¶
Describes an optional repeated element.
This is a shortcut for creating an
Optional
with anOneOrMore
element inside.Dict keys:
zero_or_more: Element[T]
, requiredElement that will be repeated.
repeat: Element[T]
An element that will be placed on the backwards path.
skip: bool
If set to
True
, the optional repeated element will be rendered off the main line.skip_bottom: bool
If set to
True
, the skip line will be rendered below the skipped element.
Example:
zero_or_more: non_terminal: "expr" repeat: "COMMA"
diagram = zero_or_more( non_terminal("expr"), repeat=terminal("COMMA"), )
expr COMMA
- type syntax_diagrams.Barrier[T]¶
Isolates an element and disables optimizations that merge lines between this element and the rest of the diagram.
Dict keys:
barrier: Element[T]
, requiredElement that will be isolated.
Example:
- "A" - optional: - "B" - barrier: - optional: - "C"
diagram = sequence( terminal("A"), optional( terminal("B"), barrier( optional( terminal("C"), ) ) ) )
Without barrier:
With barrier:
A B C A B C
- type syntax_diagrams.Group[T]¶
Draws a box around some element.
Dict keys:
group: Element[T]
, requiredElement that will be placed in a group.
href: text
Optional caption for this group.
href: str
Makes group’s caption into a hyperlink.
title: str
Title for hyperlink.
css_class: str
Adds CSS class to group’s
<g>
element.
Example:
- "def" - "(" - group: - zero_or_more: - non_terminal: "param" - optional: - ":" - non_terminal: "type" repeat: "," - optional: "," text: Function parameters - ")" - ":"
diagram = sequence( terminal("def"), terminal("("), group( zero_or_more( non_terminal("param"), optional( terminal(":"), non_terminal("type"), ), repeat=terminal(","), ), optional(terminal(",")), text="Function parameters", ), terminal(")"), terminal(":"), )
def ( Function parameters param : type , , ) :
Using constructors¶
If you’re building diagrams manually in python code, you can use these constructors:
- syntax_diagrams.skip() Element[T] ¶
Create an element that renders as a single line without content.
See
Element
for more information.
- syntax_diagrams.terminal(text: str, *, href: str | None = None, title: str | None = None, css_class: str | None = None, resolve: bool | None = None, resolver_data: T | None = None) Element[T] ¶
Create a terminal node with optional additional settings.
See
Terminal
for description of parameters.
- syntax_diagrams.non_terminal(text: str, *, href: str | None = None, title: str | None = None, css_class: str | None = None, resolve: bool | None = None, resolver_data: T | None = None) Element[T] ¶
Create a non-terminal node with optional additional settings.
See
NonTerminal
for description of parameters.
- syntax_diagrams.comment(text: str, *, href: str | None = None, title: str | None = None, css_class: str | None = None, resolve: bool | None = None, resolver_data: T | None = None) Element[T] ¶
Create a comment node with optional additional settings.
See
Comment
for description of parameters.
- syntax_diagrams.sequence(*items: Element[T], linebreaks: _t.Literal['HARD', 'SOFT', 'DEFAULT', 'NO_BREAK'] | LineBreak | list[_t.Literal['HARD', 'SOFT', 'DEFAULT', 'NO_BREAK'] | LineBreak] | None = None) Element[T] ¶
Create an automatically wrapped sequence of elements.
See
Sequence
for description of parameters.
- syntax_diagrams.stack(*items: Element[T]) Element[T] ¶
Create a sequence of elements that wraps after each element.
See
Stack
for description of parameters.
- syntax_diagrams.no_break(*items: Element[T]) Element[T] ¶
Create a sequence of elements that doesn’t wrap.
See
NoBreak
for description of parameters.
- syntax_diagrams.choice(*items: Element[T], default: int = 0) Element[T] ¶
Create a choice between several elements.
See
Choice
for description of parameters.
- syntax_diagrams.optional(*items: Element[T], skip: bool = False, skip_bottom: bool = False) Element[T] ¶
Create an optional element.
See
Optional
for description of parameters.
- syntax_diagrams.one_or_more(*items: Element[T], repeat: Element[T] | None = None) Element[T] ¶
Create a repeated element.
See
OneOrMore
for description of parameters.
- syntax_diagrams.zero_or_more(*items: Element[T], repeat: Element[T] | None = None, skip: bool = False, skip_bottom: bool = False) Element[T] ¶
Create an optional repeated element.
See
ZeroOrMore
for description of parameters.
Line breaks and wrapping¶
You can use Stack
and NoBreak
to control how diagram lines are wrapped.
Additionally, you can pass a list of line breaks to a Sequence
element.
- class syntax_diagrams.LineBreak(*values)¶
Type of a line break that can be specified when creating a sequence.
- DEFAULT = 'DEFAULT'¶
Prefers not to break line in this position unless necessary.
- HARD = 'HARD'¶
Always breaks a line in this position.
- NO_BREAK = 'NO_BREAK'¶
Disables breaking in this position.
- SOFT = 'SOFT'¶
Breaks a line in this position if the sequence can’t fit in allowed dimensions.