Metadata-Version: 2.5
Name: open-processing-model
Version: 0.10.0
Summary: Convert TEI, Docbook or JATS XML to HTML, PDF, EPUB, Word and Markdown from the command line, using TEI ODD processing models
Project-URL: Homepage, https://opm.e-editiones.org/
Project-URL: Repository, https://github.com/eeditiones/open-processing-model
Project-URL: Issues, https://github.com/eeditiones/open-processing-model/issues
Project-URL: Changelog, https://github.com/eeditiones/open-processing-model/blob/main/CHANGELOG.md
Author-email: e-editiones <info@e-editiones.org>
License-Expression: AGPL-3.0-or-later
License-File: LICENSE
License-File: LICENSING.md
Keywords: cli,command-line,digital-editions,digital-humanities,docbook,docx,epub,jats,markdown,odd,pandoc,processing-model,publishing,python,static-site,tei,tei-to-html,tei-to-pdf,tei-xml,typst,word,xml,xslt
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP :: Site Management
Classifier: Topic :: Printing
Classifier: Topic :: Sociology :: History
Classifier: Topic :: Software Development :: Documentation
Classifier: Topic :: Text Processing :: Markup :: HTML
Classifier: Topic :: Text Processing :: Markup :: Markdown
Classifier: Topic :: Text Processing :: Markup :: XML
Classifier: Typing :: Typed
Requires-Python: >=3.12
Requires-Dist: elementpath>=4.8
Requires-Dist: jinja2>=3.1
Requires-Dist: lxml>=5.0
Requires-Dist: platformdirs>=4.10.0
Requires-Dist: pygments>=2.17
Requires-Dist: python-docx>=1.1
Requires-Dist: questionary>=2.1.1
Requires-Dist: rich-pyfiglet>=2.0.1
Requires-Dist: rich>=13.0
Requires-Dist: typer>=0.24.1
Description-Content-Type: text/markdown

<p align="center">
  <picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/eeditiones/open-processing-model/main/docs/assets/logo-wordmark-dark.svg"><img src="https://raw.githubusercontent.com/eeditiones/open-processing-model/main/docs/assets/logo-wordmark.svg" alt="opm — Open Processing Model" width="380"></picture>
</p>

# Open Processing Model

