Skip to main content
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.0a5-blue[AsciiDoctrine 0.2.0a5+]
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

You can use the direct `render()` convenience function:

[source,python]
----
import asciidoctype

# 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 = asciidoctype.render(node, target_format="html5")
# → '<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

=== `asciidoctype.render`

[source,python]
----
def render(
node: Dict[str, Any],
target_format: TargetFormat | str = "html5",
search_paths: Optional[Sequence[str | Path]] = None,
strict: bool = False,
validate_templates: bool = True,
max_depth: int = 500,
highlighter: Optional[HighlighterCallable] = None,
context: Optional[Dict[str, Any]] = None,
) -> str: ...
----

Convenience shortcut that instantiates an `AsciiDoctypeRenderer` and renders an ASG node in a single call.

=== `AsciiDoctypeRenderer`

[source,python]
----
class AsciiDoctypeRenderer:
def __init__(
self,
target_format: TargetFormat | str = "html5",
search_paths: Optional[Sequence[str | Path]] = None,
strict: bool = False,
validate_templates: bool = True,
max_depth: int = 500,
highlighter: Optional[HighlighterCallable] = None,
) -> 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 sequence of directory paths (`str` or `pathlib.Path`) for custom template overrides.
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.

`highlighter`::
`HighlighterCallable` (`Callable[[str, str], Optional[str]]`, default `None`). Optional
server-side syntax highlighting callable receiving `(code, language)` (e.g. Pygments).

`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.0a5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for asciidoctype 0.1.0a5
File Size Uploaded
asciidoctype-0.1.0a5.tar.gz 45.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for asciidoctype 0.1.0a5
File Interpreter ABI Platform
asciidoctype-0.1.0a5-py3-none-any.whl Python 3 none any Details

Total release size: 97.6 kB

Release files / asciidoctype-0.1.0a5.tar.gz

Download URL asciidoctype-0.1.0a5.tar.gz
Size 45.6 kB
Tags Source
SHA-256 checksum
How to use checksums
7aab464ca57022207b8ff465900c2074ae8fe314d6a9bcdd135d56197880e88e
BLAKE2b-256 checksum
How to use checksums
8f18fedfd8dcc5221074ddc3467abf44648fcf9536cc457599b405a96cc81166
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.0a5-py3-none-any.whl

Download URL asciidoctype-0.1.0a5-py3-none-any.whl
Size 52.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dafe50483d2ff438ab0b1eb4eb99e1960af88d9f09806163065a14ead16a5359
BLAKE2b-256 checksum
How to use checksums
6321329c43f8186e784682ebed0397d8ba9a79d0989a7a1fa1194c0bdf1fae40
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.5
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page