// SPDX-License-Identifier: CC-BY-SA-4.0
// Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>

= A2ML Pandoc Reader, Writer & Filter
:author: Jonathan D.A. Jewell
:toc: preamble
:icons: font

== Overview

Pandoc custom reader, writer, and Lua filter for
https://github.com/hyperpolymath/standards/tree/main/a2ml[A2ML (Attested Markup Language)].
These components let you convert A2ML documents to and from any format that
https://pandoc.org[Pandoc] supports: HTML, PDF, DOCX, Markdown, LaTeX, EPUB, and dozens more.

== Installation

Copy the Lua files into your project or a shared filters directory:

[source,sh]
----
# Minimal: reader + writer
cp a2ml-reader.lua a2ml-writer.lua /path/to/your/project/

# Full suite: reader + writer + filter + template
cp a2ml-reader.lua a2ml-writer.lua a2ml-filter.lua a2ml.html /path/to/your/project/

# Combined reader (includes writer logic)
cp a2ml.lua /path/to/your/project/
----

Requires Pandoc 3.0+ with Lua support.

== Reader: A2ML to Anything

The reader parses `.a2ml` files into the Pandoc AST, enabling conversion to any output
format.

[source,sh]
----
# A2ML to HTML
pandoc -f a2ml-reader.lua input.a2ml -o output.html

# A2ML to Markdown
pandoc -f a2ml-reader.lua input.a2ml -t markdown

# A2ML to PDF (via LaTeX)
pandoc -f a2ml-reader.lua input.a2ml -o output.pdf

# A2ML to DOCX
pandoc -f a2ml-reader.lua input.a2ml -o output.docx

# A2ML to JSON AST (for programmatic use)
pandoc -f a2ml-reader.lua input.a2ml -t json
----

=== Syntax Mapping

[cols="1,3"]
|===
| A2ML Syntax | Pandoc AST Element

| `# Heading` through `##### Heading`
| `Header` (levels 1--5) with auto-generated IDs

| `@directive(attrs): ... @end`
| `Div` with CSS classes `a2ml-directive` and `a2ml-<name>`

| `**bold**`
| `Strong`

| `*italic*`
| `Emph`

| `[text](url)`
| `Link`

| `@ref(id)`
| `Link` targeting `#id` (internal cross-reference)

| `- list items` / `* list items`
| `BulletList`

| +```lang ... ```+
| `CodeBlock` with language annotation

| `;; comment`
| Stripped (Scheme-style comments)

| Blank-line-separated text
| `Para`
|===

== Writer: Anything to A2ML

The writer converts any Pandoc-supported input format to A2ML surface syntax.

[source,sh]
----
# Markdown to A2ML
pandoc input.md -t a2ml-writer.lua -o output.a2ml

# HTML to A2ML
pandoc input.html -t a2ml-writer.lua -o output.a2ml

# Round-trip: A2ML to AST to A2ML
pandoc -f a2ml-reader.lua input.a2ml -t a2ml-writer.lua -o roundtrip.a2ml
----

The writer produces:

* `#` headings from `Header` elements
* `@directive: ... @end` from `Div` elements with `a2ml-*` classes
* `@abstract: ... @end` from `BlockQuote` elements
* Fenced code blocks with language annotations
* `@ref()` for internal cross-references (links targeting `#id`)
* Ordered and unordered lists
* SPDX header on all output

== Filter: a2ml-filter.lua

A Lua filter providing six post-processing passes over the AST. Run it with `--lua-filter`
after the reader:

[source,sh]
----
pandoc -f a2ml-reader.lua input.a2ml \
  --lua-filter=a2ml-filter.lua \
  -o output.html
----

=== Capabilities

[cols="1,3"]
|===
| Feature | Description

| Cross-reference resolver
| `@ref(id)` links are validated against actual heading anchors. Resolved refs get a
  tooltip; unresolved refs produce a warning and are marked with a CSS class.

| Include directive
| `@include(file.a2ml)` directives are replaced with the parsed content of the referenced
  file via `pandoc.read()`. Missing files produce a visible error block.

| TOC generator
| Auto-generates a Table of Contents from all document headings. Inserted after the first
  level-1 heading (or at the top if none exists). Wrapped in a Div with id `a2ml-toc`.

| Diagram rendering
| Code blocks tagged `mermaid` or `graphviz`/`dot` are rendered to inline SVG via
  `pandoc.pipe()`. Falls back to showing source code if the external tool is unavailable.

| SPDX validator
| Checks for `SPDX-License-Identifier` in metadata or early document blocks. Warns if
  missing.

| Metadata enrichment
| Populates `version`, `date`, and `author` from git (`git describe`, `git log`,
  `git config`) when not already present in the document metadata.
|===

=== Disabling Capabilities

Set metadata flags in your document or a YAML metadata block to disable individual
features:

[source,yaml]
----
---
a2ml-includes: false
a2ml-diagrams: false
a2ml-validate: false
a2ml-smart: false
---
----

== Full Pipeline

Combine reader, filter, and HTML template for the best output:

[source,sh]
----
pandoc -f a2ml-reader.lua input.a2ml \
  --lua-filter=a2ml-filter.lua \
  --template=a2ml.html \
  -o output.html
----

=== HTML Template Features

The bundled `a2ml.html` template provides:

* SPDX badge in the document header
* Directive styling: `@abstract` (blue), `@opaque` (amber), `@fig` (green), `@note` (orange), `@warning` (red)
* Responsive layout with mobile breakpoints
* Print-friendly monochrome output
* Syntax highlighting for code blocks
* Collapsible TOC box
* Cross-reference colouring (resolved in blue, unresolved in red)

Template variables: `$title$`, `$author$`, `$date$`, `$version$`, `$spdx-license$`, `$a2ml-format$`.

== Extensions Table

Both the reader and filter advertise extension flags:

[cols="1,3"]
|===
| Extension | Purpose

| `+smart`
| Typographic quotes (SmartyPants processing)

| `+includes`
| File inclusion via `@include` directives

| `+diagrams`
| Diagram rendering (Mermaid, Graphviz/Dot)

| `+validate`
| Structural validation (SPDX headers, cross-references)
|===

== Files

[cols="1,1,2"]
|===
| File | Lines | Purpose

| `a2ml.lua`
| ~360
| Combined reader (alternative to using reader + writer separately)

| `a2ml-reader.lua`
| 189
| Standalone reader: A2ML source to Pandoc AST

| `a2ml-writer.lua`
| 153
| Standalone writer: Pandoc AST to A2ML surface syntax

| `a2ml-filter.lua`
| 465
| Lua filter with 6 post-processing passes

| `a2ml.html`
| --
| HTML5 template with A2ML-specific CSS
|===

== Spec Compliance

This reader implements the A2ML v1.0.0 surface syntax as specified in
`SPEC-v1.0.adoc`. Test vectors in `tests/vectors/` validate correct output for all core
constructs. Media type: `application/vnd.a2ml` (IANA registration pending).

== Licensing

SPDX-License-Identifier: MPL-2.0

See link:LICENSE[LICENSE] for the full text.

== Part of the A2ML Ecosystem

This directory is part of the link:../README.adoc[A2ML specification and tooling] in the
https://github.com/hyperpolymath/standards[standards monorepo]. See the parent directory
for language bindings, the validation GitHub Action, editor integrations, and the CLI.
