all2md.parsers.org

Org-Mode to AST converter.

This module provides conversion from Org-Mode documents to AST representation using the orgparse parser. It enables bidirectional transformation by parsing Org files into the same AST structure used for other formats.

class all2md.parsers.org.OrgParser

Bases: BaseParser

Convert Org-Mode to AST representation.

This converter uses orgparse to parse Org-Mode files and builds an AST that matches the structure used throughout all2md, enabling bidirectional conversion and transformation pipelines.

Parameters:

options (OrgParserOptions or None, default = None) – Parser configuration options

Notes

orgparse Limitations:

The parser relies on the orgparse library which has some known limitations:

  • LOGBOOK drawer content: When SCHEDULED/DEADLINE lines are placed after a PROPERTIES drawer (non-standard position), orgparse may strip the LOGBOOK drawer content. This is an orgparse limitation, not a bug in all2md.

  • Drawer positioning: Org-mode spec requires planning lines (SCHEDULED, DEADLINE, CLOSED) to come right after the heading. Some documents place them after PROPERTIES, which can cause parsing issues.

  • CLOCK entries: CLOCK entries within LOGBOOK drawers may or may not be available depending on document structure. The parser attempts to extract them from both node.clock and LOGBOOK drawer content.

What IS Supported:

  • ✓ SCHEDULED timestamps with time ranges and repeaters

  • ✓ DEADLINE timestamps

  • ✓ CLOSED timestamps (when properly positioned)

  • ✓ Properties drawer (well-supported)

  • ✓ Tags and TODO keywords

  • ✓ LOGBOOK drawer (when content is available)

  • ✓ CLOCK entries (via node.clock)

  • ✓ Full timestamp metadata preservation

Examples

Basic parsing:

>>> parser = OrgParser()
>>> doc = parser.parse("* Heading\n\nThis is **bold**.")

With options:

>>> options = OrgParserOptions(
...     todo_keywords=["TODO", "IN-PROGRESS", "DONE"],
...     parse_tags=True
... )
>>> parser = OrgParser(options)
>>> doc = parser.parse(org_text)

Enhanced features:

>>> options = OrgParserOptions(
...     parse_closed=True,
...     parse_logbook=True,
...     preserve_timestamp_metadata=True
... )
>>> parser = OrgParser(options)
>>> doc = parser.parse(org_file)
>>> # Access enhanced metadata
>>> heading = doc.children[0]
>>> if "org_closed" in heading.metadata:
...     print(f"Closed: {heading.metadata['org_closed']}")

Initialize the Org parser with options and progress callback.

__init__(options: OrgParserOptions | None = None, progress_callback: Callable[[ProgressEvent], None] | None = None)

Initialize the Org parser with options and progress callback.

parse(input_data: str | Path | IO[bytes] | bytes) Document

Parse Org-Mode input into AST Document.

Parameters:

input_data (str, Path, IO[bytes], or bytes) – Org-Mode input to parse. Can be: - File path (str or Path) - File-like object in binary mode - Raw Org bytes - Org string

Returns:

AST document node

Return type:

Document

Raises:
extract_metadata(document: Any) DocumentMetadata

Extract metadata from orgparse document.

Parameters:

document (orgparse.OrgNode) – Parsed orgparse document

Returns:

Extracted metadata from document

Return type:

DocumentMetadata

Notes

Org-Mode documents can have metadata in several places: - File-level properties (#+TITLE:, #+AUTHOR:, etc.) via env - Top-level heading as title - Properties drawer in first heading