AST#

class humanmark.ast.Node(*, line_no=0, children=None)#

The base class for all types of nodes in the AST.

Internals

Internally, Node’s are a doubly-linked list. This isn’t terribly efficient in Python, but makes complex structure manipulation trivial. Since we’re human-focused, this trade-off in favour of usability is well worth it.

first: humanmark.ast.Node#

The first child in the node.

last: humanmark.ast.Node#

The last child in the node.

parent: humanmark.ast.Node#

The parent of this node.

next: humanmark.ast.Node#

The next sibling node.

prev: humanmark.ast.Node#

The previous sibling node.

line_no#

The source line number, if known.

pprint(*, indent='', file=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, is_last=False, show_line_no=True)#

Pretty-print this node and all of its children to a file-like object.

Parameters
  • indent – The indent to apply at the start of each line. [default: ‘’]

  • file – IO object for output. [default: sys.stdout]

  • is_last – True if this is the last child in a sequence. [default: False]

  • show_line_no – True if source line numbers should be shown. [default: True]

pretty(*, indent='', show_line_no=True)#

Pretty-print this node and all of its children, returning the result as a string.

Parameters
  • indent – The indent to apply at the start of each line. [default: ‘’]

  • show_line_no – True if source line numbers should be shown. [default: True]

find(of_type=None, *, f=None, depth=None)#

Find and yield child nodes that match all given filters.

>>> fragment = Fragment(children=[Text('Hello World!')])
>>> for text in fragment.find(Text):
...     print(text.content)

find() supports simple paths. For example, to get all the text under headers:

>>> for text in fragment.find(Header / Text):
...     print(text.content)

find() supports slicing on paths, to skip items, get a range of items, or to get a specific index.

>>> for list_item in fragment.find(List / ListItem[::2]):
...     print(list_item)
Parameters
  • of_type – A Node subclass to match to.

  • f – Any callable object which will be given the node.

  • depth – The maximum depth to search for matching children. By default only immediate children are checked. Passing a negative value will search with no limit.

find_one(*args, default=None, **kwargs)#

Same as find(), but returns only the first match, or None if no result was found.

>>> fragment = Fragment(children=[Text('Hello World!')])
>>> print(fragment.find_one(Text))
Parameters
  • of_type – A Node subclass to match to.

  • f – Any callable object which will be given the node.

  • depth – The maximum depth to search for matching children. By default only immediate children are checked. Passing a negative value will search with no limit.

  • default – The value to return when no result is found. [default: None]

extend(value) humanmark.ast.Node#

Append one or more nodes to this Node’s list of children.

Parameters

value – An iterable of nodes. May also contain sub-iterables, which will be recursively flattended.

fix_missing_locations() humanmark.ast.Node#

Recursively populates line_no values on child nodes using the parent value.

is_allowed_child(child: humanmark.ast.Node) bool#

Returns True if child is allowed to be directly under this node.

It may still be possible for the child to be indirectly under this node, such as wrapping an inline in a paragraph.

Called by methods like append() and extend() to ensure the children being added are valid.

Parameters

child – The node to be checked.

tidy() humanmark.ast.Node#

Removes some redundant markup.

This:
  • Removes stray Fragment’s under a container.

  • Removes empty Text nodes.

  • Merges adjacent Text nodes.

remove(of_type=None, *, f=None, depth: Optional[int] = None) humanmark.ast.Node#

Removes all nodes that match the given conditions.

For example, to remove all the text nodes that contain the word ‘Mars’:

>>> fragment = Fragment(children=[
...     Text('Hello Earth!'),
...     Text('Hello Mars!'),
... ])
>>> fragment.remove(Text, f=lambda n: 'Mars' in n.content)

or to erase all inline HTML:

>>> fragment.remove(HTMLInline)
Parameters
  • of_type – A Node subclass to match to.

  • f – Any callable object which will be given the node. If the callable returns True, the node will be deleted.

  • depth – The maximum depth to search for matching children. By default only immediate children are checked. Passing a negative value will search with no limit.

Remove this node from its parent.

A node that has been unlinked is free to be moved to a new position in the tree or an entirely new tree.

delete() humanmark.ast.Node#

