pandoc-allium
Install
pip install pandoc-allium
This registers the pandoc-allium console script on PATH. You'll also
need the allium CLI itself and pandoc -- see Requirements
below. Then run pandoc with the filter:
pandoc -F pandoc-allium \
--syntax-definition "$(pandoc-allium --syntax-path)" \
-s examples/demo.md -o demo.html
A pandoc filter for the Allium specification language. For every fenced code block written as:
```allium
-- allium: 1
entity Widget {
id: Integer
status: idle | active
}
rule Activate {
when: w: Widget.status
requires: w.status = idle
ensures: w.status = active
}
```
the filter runs allium check against exactly that text and inserts a
diagnostics report right after the block. The original source is never
altered -- the filter only ever adds a block after it, so re-extracting
the code (or handing the doc to another tool) always gets byte-for-byte
what you wrote.
Syntax highlighting is handled separately and natively by pandoc's own
Skylighting engine via a
bundled Kate syntax definition -- no JavaScript required for that part. A
small Node package is also included for running allium check from a JS
toolchain (npm scripts, CI, a docs build) independent of pandoc.
Requirements
- pandoc (tested against the Homebrew build, 3.9.x)
- the
alliumCLI itself:brew install juxt/allium/allium(orcargo install allium-cli) -- see https://juxt.github.io/allium/installation - Python 3.9+ and pipenv, for the pandoc filter
- Node 22+ (cucumber-js requires it) and yarn, only
if you want the JS runner (nvm users:
cd js && nvm usepicks up the pinned version fromjs/.nvmrc)
Local LLM development (Apple Silicon only)
The repo includes an optional local LLM setup for offline, AI-assisted
coding via the pi agent
framework. It runs the
unsloth/Qwen3.6-27B-MLX-8bit
model entirely on-device using Apple's
MLX framework — no API keys or
network access required.
How it works
The Pipfile conditionally installs mlx-vlm on macOS (sys_platform == 'darwin'). This gives two just recipes:
just chat-qwen— starts an interactive chat session with the model viamlx_vlm.chat. Good for quick questions.just serve-qwen— starts an OpenAI-compatible HTTP server athttp://localhost:8080/v1viamlx_vlm.server. Leave this running in its own terminal; thepiagent connects to it as its provider.
The .pi/settings.json file tells pi to use the mlx-lm provider
pointing at unsloth/Qwen3.6-27B-MLX-8bit as the default model.
System prompt
.pi/SYSTEM.md replaces pi's default system prompt with a project-
specific brief. It covers:
- Tools — which capabilities the agent has (
read,bash,edit,write) and how to use them. - Working style — conventions like "read before you write," "verify with project commands," and "never alter the original fenced block."
- Project context — a summary of the codebase layout, module responsibilities, and repo-specific conventions.
- Commands — the
justrecipes the agent should use for testing and linting.
Edit .pi/SYSTEM.md to change the agent's behavior for this project.
Python filter (pipenv)
pipenv install --dev
This installs the package itself (editable) plus its one dependency,
panflute, and registers the
pandoc-allium console script inside the pipenv virtualenv. Run pandoc
through pipenv run so that script is on PATH (your system's Homebrew
pandoc is used as-is -- pipenv never shadows it):
pipenv run pandoc -F pandoc-allium \
--syntax-definition "$(pipenv run pandoc-allium --syntax-path)" \
-s examples/demo.md -o demo.html
--syntax-definition is optional but recommended: without it, allium
code blocks still get checked, they just render as plain unhighlighted
code. It works identically for HTML, LaTeX/PDF, docx, and every other
Skylighting-backed writer pandoc has. pandoc-allium --syntax-path prints
the syntax file's installed, absolute path, so this works the same way
whether you installed via pipenv, pip install pandoc-allium, or an
editable checkout.
Opting out per block
Add .no-check to a block's classes to keep it in a doc (e.g. to show a
deliberately-broken example) without ever invoking allium:
```{.allium .no-check}
this isn't valid allium and that's the point
```
Error handling
Nothing about a broken environment should take down the whole pandoc run.
pandoc_allium/allium_cli.py classifies everything that can go wrong into
a ToolError and the filter renders it as a normal diagnostics block
instead of crashing:
| situation | reported as |
|---|---|
allium not on PATH |
not_installed (with the install command as a fix-it hint) |
| spec takes longer than the timeout (15s default) | timeout |
| non-JSON or unexpected stdout shape | invalid_output |
| any other non-zero exit / stderr-only failure | runtime_error |
Set ALLIUM_BIN=/path/to/allium to point at a specific binary (also used
by the test suite to substitute a fake binary).
Tests
pipenv run pytest
JS runner (yarn)
js/ is a small, dependency-free Node package that wraps allium check
the same way allium_cli.py does, for use outside of pandoc (npm scripts,
CI, a docs pipeline):
cd js
yarn install
yarn test
As a library:
const { runCheck } = require('./js/src/run-allium');
const result = runCheck(specSourceText);
// result.error, or result.diagnostics: [{severity, message, line, col, code}, ...]
As a standalone CLI:
node js/bin/run-allium.js path/to/spec.allium
Exit codes match allium check itself: 0 clean, 1 one or more
diagnostics, 2 no input files or allium couldn't be run at all.
Feature tests (Cucumber)
yarn test runs the unit suite (test/) and then a
cucumber-js suite (features/)
that drives the actual bin/run-allium.js CLI end-to-end -- writing real
spec files to a temp dir and asserting on exit codes and stdout/stderr --
to read as a plain-language description of what this system guarantees
(a clean spec exits 0, an invalid one is reported as an error, a missing
allium install fails with a helpful hint, etc). Run just that suite with:
cd js
yarn test:features
Layout
pandoc_allium/
allium_cli.py subprocess wrapper around `allium check` (+ error classification)
render.py builds the diagnostics Div from a CheckResult
filter.py the panflute filter itself (entry point: pandoc-allium)
syntax/allium.xml Kate/Skylighting syntax definition for native highlighting
js/
src/run-allium.js Node port of allium_cli.py
bin/run-allium.js standalone CLI
test/ unit tests for src/run-allium.js
features/ cucumber-js feature tests driving bin/run-allium.js end-to-end
.pi/
settings.json pi agent config (default provider + model)
SYSTEM.md project-specific system prompt for the pi agent
tests/ pytest suite (fixtures/ holds raw .allium snippets)
examples/ demo.md, common-errors.md, workflow.md, multi-entity.md
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pandoc_allium-0.1.1.tar.gz.
File metadata
- Download URL: pandoc_allium-0.1.1.tar.gz
- Upload date:
- Size: 18.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4da888326da15cbf69cacb47884aee87cf806ed161202fb35f97e55f04d3b23a
|
|
| MD5 |
dab07cff59e4ed93cdf3ba07cdc7d667
|
|
| BLAKE2b-256 |
7eef0f3d4b0f6775ce57bffd78aea90e3567dc651fab549b65b40cfd7ae4929f
|
Provenance
The following attestation bundles were made for pandoc_allium-0.1.1.tar.gz:
Publisher:
publish.yml on iwillig/pandoc-allium
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pandoc_allium-0.1.1.tar.gz -
Subject digest:
4da888326da15cbf69cacb47884aee87cf806ed161202fb35f97e55f04d3b23a - Sigstore transparency entry: 2249122245
- Sigstore integration time:
-
Permalink:
iwillig/pandoc-allium@d757ec8e6b2763dbd4306ad0395c4903dc4d5ab9 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/iwillig
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d757ec8e6b2763dbd4306ad0395c4903dc4d5ab9 -
Trigger Event:
release
-
Statement type:
File details
Details for the file pandoc_allium-0.1.1-py3-none-any.whl.
File metadata
- Download URL: pandoc_allium-0.1.1-py3-none-any.whl
- Upload date:
- Size: 13.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
92af4d147008b0cc00e034593b9f57db02c62b97fa2627ad035bcebccebc62e3
|
|
| MD5 |
e5018fcfc454b2efc0465d932c2757ed
|
|
| BLAKE2b-256 |
c9fd83ca2f9fe560d2f07101603d8e78e0577fd9d2b2e1b97517a6b18956bba3
|
Provenance
The following attestation bundles were made for pandoc_allium-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on iwillig/pandoc-allium
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pandoc_allium-0.1.1-py3-none-any.whl -
Subject digest:
92af4d147008b0cc00e034593b9f57db02c62b97fa2627ad035bcebccebc62e3 - Sigstore transparency entry: 2249122622
- Sigstore integration time:
-
Permalink:
iwillig/pandoc-allium@d757ec8e6b2763dbd4306ad0395c4903dc4d5ab9 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/iwillig
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d757ec8e6b2763dbd4306ad0395c4903dc4d5ab9 -
Trigger Event:
release
-
Statement type: