all2md.ast.visitors
Visitor pattern implementation for AST traversal.
This module provides the visitor pattern base classes for traversing and processing AST nodes. Visitors enable separation of algorithms (like rendering, validation, transformation) from the node structure itself.
The visitor pattern allows for: - Clean separation of concerns - Easy addition of new processing algorithms - Type-safe node processing - Flexible tree traversal strategies
- class all2md.ast.visitors.NodeVisitor
Bases:
ABCAbstract base class for AST node visitors.
Subclasses should implement visit_* methods for each node type they want to process. The visitor pattern allows algorithms to be separated from the node structure.
All visit methods should accept a node and return Any (typically None for side-effect visitors, or accumulated results for transforming visitors).
Examples
Simple visitor that counts nodes:
>>> class NodeCounter(NodeVisitor): ... def __init__(self): ... self.count = 0 ... ... def generic_visit(self, node): ... self.count += 1 ... # Visit children if they exist ... if hasattr(node, 'children'): ... for child in node.children: ... child.accept(self) ... >>> counter = NodeCounter() >>> document.accept(counter) >>> print(counter.count)
- abstractmethod visit_document(node: Document) Any
Visit a Document node.
- Parameters:
node (Document) – The document node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_heading(node: Heading) Any
Visit a Heading node.
- Parameters:
node (Heading) – The heading node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_paragraph(node: Paragraph) Any
Visit a Paragraph node.
- Parameters:
node (Paragraph) – The paragraph node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_code_block(node: CodeBlock) Any
Visit a CodeBlock node.
- Parameters:
node (CodeBlock) – The code block node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_block_quote(node: BlockQuote) Any
Visit a BlockQuote node.
- Parameters:
node (BlockQuote) – The block quote node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_list(node: List) Any
Visit a List node.
- Parameters:
node (List) – The list node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_list_item(node: ListItem) Any
Visit a ListItem node.
- Parameters:
node (ListItem) – The list item node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_table(node: Table) Any
Visit a Table node.
- Parameters:
node (Table) – The table node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_table_row(node: TableRow) Any
Visit a TableRow node.
- Parameters:
node (TableRow) – The table row node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_table_cell(node: TableCell) Any
Visit a TableCell node.
- Parameters:
node (TableCell) – The table cell node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_thematic_break(node: ThematicBreak) Any
Visit a ThematicBreak node.
- Parameters:
node (ThematicBreak) – The thematic break node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_html_block(node: HTMLBlock) Any
Visit an HTMLBlock node.
- Parameters:
node (HTMLBlock) – The HTML block node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_comment(node: Comment) Any
Visit a Comment node (block-level).
- Parameters:
node (Comment) – The comment block node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_text(node: Text) Any
Visit a Text node.
- Parameters:
node (Text) – The text node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_emphasis(node: Emphasis) Any
Visit an Emphasis node.
- Parameters:
node (Emphasis) – The emphasis node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_strong(node: Strong) Any
Visit a Strong node.
- Parameters:
node (Strong) – The strong node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_code(node: Code) Any
Visit a Code node.
- Parameters:
node (Code) – The code node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_link(node: Link) Any
Visit a Link node.
- Parameters:
node (Link) – The link node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_image(node: Image) Any
Visit an Image node.
- Parameters:
node (Image) – The image node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_line_break(node: LineBreak) Any
Visit a LineBreak node.
- Parameters:
node (LineBreak) – The line break node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_strikethrough(node: Strikethrough) Any
Visit a Strikethrough node.
- Parameters:
node (Strikethrough) – The strikethrough node to visit
- Returns:
Result of processing this node
- Return type:
Any
- visit_mark(node: Mark) Any
Visit a Mark (highlight) node.
Unlike most visit methods this is concrete rather than abstract so that visitors predating the Mark node (e.g. format renderers that do not have a dedicated highlight syntax) degrade gracefully: the default simply visits the node’s children, emitting their content unwrapped rather than dropping it. Visitors that support highlighting should override this method.
- Parameters:
node (Mark) – The mark node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_underline(node: Underline) Any
Visit an Underline node.
- Parameters:
node (Underline) – The underline node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_superscript(node: Superscript) Any
Visit a Superscript node.
- Parameters:
node (Superscript) – The superscript node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_subscript(node: Subscript) Any
Visit a Subscript node.
- Parameters:
node (Subscript) – The subscript node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_html_inline(node: HTMLInline) Any
Visit an HTMLInline node.
- Parameters:
node (HTMLInline) – The inline HTML node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_comment_inline(node: CommentInline) Any
Visit a CommentInline node (inline).
- Parameters:
node (CommentInline) – The inline comment node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_footnote_reference(node: FootnoteReference) Any
Visit a FootnoteReference node.
- Parameters:
node (FootnoteReference) – The footnote reference node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_math_inline(node: MathInline) Any
Visit a MathInline node.
- Parameters:
node (MathInline) – The inline math node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_footnote_definition(node: FootnoteDefinition) Any
Visit a FootnoteDefinition node.
- Parameters:
node (FootnoteDefinition) – The footnote definition node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_definition_list(node: DefinitionList) Any
Visit a DefinitionList node.
- Parameters:
node (DefinitionList) – The definition list node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_definition_term(node: DefinitionTerm) Any
Visit a DefinitionTerm node.
- Parameters:
node (DefinitionTerm) – The definition term node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_definition_description(node: DefinitionDescription) Any
Visit a DefinitionDescription node.
- Parameters:
node (DefinitionDescription) – The definition description node to visit
- Returns:
Result of processing this node
- Return type:
Any
- abstractmethod visit_math_block(node: MathBlock) Any
Visit a MathBlock node.
- Parameters:
node (MathBlock) – The math block node to visit
- Returns:
Result of processing this node
- Return type:
Any
- generic_visit(node: Node) Any
Fallback visitor for unhandled node types.
This method is called when no specific visit_* method exists. The default implementation does nothing but can be overridden.
- Parameters:
node (Node) – The node to visit
- Returns:
Result of processing (default: None)
- Return type:
Any
- class all2md.ast.visitors.ValidationVisitor
Bases:
NodeVisitorVisitor that validates AST structure.
This visitor checks for structural issues in the AST, such as: - Invalid nesting (e.g., block nodes inside inline nodes) - Missing required fields - Invalid field values - Presence of raw HTML content (when disallowed) - Block/inline containment rules (in strict mode) - URL scheme validation (in strict mode)
- Parameters:
strict (bool, default = True) – Whether to raise errors on validation failures
allow_raw_html (bool, default = False) – Whether to allow HTMLBlock and HTMLInline nodes. By default (False), any raw HTML content will trigger a validation error for security. Set to True only when you trust the HTML source and need to preserve raw HTML content. This follows security best practices of default-deny for potentially unsafe content.
Notes
- Security Considerations:
Raw HTML in documents can pose security risks (XSS attacks, code injection). This validator defaults to rejecting HTML to enforce security best practices. Only set allow_raw_html=True when: - You trust the document source - HTML will be sanitized before rendering - You’re working in a trusted/non-web context
Examples
- Strict validation (rejects HTML by default):
>>> validator = ValidationVisitor(strict=True) >>> doc.accept(validator) # Raises ValueError if HTML present
- Allow HTML from trusted sources:
>>> validator = ValidationVisitor(strict=True, allow_raw_html=True) >>> doc.accept(validator) # Permits HTMLBlock/HTMLInline nodes
Initialize the validator with strictness and HTML policy.
- Parameters:
strict (bool, default = True) – Whether to raise errors immediately on validation failures
allow_raw_html (bool, default = False) – Whether to allow raw HTML nodes (security: default deny)
- INLINE_NODES = frozenset({<class 'all2md.ast.nodes.Code'>, <class 'all2md.ast.nodes.Emphasis'>, <class 'all2md.ast.nodes.FootnoteReference'>, <class 'all2md.ast.nodes.HTMLInline'>, <class 'all2md.ast.nodes.Image'>, <class 'all2md.ast.nodes.LineBreak'>, <class 'all2md.ast.nodes.Link'>, <class 'all2md.ast.nodes.Mark'>, <class 'all2md.ast.nodes.MathInline'>, <class 'all2md.ast.nodes.Strikethrough'>, <class 'all2md.ast.nodes.Strong'>, <class 'all2md.ast.nodes.Subscript'>, <class 'all2md.ast.nodes.Superscript'>, <class 'all2md.ast.nodes.Text'>, <class 'all2md.ast.nodes.Underline'>})
- BLOCK_NODES = frozenset({<class 'all2md.ast.nodes.BlockQuote'>, <class 'all2md.ast.nodes.CodeBlock'>, <class 'all2md.ast.nodes.DefinitionDescription'>, <class 'all2md.ast.nodes.DefinitionList'>, <class 'all2md.ast.nodes.DefinitionTerm'>, <class 'all2md.ast.nodes.Document'>, <class 'all2md.ast.nodes.FootnoteDefinition'>, <class 'all2md.ast.nodes.HTMLBlock'>, <class 'all2md.ast.nodes.Heading'>, <class 'all2md.ast.nodes.List'>, <class 'all2md.ast.nodes.ListItem'>, <class 'all2md.ast.nodes.MathBlock'>, <class 'all2md.ast.nodes.Paragraph'>, <class 'all2md.ast.nodes.Table'>, <class 'all2md.ast.nodes.TableCell'>, <class 'all2md.ast.nodes.TableRow'>, <class 'all2md.ast.nodes.ThematicBreak'>})
- __init__(strict: bool = True, allow_raw_html: bool = False)
Initialize the validator with strictness and HTML policy.
- Parameters:
strict (bool, default = True) – Whether to raise errors immediately on validation failures
allow_raw_html (bool, default = False) – Whether to allow raw HTML nodes (security: default deny)
- errors: list[str]
- visit_block_quote(node: BlockQuote) None
Validate a BlockQuote node.
- visit_thematic_break(node: ThematicBreak) None
Validate a ThematicBreak node.
- visit_html_block(node: HTMLBlock) None
Validate an HTMLBlock node.
Checks if raw HTML is allowed based on the allow_raw_html setting.
- visit_comment(node: Comment) None
Validate a Comment node (block-level).
Comments are informational and generally safe, but we validate that they have content.
- visit_strikethrough(node: Strikethrough) None
Validate a Strikethrough node.
- visit_superscript(node: Superscript) None
Validate a Superscript node.
- visit_html_inline(node: HTMLInline) None
Validate an HTMLInline node.
Checks if raw HTML is allowed based on the allow_raw_html setting.
- visit_comment_inline(node: CommentInline) None
Validate a CommentInline node (inline).
Comments are informational and generally safe, but we validate that they have content.
- visit_footnote_reference(node: FootnoteReference) None
Validate a FootnoteReference node.
- visit_math_inline(node: MathInline) None
Validate a MathInline node.
- visit_footnote_definition(node: FootnoteDefinition) None
Validate a FootnoteDefinition node.
- visit_definition_list(node: DefinitionList) None
Validate a DefinitionList node.
- visit_definition_term(node: DefinitionTerm) None
Validate a DefinitionTerm node.
- visit_definition_description(node: DefinitionDescription) None
Validate a DefinitionDescription node.