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.0a7-blue[AsciiDoctrine 0.2.0a7+]
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.0a6

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.0a6
File Size Uploaded
asciidoctype-0.1.0a6.tar.gz 45.9 kB Details

Built distribution (wheel)

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

Total release size: 97.8 kB

Release files / asciidoctype-0.1.0a6.tar.gz

Download URL asciidoctype-0.1.0a6.tar.gz
Size 45.9 kB
Tags Source
SHA-256 checksum
How to use checksums
af39da16627fd4f621e7eee3adb065557b0bb20d91fb6e10f718b22fbc119221
BLAKE2b-256 checksum
How to use checksums
2a0616f3daf73d723c0f5ccc5f10fca2e8ae78cdc18a86d5db489c6dc9bd20b1
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.0a6-py3-none-any.whl

Download URL asciidoctype-0.1.0a6-py3-none-any.whl
Size 52.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d8c7d90be4f453ff9dbc20b6fc0be76da96d3665f919e6d7dbbfd93ceecccac7
BLAKE2b-256 checksum
How to use checksums
65f2b793e9b895fdd3724573754f1312364b149316404ce220bf7b869b34456b
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