Skip to main content

A high-performance, pure-Python AsciiDoc parser based on Lark.

Project description

= Asciidoctrine
Michael R. Bernstein <zopemaven@gmail.com>
v0.1.0
:toc: left
:icons: font
:idprefix:
:idseparator: -
:sectanchors:
:sectlinks:
:source-highlighter: highlight.js

image:https://img.shields.io/badge/License-Apache_2.0-blue.svg[License, link=https://opensource.org/licenses/Apache-2.0]
image:https://img.shields.io/badge/python-3.9+-blue.svg[Python Version]
image:https://img.shields.io/badge/status-alpha-orange.svg[Development Status]

A high-performance, pure-Python AsciiDoc parser built with Lark, designed for compatibility with the official AsciiDoc specification and the TCK.

== 💡 Motivation

The Python ecosystem has long lacked a modern, maintainable, and specification-compliant AsciiDoc parser. Existing tools are often port-based or rely on regex-heavy implementations that struggle with the complex, context-sensitive nature of AsciiDoc.

Asciidoctrine is built from the ground up to provide:

1. **Spec Alignment**: Strict adherence to the upcoming official AsciiDoc Language Specification.
2. **First-Class AST**: A structured, type-safe Abstract Syntax Tree that makes building renderers and static analysis tools a breeze.
3. **Performance**: Leveraging the Lark parsing engine for efficient processing of large documents.

== 🏗 Architecture

The parser operates in a multi-pass pipeline to handle the inherent complexity of AsciiDoc:

[source,mermaid]
....
graph LR
A[Source] --> B(Lark Parser)
B --> C[Concrete Syntax Tree]
C --> D(Transformer)
D --> E[Structured AST]
E --> F(Semantic Passes)
F --> G[Resolved ASG]
....

* **AST (Abstract Syntax Tree)**: Represented in `nodes.py`, this is a structural tree of the document elements.
* **ASG (Abstract Semantic Graph)**: The final resolved state where attributes, cross-references, and includes are fully processed.

== 🛠️ Technical Choices

* **Lark Parsing Engine**: We use Lark because it supports multiple parsing algorithms (Earley, LALR) and has an experimental PEG mode. This allow us to handle the context-sensitive nature of AsciiDoc without the maintenance nightmare of large regex collections.
* **Two-Pass Pipeline**: Handling attributes and includes requires knowing the state of the whole document. Our multi-pass approach ensures that we can resolve semantic details (like cross-references) correctly.
* **Pure Python**: Zero C-extensions means easy installation on all platforms including Pyodide and WebAssembly.

== 🚀 Installation

[source,bash]
----
pip install asciidoctrine
----

> [!NOTE]
> This package is currently in early alpha. It is being developed in tandem with the official TCK integration.

== 📖 Quick Start

[source,python]
----
from asciidoctrine.lark_parser import parse_to_ast

source = """
== Section Title
This is a *bold* word in a paragraph.
"""

# Returns a Document node from nodes.py
doc = parse_to_ast(source)

# Iterate through sections
for section in doc.walk():
if section.type == 'section':
print(f"Found section: {section.title_node.children[0].text}")
----

=== AST Representation

Parsing the source above yields a structured representation:

[source,json]
----
{
"type": "document",
"children": [
{
"type": "section",
"level": 1,
"title": {
"type": "title",
"children": [
{ "type": "text", "text": "Section Title" }
]
},
"children": [
{
"type": "paragraph",
"children": [
{ "type": "text", "text": "This is a " },
{ "type": "strong", "children": [{ "type": "text", "text": "bold" }] },
{ "type": "text", "text": " word in a paragraph." }
]
}
]
}
]
}
----

== 🗺 Roadmap to Parity

The path to 1:1 parity with Asciidoctor is tracked through the following phases:

[cols="1,3,1"]
|===
| Phase | Focus | Status

| **0** | **Foundations**: PEG grammar, structured AST, and TCK harness. | ✅
| **1** | **Advanced Blocks**: Admonitions ✅, Sidebars ✅, Source blocks ✅, and Example blocks ✅. | ✅
| **2** | **Document Infra**: Headers ✅, attributes ✅, and includes ✅. | ✅
| **3** | **Tables & Description Lists**: Nested/mixed description lists and advanced table cell alignments/spans (Priority 1). | ⏳
| **4** | **Testing Integration (`asciidoctest`)**: Code block attributes, callout stripping, and source location tracking (Priority 2). | ⏳
| **5** | **Static Site Generator Support**: Auto-slugified section IDs, TOC outline extraction, and cross-references (Priority 3). | ⏳
| **6** | **Sphinx Extension Support**: Metadata alignment, complete node renderer visitor auditing, and Pygments styling (Priority 4). | ⏳
|===

== 📁 Project Structure

[source,text]
----
asciidoctrine/
├── src/
│ └── asciidoctrine/ # Core parser logic
│ ├── grammar.lark # EBNF Grammar
│ ├── lark_parser.py # Transformer and Parser entry point
│ ├── nodes.py # AST Node definitions
│ └── __init__.py # Public API
├── examples/ # Real-world usage samples
├── tests/ # Unit and integration tests
├── pyproject.toml # Build configuration
└── README.adoc # This file
----

== 🧪 Testing & Compliance

We prioritize correctness by testing against three fronts:
1. **Unit Tests**: Granular tests for individual grammar rules.
2. **Integration Suite**: A library of real-world `.adoc` examples.
3. **TCK (Technology Compatibility Kit)**: (In-Progress) Alignment with the official AsciiDoc TCK suite.

Run tests locally with:
[source,bash]
----
pytest
----

== 🤝 Contributing

We welcome contributions! Please see link:CONTRIBUTING.adoc[CONTRIBUTING.adoc] for setup instructions and code style guidelines.

== 📜 License

Distributed under the **Apache License 2.0**. See link:LICENSE[LICENSE] for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

asciidoctrine-0.1.0a1.tar.gz (43.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

asciidoctrine-0.1.0a1-py3-none-any.whl (35.0 kB view details)

Uploaded Python 3

File details

Details for the file asciidoctrine-0.1.0a1.tar.gz.

File metadata

  • Download URL: asciidoctrine-0.1.0a1.tar.gz
  • Upload date:
  • Size: 43.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for asciidoctrine-0.1.0a1.tar.gz
Algorithm Hash digest
SHA256 48d4cb1c90b884c00adc23227b74e6d0c1a57e8adb72ae90d6b18a413cff4ee9
MD5 02fb89ad27633d2705f0069ca5021b47
BLAKE2b-256 9f339ea5678929c178e65a98fa42de7ed2f3201ec5be6aa3f1a079d03f77fd01

See more details on using hashes here.

File details

Details for the file asciidoctrine-0.1.0a1-py3-none-any.whl.

File metadata

File hashes

Hashes for asciidoctrine-0.1.0a1-py3-none-any.whl
Algorithm Hash digest
SHA256 f9cfef5a07c9b99e3d61a65f6cfcdf47883002387957f6bcd90f5d1182bb40c8
MD5 d7370fe58cef51c63ebf70b32d6d35ef
BLAKE2b-256 7fc23a75b6f521cca32cd429c797dbd81adf30a5df008c68d6248021dada7e90

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page