Pre-release
This release is a pre-release and may not be stable for production use.
= AsciiDoctype
:toc: left
:toc-title: Contents
:toclevels: 3
:icons: font
:source-highlighter: highlight.js
:description: A standalone, pure-Python HTML5 and XHTML rendering library for AsciiDoctrine ASG dictionaries.
image:https://img.shields.io/badge/License-Apache%202.0-blue.svg[Apache 2.0 License, link=LICENSE.adoc]
image:https://img.shields.io/badge/python-%3E%3D3.10-green[Python 3.10+]
image:https://img.shields.io/badge/chameleon-%3E%3D4.0-orange[Chameleon 4.0+]
image:https://img.shields.io/badge/latex2mathml-%3E%3D3.77-purple[latex2mathml 3.77+]
image:https://img.shields.io/badge/asciidoctrine-%3E%3D0.2.0a1-blue[AsciiDoctrine 0.2.0a1+]
image:https://img.shields.io/pypi/v/asciidoctype.svg[PyPI, link=https://pypi.org/project/asciidoctype/]
AsciiDoctype is a **headless, pure-Python rendering library** that lowers the
Resolved Abstract Semantic Graph (ASG) produced by
https://github.com/asciidoctor/asciidoctrine[AsciiDoctrine] into valid,
well-formed HTML5 or strict XHTML markup.
It is the designated rendering layer in the **AsciiDoctrine ecosystem** — sitting
between the semantic parser and any downstream orchestrator (Golem SSG, EPUB
compilers, custom toolchains).
....
+--------------------+ +------------------+ +---------------------+
| AsciiDoctrine | ───> | AsciiDoctype | ───> | Golem / EPUB / |
| (Pure Semantic ASG)| | (Chameleon ZPT) | | Custom Tool |
+--------------------+ +------------------+ +---------------------+
....
== Why AsciiDoctype?
[cols="1,3",options="header"]
|===
|Principle |Explanation
|*Headless*
|Ships zero CSS, zero JavaScript, zero styling opinions. Markup is clean,
un-styled semantic HTML ready for any design system downstream.
|*Themeable*
|Custom themes supply their own Chameleon (ZPT) templates. AsciiDoctype
resolves user templates first and falls back to its bundled core templates
automatically.
|*Dual-pipeline*
|Identical ASG dictionaries render cleanly to either HTML5 (browser-native)
or XHTML 1.0 Strict (EPUB/Kindle-safe) with a single constructor flag.
|*Bytecode speed*
|Powered by https://chameleon.readthedocs.io/[Chameleon], which pre-compiles
templates to native Python bytecode. Recursive tree rendering is fast even on
deeply nested documents.
|*Clean boundaries*
|AsciiDoctype never touches the filesystem beyond template lookup. No file I/O,
no CSS injection, no link validation — each concern lives in the correct layer.
|*Native MathML*
|Converts LaTeX math (latexmath) to native MathML markup at render time via latex2mathml. No downstream JavaScript dependencies like MathJax or KaTeX needed.
|===
== Quick Start
=== Installation
[source,bash]
----
pip install asciidoctype
----
Or in development mode:
[source,bash]
----
git clone https://github.com/webmaven/asciidoctype.git
cd asciidoctype
python -m venv .venv && source .venv/bin/activate
pip install -e .[test]
----
=== Minimal Usage
[source,python]
----
from asciidoctype import AsciiDoctypeRenderer
renderer = AsciiDoctypeRenderer(target_format="html5")
# An ASG node dictionary as produced by AsciiDoctrine's to_dict()
node = {
"name": "paragraph",
"type": "block",
"attributes": {},
"inlines": [
{"name": "text", "type": "string", "value": "Hello, "},
{
"name": "span",
"type": "inline",
"variant": "strong",
"inlines": [{"name": "text", "type": "string", "value": "world"}],
},
{"name": "text", "type": "string", "value": "!"},
],
}
html = renderer.render(node)
# → '<p>Hello, <strong>world</strong>!</p>'
----
=== Rendering a Complete Document
[source,python]
----
from asciidoctype import AsciiDoctypeRenderer
renderer = AsciiDoctypeRenderer(target_format="html5")
document_node = {
"name": "document",
"type": "block",
"header": {"title": "My Document"},
"blocks": [
{
"name": "section",
"type": "block",
"level": 1,
"attributes": {"id": "intro"},
"title": [{"name": "text", "type": "string", "value": "Introduction"}],
"blocks": [
{
"name": "paragraph",
"type": "block",
"attributes": {},
"inlines": [
{"name": "text", "type": "string", "value": "Welcome."}
],
}
],
}
],
}
html = renderer.render(document_node)
----
=== Using a Custom Theme
Supply an ordered list of `Path` objects. AsciiDoctype resolves templates in
order, falling back to its bundled templates for any file not found in the
custom directories.
[source,python]
----
from pathlib import Path
from asciidoctype import AsciiDoctypeRenderer
renderer = AsciiDoctypeRenderer(
target_format="html5",
search_paths=[
Path("./my_site/overrides"), # highest priority
Path("./themes/my_theme"), # secondary theme
],
)
----
If `my_site/overrides/paragraph.html` exists it is used; otherwise
`themes/my_theme/paragraph.html` is tried; otherwise the bundled
`core_templates/html5/paragraph.html` is used.
== XHTML (EPUB) Mode
[source,python]
----
renderer = AsciiDoctypeRenderer(target_format="xhtml")
----
XHTML mode produces:
* `<?xml version="1.0" encoding="UTF-8"?>` declaration
* `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" ...>` DOCTYPE
* `<html xmlns="http://www.w3.org/1999/xhtml">` namespace binding
* Explicit `<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />`
* All void elements closed: `<br />`, `<img />`, `<meta />`
== API Reference
=== `AsciiDoctypeRenderer`
[source,python]
----
class AsciiDoctypeRenderer:
def __init__(
self,
target_format: str = "html5",
search_paths: Optional[List[Path]] = None,
strict: bool = False,
validate_templates: bool = True,
max_depth: int = 500,
) -> None: ...
def render(
self,
node: Dict[str, Any],
context: Optional[Dict[str, Any]] = None,
) -> str: ...
----
`target_format`::
`"html5"` (default) or `"xhtml"`. Raises `ValueError` for any other value.
`search_paths`::
Ordered list of `Path` objects for template override directories. The bundled
core templates are always appended last as the final fallback.
`strict`::
`bool` (default `False`). When `True`, enforces fail-fast validation: rejects
unrecognized node types, disallowed URI schemes (`javascript:`, etc.), and
template security audit warnings.
`validate_templates`::
`bool` (default `True`). Audits custom search paths on initialization using
`asciidoctype.linter` to detect insecure template directives (`structure`).
`max_depth`::
`int` (default `500`). Maximum recursion depth protection against circular or
maliciously deep ASG trees.
`render(node, context=None)`::
Recursively renders an ASG node dictionary and returns a markup string.
Raises `TypeError` if `node` is not a dict with a `"name"` key.
Raises `AsciiDoctypeRenderingError` if template execution fails.
=== `AsciiDoctypeRenderingError`
Raised when a Chameleon template fails during rendering. The message includes
the node name, target pipeline, and the underlying error for quick diagnosis.
[source,python]
----
from asciidoctype import AsciiDoctypeRenderingError
try:
html = renderer.render(bad_node)
except AsciiDoctypeRenderingError as e:
print(e)
# Critical rendering failure processing structural node entity: 'listing'
# Target Specification Pipeline: [html5]. Base Error: ...
----
== Project Links
* Showcase Gallery: https://webmaven.github.io/asciidoctype/ (Zero-JS E2E Node Gallery)
* PyPI: https://pypi.org/project/asciidoctype/
* Source: https://github.com/webmaven/asciidoctype
* Issues: https://github.com/webmaven/asciidoctype/issues
* License: link:LICENSE.adoc[Apache 2.0]
* Changelog: link:CHANGELOG.adoc[CHANGELOG.adoc]
* Architecture: link:ARCHITECTURE.adoc[ARCHITECTURE.adoc] — design, internals, ASG schemas
* Developer Guide: link:AGENTS.adoc[AGENTS.adoc] — development setup, standards, and workflows
* Contributing: link:CONTRIBUTING.adoc[CONTRIBUTING.adoc] — how to submit changes
Release files for asciidoctype 0.1.0a3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| asciidoctype-0.1.0a3.tar.gz | 41.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| asciidoctype-0.1.0a3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 91.6 kB
Release files / asciidoctype-0.1.0a3.tar.gz
| Download URL | asciidoctype-0.1.0a3.tar.gz |
|---|---|
| Size | 41.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a37285211fd81ad54dabc2e7fb8cc361339404329fd069556325179e6cc5d42e
|
|
BLAKE2b-256 checksum How to use checksums |
61a000c8d28bc495c8e773a16d0c9e8df24655bdc9b0e27ba5adac9f117e83a6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.5
|
Release files / asciidoctype-0.1.0a3-py3-none-any.whl
| Download URL | asciidoctype-0.1.0a3-py3-none-any.whl |
|---|---|
| Size | 50.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e64ec7c63741afcf6b422b755fe3b77f7a9bca723dc4669944902263f0d4b19b
|
|
BLAKE2b-256 checksum How to use checksums |
70273adbff52b0d9ac84d010d7398f84923982248e0fe6725f6cefdcc339ccfe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.5
|