Deletes the current node and returns the next sibling.

Useful for traversing over child nodes and removing some.

replace(replacement: humanmark.ast.Node) humanmark.ast.Node#

Replaces this node with replacement and unlinks it from its parent.

contained_by(of_type: Union[humanmark.ast.Node, Sequence[humanmark.ast.Node]]) bool#

Returns True if this node is contained by a node of_type, not just as a direct parent but anywhere in the hierarchy.

of_type may also be a list of types, in which case this method with return True if this node is contained by any of the given types.

prepend_siblings(others: Iterable[humanmark.ast.Node]) humanmark.ast.Node#

Prepends all nodes in others to this node.

Returns the node at the end of others.

prepend_sibling(other: humanmark.ast.Node) humanmark.ast.Node#

Prepends the node other before this node.

As a shortcut, the << operator can be used instead. For example, to insert a header before an existing paragraph:

Paragraph(children=[Text('Hello!')]) << Header(1)
append_siblings(others: Iterable[humanmark.ast.Node]) humanmark.ast.Node#

Appends all nodes in others after this node.

Returns the node at the end of others.

append_sibling(other: humanmark.ast.Node) humanmark.ast.Node#

Inserts the node other after this node.

As a shortcut, the >> operator can be used instead. For example, to insert a paragraph after an existing header:

Header(1) >> Paragraph(children=[Text('Hello!')])
to_dict() Dict#

Recursively dump this node and all of its children to a dict.

class humanmark.ast.Fragment(*, line_no=0, children=None)#

A fragment of Markdown that serves no purpose in rendering. It simply acts as a container.

class humanmark.ast.Text(content: str, *, line_no=0, children=None)#
class humanmark.ast.ThematicBreak(char: str, *, line_no=0, children=None)#
class humanmark.ast.HTMLBlock(content: str, *, line_no=0, children=None)#
class humanmark.ast.HTMLInline(content: str, *, line_no=0, children=None)#
class humanmark.ast.Header(level: int, *, line_no=0, children=None)#
class humanmark.ast.Paragraph(*, line_no=0, children=None)#
class humanmark.ast.List(*, line_no=0, children=None, start=None)#
class humanmark.ast.ListItem(*, line_no=0, children=None, bullet: str = '-')#
class humanmark.ast.BlockQuote(*, line_no=0, children=None)#
class humanmark.ast.CodeBlock(*, line_no=0, children=None, infostring=None, fenced=None, fencechar='`')#

A block of code.

If fenced is False, the codeblock will be indented instead.

Parameters
  • infostring – Optional text that will follow the start of the fence. Typically used to specify a syntax highlighting language. [default: None]

  • fenced – Should this code block be fenced or indented. Defaults to True only if an infostring is provided. [default: False]

  • fencechar – The character to use for a fenced code block. Must be one of ‘`’ or ‘~’. [default: `]

class humanmark.ast.Strong(*, line_no=0, children=None)#
class humanmark.ast.Emphasis(*, line_no=0, children=None)#
class humanmark.ast.Strike(*, line_no=0, children=None)#

A container for a hyperlink.

If a reference is provided, it will be used when emitting a link instead of the full URL, with the actual URL being emitted elsewhere. In a markdown document, these references would typically end up at the bottom of the document.

If the url and the text are identical, the link is assumed to be an autolink.

Parameters
  • url – The relative or absolute URL to target.

  • reference – A reference label to emit instead of the full URL.

True if this link should be rendered as an autolink.

class humanmark.ast.InlineCode(*, line_no=0, children=None)#
class humanmark.ast.Image(url: str, title=None, reference=None, *, line_no=0, children=None)#

A container for an image.

If a reference is provided, it will be used when emitting a link instead of the full URL, with the actual URL being emitted elsewhere. In a markdown document, these references would typically end up at the bottom of the document.

Parameters
  • url – The relative or absolute URL to target.

  • title – A title for the image.

  • reference – A reference label to emit instead of the full URL.

class humanmark.ast.SoftBreak(*, line_no=0, children=None)#

In markdown, a softbreak represents a literal newline (\n).

Various rendering formats may discard a SoftBreak if it will have no impact on the final result, such as in HTML.