**Open Processing Model** (`opm`) converts TEI XML, and other XML such as DocBook or JATS, into HTML, PDF (via [Typst](https://typst.app/)), EPUB, Word, Markdown or JSON. It can also be used to transform a TEI edition into a static website, prepare the data for an external static site generator, or index documents for a search engine.

Instead of writing XSLT or XQuery, describe how each element should be presented in a **TEI ODD** document, and `opm` compiles it into a reusable Python module.

`opm` is an implementation of the [TEI Processing Model](https://tei-c.org/release/doc/tei-p5-doc/en/html/TD.html#TDPM) standard in Python. The TEI Processing Model was created to allow publishers, editors or scholars to transform documents without becoming programmers. Knowing XML, TEI and basic XPath is enough.
Instead of writing XSLT or XQuery, you describe in TEI how each element should be presented.

The design of `opm` follows the [`tei-publisher-lib`](https://github.com/eeditiones/tei-publisher-lib) implementation in [TEI Publisher](https://tei-publisher.org) and aims to be as compatible as possible, so ODDs can be shared between both. While `tei-publisher-lib` compiles the processing model instructions found in an ODD into XQuery code, `opm` outputs Python instead.

`opm` does not require a database, runs entirely on the command line, is very fast for batch processing and has very slim dependencies.

👉 **Documentation:** [Read the full documentation here.](https://opm.e-editiones.org)

## Quick start

Python ≥ 3.12. Install the package, then scaffold a project:

```bash
pip install open-processing-model
# or: uv add open-processing-model

opm init                          # asks: empty project, or one of the examples
# opm init --vocabulary docbook   # empty DocBook project, no prompt
# opm init --example jats         # copy of an example project

opm transform data/sample.xml --preview
opm chunk data/sample.xml --force
opm serve
opm odd document my.odd --force --preview         # ODD documentation site
```

A one-off transform needs no project files (`opm transform my.xml --preview`
uses the packaged stock ODD and templates). `opm init` writes editable
`opm.toml`, templates, CSS, and an ODD — or, with `--example`, copies one of the
example projects under [`examples/`](https://github.com/eeditiones/open-processing-model/tree/main/examples) (`--list-examples` shows them).

## Development

This repository uses [`uv`](https://docs.astral.sh/uv/). From a clone:

```bash
uv sync

uv run opm transform examples/tei-test.xml --preview
uv run opm transform examples/tei-test.xml -t web --preview
uv run opm chunk examples/tei-test.xml -o chunks/ --force
uv run opm serve -d chunks/

# Example projects (run from the example directory):
cd examples/serafin && uv run opm chunk data/letters/serafin01.xml --force --preview
cd examples/docbook && uv run opm chunk data/doc/quickstart.xml --force --preview
cd examples/jats && uv run opm chunk data/article/hertziana-digital-editions.xml --force --preview
cd examples/odd && uv run opm odd document --force --preview   # the TEI Guidelines
```

### `opm` without `uv run`

To get `opm` on your `PATH` while still running the working tree, install the
clone as an editable tool:

```bash
uv tool install --editable . --force
```

Code changes are picked up straight away — the tool venv links to `src/`, so
there is nothing to re-sync after an edit. **Dependency changes are not**: when
`[project] dependencies` in `pyproject.toml` gains an entry, run the same
command again, or the installed `opm` keeps the dependency set it was resolved
with and fails on the new import.

Note that `.venv/bin/opm` shadows the tool whenever the project venv is on
`PATH`; `which -a opm` shows which one you are about to run.

See [CONTRIBUTING.md](https://github.com/eeditiones/open-processing-model/blob/main/CONTRIBUTING.md) before opening a pull request — contributions
require a one-click [contributor license agreement](https://github.com/eeditiones/open-processing-model/blob/main/.github/CLA.md).

## Tests

```bash
uv sync --group dev
uv run --group dev pytest                            # all tests
uv run --group dev pytest tests/test_odd_compiler.py # single file
```

## Documentation

The docs site is built with [Zensical](https://zensical.org/) (successor to
Material for MkDocs, plus mkdocstrings). To preview locally:

```bash
uv sync --group docs
uv run python scripts/gen_cli_docs.py                # refresh CLI reference from the Typer app
uv run --group docs zensical serve                   # http://127.0.0.1:8000
uv run --group docs zensical build                   # static site into ./site
```

## Supporters

Development of `opm` is supported by:

<p align="center">
  <a href="https://www.ernst-goehner-stiftung.ch/"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/eeditiones/open-processing-model/main/docs/assets/EGS_Logo_Standard_RGB_white.svg"><img src="https://raw.githubusercontent.com/eeditiones/open-processing-model/main/docs/assets/EGS_Logo_Standard_RGB.svg" alt="Ernst Göhner Stiftung" height="44"></picture></a>
  &nbsp;&nbsp;&nbsp;&nbsp;
  <a href="https://www.sagw.ch/"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/eeditiones/open-processing-model/main/docs/assets/SAGW_Logo_addition_supported_pos_white.svg"><img src="https://raw.githubusercontent.com/eeditiones/open-processing-model/main/docs/assets/SAGW_Logo_addition_supported_pos.svg" alt="Swiss Academy of Humanities and Social Sciences" height="58"></picture></a>
  &nbsp;&nbsp;&nbsp;&nbsp;
  <a href="https://www.zb.uzh.ch/"><img src="https://raw.githubusercontent.com/eeditiones/open-processing-model/main/docs/assets/ZB_Logo_RGB_1024px.png" alt="Zentralbibliothek Zürich" height="54"></a>
</p>

<p align="center">
  <a href="https://theologie.unibas.ch/de/karl-barth-zentrum/"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/eeditiones/open-processing-model/main/docs/assets/karl-barth-white.png"><img src="https://raw.githubusercontent.com/eeditiones/open-processing-model/main/docs/assets/karl-barth.png" alt="Karl Barth-Stiftung" height="44"></picture></a>
  <br>
  <sub>Karl Barth-Stiftung, Universität Basel</sub>
</p>

<p align="center">
  <a href="https://www.zde.uzh.ch/"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/eeditiones/open-processing-model/main/docs/assets/uzh-logo-white.png"><img src="https://raw.githubusercontent.com/eeditiones/open-processing-model/main/docs/assets/uzh-logo-black.png" alt="Universität Zürich" height="44"></picture></a>
  <br>
  <sub>Zentrum Digitale Editionen &amp; Editionsanalytik, Universität Zürich</sub>
</p>

### An initiative of

<p>
  <a href="https://e-editiones.org/">
    <picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/eeditiones/open-processing-model/main/docs/assets/e-editiones-logo-white.svg"><img src="https://raw.githubusercontent.com/eeditiones/open-processing-model/main/docs/assets/e-editiones-logo-color.svg" alt="e-editiones" height="40"></picture>
  </a>
</p>

## License

Copyright © 2026 e-editiones. Licensed under the [GNU Affero General Public License,
version 3 or later](https://github.com/eeditiones/open-processing-model/blob/main/LICENSE), with [additional permissions](https://github.com/eeditiones/open-processing-model/blob/main/LICENSING.md).

The AGPL means that if you build on `opm` and offer it to others — including as a hosted
service — your users are entitled to the source. Members of
[e-editiones](https://www.e-editiones.org/) may instead use `opm` under the **LGPL**,
which lifts that obligation: see [LICENSING.md, Part B](https://github.com/eeditiones/open-processing-model/blob/main/LICENSING.md#part-b--member-licence-grant).
Membership funds the long-term maintenance of TEI Publisher and its tooling.

[LICENSING.md, Part A](https://github.com/eeditiones/open-processing-model/blob/main/LICENSING.md#part-a--additional-permissions) grants everyone additional permissions
under AGPL §7: invoking `opm` as a separate process leaves your program alone, transform
modules compiled from your ODDs are yours to license and to execute, so are XPath
extension modules, and the files `opm init` writes into your project are released under
CC0. Vendoring `opm`'s own source into your tree is the case those permissions do not
cover.

Documents you transform with `opm` are your own; the licence does not reach the output.
See [the licensing guide](https://github.com/eeditiones/open-processing-model/blob/main/docs/license.md) for where the line falls in practice.
