{
  "markdown": "<!--\nSPDX-FileCopyrightText: 2026 Jandira Technologies, LLC\n\nSPDX-License-Identifier: AGPL-3.0-only\n-->\n\n> **See every page side by side: [jandira-tech.github.io/neurotic_docx_bench](https://jandira-tech.github.io/neurotic_docx_bench/)**  \n> jubarte vs Microsoft Word, docxide-pdf, LibreOffice, PyMuPDF Pro, MiniPdf, rdocx and office2pdf on 808 documents, DOCX to PDF, scored per page.\n\n# jubarte\n\n**Word-faithful DOCX redlines and rendering, without Word.**\n\nCompare two Word documents into native tracked changes, inspect or resolve\nchanges programmatically, apply validated edit plans, and render DOCX to PDF\nor PNG — from Rust, Python, Node/browser, or the CLI.\n\n[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/15267/badge)](https://www.bestpractices.dev/projects/15267)\n[![CI](https://github.com/jandira-tech/jubarte-redlines/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/jandira-tech/jubarte-redlines/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/jandira-tech/jubarte-redlines/branch/main/graph/badge.svg)](https://codecov.io/gh/jandira-tech/jubarte-redlines)\n[![crates.io](https://img.shields.io/crates/v/jubarte-redlines.svg)](https://crates.io/crates/jubarte-redlines)\n[![docs.rs](https://docs.rs/jubarte-redlines/badge.svg)](https://docs.rs/jubarte-redlines)\n[![PyPI](https://img.shields.io/pypi/v/jubarte-redlines.svg)](https://pypi.org/project/jubarte-redlines/)\n[![npm](https://img.shields.io/npm/v/jubarte-wasm.svg)](https://www.npmjs.com/package/jubarte-wasm)\n[![MSRV](https://img.shields.io/badge/MSRV-1.94-blue)](./Cargo.toml)\n[![license](https://img.shields.io/badge/license-AGPL--3.0--only-blue.svg)](./LICENSE)\n[![Socket Badge](https://badge.socket.dev/cargo/package/jubarte-redlines/0.13.0)](https://badge.socket.dev/cargo/package/jubarte-redlines/0.13.0)\n\nJubarte is an in-process DOCX engine for applications that need Microsoft\nWord-style review workflows without automating Microsoft Word or LibreOffice.\n\n- **Compare DOCX → tracked DOCX** with native insertions, deletions, moves and\n  formatting changes.\n- **List, accept or reject changes** globally or selectively by change ID,\n  author and kind.\n- **Render DOCX → PDF / PNG** with an independent Word-oriented layout engine.\n- **Inspect and edit documents safely** using paragraph IDs, source hashes and\n  atomic JSON edit plans.\n- **Use the same core engine everywhere**: Rust, CLI, Python and WebAssembly\n  for Node/browser.\n- **Keep the original package**: relationships, styles, headers/footers,\n  notes, media and other DOCX parts are preserved by the comparison workflow.\n\n> Jubarte is not affiliated with Microsoft. “Word-faithful” describes\n> engineering targets measured against Microsoft Word behavior; it is not a\n> claim that every DOCX will render byte-for-byte or page-for-page identically.\n\n**Live benchmark, every page against Microsoft Word:\n[jandira-tech.github.io/neurotic_docx_bench](https://jandira-tech.github.io/neurotic_docx_bench/)**\n· tables: [neurotic_docx_bench RESULTS.md](https://github.com/jandira-tech/neurotic_docx_bench/blob/main/RESULTS.md)\n\n## Feedback and contributions\n\nReport bugs and request enhancements in the public\n[issue tracker](https://github.com/jandira-tech/jubarte-redlines/issues), which\nalso archives reports and responses. English reports are welcome. See\n[CONTRIBUTING.md](CONTRIBUTING.md) for pull requests, coding requirements,\nbuilding and tests, and [SECURITY.md](SECURITY.md) for private vulnerability\nreports. The [OpenSSF evidence review](docs/OPENSSF.md) tracks the criteria\nand outstanding maintainer attestations.\n\n## Quick start\n\nInstall the CLI:\n\n```sh\ncargo install jubarte-redlines\njubarte --version\n```\n\nPrebuilt archives are also published on\n[GitHub Releases](https://github.com/jandira-tech/jubarte-redlines/releases).\nCheck the assets attached to the release you intend to install.\n\n### Compare two Word documents\n\n```sh\njubarte original.docx modified.docx \\\n  -o redline.docx \\\n  --author \"Reviewer\"\n```\n\n`redline.docx` contains native Word tracked changes.\n\nWithout `-o`, jubarte prints the redline as the agent view and writes\nnothing; `-o redline.pdf` renders it instead.\n\n### Inspect and resolve tracked changes\n\n```sh\njubarte changes redline.docx          # one change per line (a replacement is one): r12, kind, target, author, paragraph, text\n\n# Resolve one specific change and leave the others tracked:\njubarte accept redline.docx \\\n  -o partially-accepted.docx \\\n  --id r12\n\n# Or resolve everything:\njubarte accept redline.docx -o final.docx\njubarte reject redline.docx -o original-state.docx\n```\n\nSelection flags can be repeated and combined:\n\n```sh\njubarte reject redline.docx \\\n  -o reviewed.docx \\\n  --author \"Reviewer A\" \\\n  --kind formatting\n```\n\n### Render DOCX to PDF or PNG\n\n```sh\n# PDF\njubarte convert redline.docx \\\n  -o redline.pdf \\\n  --revisions word \\\n  --compress\n\n# Page images: redline-page-01.png, redline-page-02.png, ...\njubarte convert redline.docx \\\n  -o redline.png \\\n  --dpi 120\n```\n\nNo Microsoft Word or LibreOffice process is launched.\n\n## How the workflow fits together\n\n```mermaid\nflowchart LR\n    A[original.docx] --> C[Compare]\n    B[modified.docx] --> C\n    C --> D[redline.docx]\n    D --> E[List changes]\n    E --> F[Accept / Reject]\n    F --> G[resolved.docx]\n\n    H[DOCX] --> I[Read]\n    I --> J[JSON edit plan]\n    J --> K[Edit]\n    K --> L[clean.docx]\n    K --> M[redline.docx]\n\n    D --> N[Render]\n    G --> N\n    L --> N\n    M --> N\n    N --> O[PDF / PNG]\n```\n\n## Documentation\n\nPer-surface guides, each ending in a **generated** reference (CLI help from\nthe real runner, API from the shipped module) that CI keeps drift-free —\n`scripts/gen_docs.sh` regenerates them:\n\n- [Rust guide](docs/rust.md) — crate features, API tour, rendering styles, `jubarte` CLI reference\n- [Python guide](docs/python.md) — wheel and `uvx`, the three library tiers, generated API reference\n- [Node and browser guide](docs/javascript.md) — `jubarte-wasm` and `npx jubarte-redlines`, entry points, generated API reference\n\nTopical documents: [Markdown pipeline](docs/MARKDOWN.md) ·\n[Word differences](docs/WORD_DIFFERENCES.md) ·\n[Word layout rules](docs/WORD_LAYOUT_RULES.md) ·\n[comment balloons](docs/WORD_COMMENT_BALLOONS.md) ·\n[self-update](docs/SELF_UPDATE.md) ·\n[benchmark classes](docs/bench_classes.md) ·\n[per-release API snapshots](docs/api/README.md).\n\n## Install\n\n### CLI\n\n```sh\ncargo install jubarte-redlines\n```\n\nThe installed binary is named `jubarte`.\n\nFrom 0.11.0, the Python wheel and the npm package also run the CLI\nwithout an install:\n\n```sh\nuvx jubarte-redlines redline a.docx b.docx -o redline.docx\nnpx jubarte-redlines redline a.docx b.docx -o redline.docx\n```\n\nBoth runners speak the shared command set — `compare`/`redline`, `diff`,\n`changes`, `accept`, `reject`, `read`, `edit`, `add`,\n`convert`, `capabilities` — and share the Rust clap parser for help,\ndefaults, aliases and usage errors. The Python wheel also runs `comments`,\n`validate` and `visual-diff`; `append`, `scrub`, `debug` and `self-update`\nremain in the binary. The npm CLI renders no PNG pages\n([`jubarte-wasm/cli/README.md`](jubarte-wasm/cli/README.md)).\n\nFor a GitHub-style text review of two Word documents:\n\n```sh\njubarte diff a.docx b.docx --format github\njubarte diff a.docx b.docx --format github --context 5 -o changes.patch\nuvx jubarte-redlines diff a.docx b.docx --format github\nnpx jubarte-redlines diff a.docx b.docx --format github\n```\n\n`github` (also `unified` or `text`) prints a standard unified patch with\n`diff --git`, file headers, hunk ranges and context. It compares the complete\n`debug -c text` view, including existing revision marks and story text in\nheaders, footers, notes, comments, tables and text boxes. It extracts all content before display clipping and never caps the number of changes, and does not create an implicit\nDOCX. Header/footer part renumbering is paired by section role. This is a\npatch of extracted **text**, for review; it cannot patch a binary DOCX.\nFormatting and media differences belong to `compare`, `debug` or `visual-diff`.\n\nCriticMarkup keeps its existing role: representing a document's current\ncontent with its tracked marks and comments. `github` gives a separate\ncomparison of those contents; it does not accept, reject or reinterpret the\nmarks unless `--accept-changes` is requested. `--format word` always accepts\nALL changes in both inputs first, then produces fresh word-level CriticMarkup.\n`normal`, `context` and `side-by-side` are also available. Long lines show a\n70-character window around the first change; `--full-lines` shows everything.\nSee [text diff details](docs/TEXT_DIFF.md).\n\nMarkdown sits beside Word: `jubarte diff` prints the changes between any\ntwo documents, Word or Markdown, as a git-style patch; `jubarte convert\ndraft.md` writes CommonMark (with CriticMarkup as tracked changes) to\nDOCX/PDF/PNG; and `jubarte edit` writes the redline's patch as\n`patch.diff`. See [`docs/MARKDOWN.md`](docs/MARKDOWN.md).\n\nFor a source checkout, the repository also contains installation scripts that\ncan install supplemental fonts used by the renderer:\n\n```sh\nscripts/install.sh\nscripts/install.sh --fonts-only\n```\n\nOn Windows, see `scripts/install.ps1`.\n\n### Rust library\n\n```sh\ncargo add jubarte-redlines --no-default-features\n```\n\nThe package is called `jubarte-redlines`; the Rust library import path is\n`jubarte`.\n\n```rust\nuse jubarte::{convert, document_comparer};\n\nfn main() -> Result<(), Box<dyn std::error::Error>> {\n    let original = std::fs::read(\"original.docx\")?;\n    let modified = std::fs::read(\"modified.docx\")?;\n\n    let redline =\n        document_comparer::compare_documents(&original, &modified, \"Reviewer\")?;\n    std::fs::write(\"redline.docx\", &redline)?;\n\n    let pdf = convert::docx_to_pdf(&redline)?;\n    std::fs::write(\"redline.pdf\", &pdf)?;\n\n    Ok(())\n}\n```\n\nThe default crate features include the CLI, fast allocator and self-update\nsupport. Library-only consumers can disable defaults and opt into features\ndeliberately.\n\nMSRV: **Rust 1.94**.\n\n### Python\n\nPython requires CPython 3.10 or later.\n\n```sh\npip install jubarte-redlines\n```\n\nLow-level byte API:\n\n```python\nfrom pathlib import Path\nfrom jubarte_redlines import (\n    compare_documents,\n    get_revisions,\n    docx_to_pdf,\n)\n\noriginal = Path(\"original.docx\").read_bytes()\nmodified = Path(\"modified.docx\").read_bytes()\n\nredline = compare_documents(\n    original,\n    modified,\n    author=\"Reviewer\",\n)\nPath(\"redline.docx\").write_bytes(redline)\n\nfor revision in get_revisions(redline):\n    print(revision)\n\nPath(\"redline.pdf\").write_bytes(\n    docx_to_pdf(redline, revisions=\"word\")\n)\n```\n\nThe richer `Document` API additionally supports inspection, Markdown\nprojection, selective change resolution, edit plans, PDF/PNG rendering and\npreview.\n\n### Node and browser\n\nNode 18+:\n\n```sh\nnpm install jubarte-wasm\n```\n\n```js\nconst {\n  compareDocuments,\n  docxToPdf,\n  listChanges,\n  acceptChanges,\n  rejectChanges,\n} = require(\"jubarte-wasm\");\n\nconst redline = compareDocuments(originalBytes, modifiedBytes, \"Reviewer\");\nconst pdf = docxToPdf(redline, false, \"word\");\n```\n\nFor applications that do not need the PDF renderer, use the slim package\nexports:\n\n```js\nconst {\n  compareDocuments\n} = require(\"jubarte-wasm/slim\");\n```\n\nBrowser builds are exported from `jubarte-wasm/web` and\n`jubarte-wasm/web-slim`.\n\n### MCP server\n\n`jubarte-mcp` exposes the engine as MCP tools (read, edit as tracked\nchanges, render, compare, accept and reject) to coding agents. Every path\nstays under `--root`.\n\n| Host | Install |\n| --- | --- |\n| Claude Code | `claude mcp add --transport stdio jubarte --scope project -- uvx --from 'jubarte-redlines[mcp]' jubarte-mcp --root .` |\n| Codex | `codex mcp add jubarte -- uvx --from 'jubarte-redlines[mcp]' jubarte-mcp --root .` |\n| Gemini CLI | `gemini extensions install https://github.com/jandira-tech/jubarte-redlines` |\n\nTools, security model and config files: [docs/adoption/mcp.md](docs/adoption/mcp.md).\n\n## CLI reference\n\nEvery command, from `jubarte --help` (regenerated by `scripts/gen_docs.sh`).\nThe complete per-command `--help` of every runner (the `jubarte` binary, the\nPython wheel, the npm CLI) is in the [per-surface guides](#documentation).\n\n<!-- gen:cli-summary:start -->\n| Command | What it does |\n|---|---|\n| `jubarte ORIGINAL MODIFIED` | Read, edit, compare and render Word documents |\n| `jubarte compare` | Compare documents: print the redline as the agent view, or write it with -o [alias: redline] |\n| `jubarte changes` | List tracked changes with IDs for accept, reject and edit plans |\n| `jubarte accept` | Accept all tracked changes, or select by ID, author or kind |\n| `jubarte reject` | Reject all tracked changes, or select by ID, author or kind |\n| `jubarte convert` | Convert Word or Markdown to DOCX, PDF, PNG or Markdown |\n| `jubarte diff` | Review differences as GitHub, word, normal, context or side-by-side text |\n| `jubarte read` | Read the agent view: YAML header, `<!-- pN -->` id lines, changes and comments with ids |\n| `jubarte edit` | Edit a document: -p WHERE with --anchor, --content, --delete, --resolve, --reply, --accept, --reject, --strike, --restore or --style (several -p per command), or a JSON plan. Writes FILE_modified.docx (--out-dir: the bundle), then prints SUCCESS and a fenced before/after diff of the full agent views (refusal: exit 3) |\n| `jubarte add` | Add a paragraph, a comment or a reply: -p WHERE --content TEXT (several -p per command). Writes FILE_modified.docx, as edit does, and prints SUCCESS and a fenced before/after diff of the full agent views |\n| `jubarte capabilities` | What this binary can do, for agents choosing an operation |\n| `jubarte visual-diff` | Compare rendered pages pixel by pixel (different pages: exit 5) |\n| `jubarte comments` | List comments, threads and the text they annotate |\n| `jubarte append` | Join documents in order, preserving images, styles, lists and notes |\n| `jubarte validate` | Check Word validity, tracked edits, accessibility, style and structure; or repair Word validity |\n| `jubarte check` | Check a document against a source-bound expectation contract |\n| `jubarte scrub` | Remove authors, editing IDs, metadata and comments before sharing |\n| `jubarte self-update` | Check or install a release from GitHub |\n<!-- gen:cli-summary:end -->\n\n### Compare\n\n```text\njubarte ORIGINAL MODIFIED [OPTIONS]\n```\n\nWithout `-o`, `jubarte A B` (or `jubarte compare A B`) prints the redline\nas the agent view (the `read` options apply) and writes nothing. With `-o`,\nthe extension picks what is written:\n\n| `-o` | Writes |\n|---|---|\n| `.docx` (or no or an unknown extension) | the redline |\n| `.md`, `.markdown`, `.txt` | the agent view of the redline; CriticMarkup when both inputs are Markdown |\n| `.pdf` | the redline, rendered (`--revisions`, `--pages`, `--changed-pages` apply) |\n| `.png` | one `STEM-page-NN.png` per page |\n| `.json` | the snapshot of the redline, as `read --json` prints it |\n\n`jubarte FILE` alone is `jubarte read FILE`; a lone name without an\nextension is taken for a mistyped task, so read such a file with\n`jubarte read FILE`.\n\nCommon options:\n\n| Option | Purpose |\n|---|---|\n| `-b, --original FILE` | Original document |\n| `-m, --modified FILE` | Modified document |\n| `-o, --output FILE` | Write the redline; the extension picks the format (above) |\n| `-a, --author NAME` | Revision author (default: `Redline`) |\n| `-d, --datetime ISO8601` | Revision timestamp (default: now, UTC) |\n| `--detail-threshold RATIO` | Comparison-detail tuning |\n| `--mode word|powertools` | Word-oriented or classic PowerTools comparison behavior |\n| `--force` | Replace an existing output |\n| `--reference-doc FILE`, `--critic`, `--resource-path DIR` | Markdown inputs |\n| `--revisions`, `--dpi`, `--pages`, `--changed-pages` | Rendering, for `-o FILE.pdf` or `.png` |\n| `-q, --quiet` | No status lines on success; a reading task still prints what it read |\n\nThe command line dates the revisions now; pin `-d 1970-01-01T00:00:00Z` for\nbyte-identical output from identical inputs. The library calls keep the\nepoch as their default, so they stay deterministic.\n\n### List tracked changes\n\n```sh\njubarte changes FILE.docx\njubarte changes FILE.docx --json\n```\n\n`changes` is intended for individually addressable review operations and\nreports stable IDs while the corresponding tracked change remains present.\nThe text listing prints short ids (`r12`, `header1.r1`, `footnotes.r3`);\n`--json` prints JSON Lines with the same short `id` (and `ref`). `--id`\ntakes the short ids: `r12`, `r1+2` (both marks of one\nchange), `header1.r1`. A change that holds a comment's reference mark ends\nits line with `holds comment c4's mark` (`holds comment marks c4, c5` for a\nthread's reply too), and `--json` lists them in `holds_comments`: resolving\nthe change so its content goes (accepting a deletion, rejecting an\ninsertion) removes those threads, as Word does. The `read` view says so on\nthe note: `{>>c4 @AC in r13: …<<}` when the note prints outside r13.\n\n\nWith human-readable CLI output, every command that writes a DOCX from a\ndocument prints a confirmation after publication (unless `-q`):\n\n````text\nSUCCESS:\n~~~~diff\n--- before in.docx\n+++ after out.docx\n@@ -1,3 +1,3 @@\n ---\n-source: in.docx\n+source: out.docx\n sha256: …\n~~~~\n````\n\nThe diff compares the full input and output agent views, including `source:`\nand `sha256:`. It uses three context lines; the output view comes from the\npublished bytes. Markdown conversion uses the original Markdown text as its\nbefore-view; comparison uses its first input. Identical views print\n`no differences` inside the fence. The fence grows past any leading tilde\nrun in the diff. Edit's former changed-range view and resolved-lines output\nare replaced by this block; an existing bundle summary stays before it,\nwith one block per DOCX. The `wrote …` lines and notes remain on stderr.\n`-q` silences the block, summary and status; warnings and errors still print.\nDry runs, saved plans and non-DOCX outputs retain their existing output.\nTemplate generation writes a JSON plan; applying it writes the DOCX.\nTyped `--json`/`--jsonl` delivery retains its machine-readable receipt.\n\n### Accept or reject\n\n```sh\njubarte accept FILE.docx -o OUTPUT.docx\njubarte reject FILE.docx -o OUTPUT.docx\n```\n\nOptional selection filters:\n\n```text\n--id ID          r12, r1+2, header1.r1\n--author NAME\n--kind insertion|deletion|move|formatting\n```\n\nFilters are repeatable. Categories combine, so a change must satisfy each\ncategory you supplied. `jubarte edit FILE -p r12 --accept` (or `--reject`)\nresolves one change and writes `FILE_modified.docx`.\n\nAdd `--keep-nested-comment` to `accept` or `reject` to preserve a comment\nand its replies when settlement removes their whole anchor. Their markers\nmove together to an empty, untracked anchor where the removed text was;\nthe command reports, for example, `kept c0 and its reply c1 on an empty anchor\nin p1`. Partial overlaps keep the existing behavior. The default removes\nwholly removed threads, as Word does.\n\n### Convert to PDF / PNG\n\n```sh\njubarte convert FILE.docx [OPTIONS]\n```\n\n| Option | Purpose |\n|---|---|\n| `-o, --output FILE` | Output path; the extension picks the format: `.docx`, `.md`, `.pdf`, `.png` (pages named `STEM-page-NN.png`) or `.json` (the snapshot) |\n| `--dpi DPI` | PNG resolution; default 96 |\n| `--compress` | Deflate PDF content streams |\n| `--revisions conventional|word|custom` | Tracked-change visualization |\n| `--keep-nested-comment` | With `--track-changes accept` or `reject`, keep comment threads whose whole anchor is removed, on an empty anchor; off by default |\n| `--revision-palette SPEC` | Custom change colors/lines |\n| `--font-report FILE` | Write font-resolution JSON |\n| `--report FILE` | Write page/render report |\n| `--force` | Replace existing output |\n| `--fail-on-substitution` | Exit 4 when a requested font was substituted |\n| `--pages SPEC` | Only these pages, for example `1-3,7`, in the PDF and the PNGs alike; PNGs keep the document's page numbers |\n| `--move-comments` | List comments after the last page; the text keeps its tint and a `[JR1]` marker |\n| `--changed-pages` | Keep only the pages a change touches: a body or note revision, a comment anchor, or the first page a revised header or footer paints on (page numbers stay the document's) |\n| `-f, --from` / `-t, --to` | `docx`, `md`, `pdf`, `png` or `json`, when `-o` has no extension: Markdown in (CriticMarkup becomes tracked changes) or out ([`docs/MARKDOWN.md`](docs/MARKDOWN.md)) |\n\nWithout `-o`, a `.docx` becomes `STEM.pdf` beside it and Markdown becomes\n`STEM.docx`; `-t md` prints to stdout.\n\nMarkdown to Word: a change or comment that names no author or date (by its\ntag or the `authors:` table) takes `-a, --author` and `-d, --datetime`,\nelse the front matter's `author:` and `last_modified:` (else `modified:`,\n`date:`, `created:`), else the `--reference-doc`'s `dc:creator` and\n`dcterms:created`, else `Redline` and now. Pin `-d 1970-01-01T00:00:00Z`\nfor byte-identical output; the library calls keep `Redline` and that\nepoch as their default and read no reference document's metadata.\n`compare`, `edit`, `add` and `diff` never take the files' metadata: their\nchanges carry `--author` and `--datetime` (default `Redline` and now).\n\nExamples:\n\n```sh\njubarte convert contract.docx\njubarte convert redline.docx --revisions word\njubarte convert redline.docx -o pages.png --dpi 144\njubarte convert long.docx -o excerpt.pdf --pages 1-3,7\njubarte convert redline.docx -o changed.pdf --changed-pages\njubarte convert contract.docx --compress --font-report fonts.json\n```\n\nA document with comments gets Word's markup pane: each comment in a\nballoon beside its range, joined to it by a dotted connector, with the\nrange tinted and bracketed. As Word does, no style writes a PDF comment\nannotation: a viewer would paint it as a note icon over the text\n([`docs/WORD_DIFFERENCES.md`](docs/WORD_DIFFERENCES.md)).\n\nA custom palette can be supplied with:\n\n```sh\njubarte convert redline.docx \\\n  --revisions custom \\\n  --revision-palette \\\n  \"deleted=#AA0000:strike,inserted=#0055FF:double-underline\"\n```\n\n### Read a document\n\n```sh\njubarte read contract.docx               # the agent view\njubarte read contract.docx --json        # the snapshot: paragraphs, runs, tables, changes, comments\njubarte read contract.docx --tables      # top-level tN grids, with nested cell paths\njubarte read contract.docx --tables -p t0 # t0 and its nested tables: grid, then view\njubarte read contract.docx -p p12,p40-p48 -o excerpt.md\n```\n\n`read` prints the agent view: a YAML header (`sha256:` of the file, the\nrevision and comment counts, authors and their handles, page setup,\nstyles, headers, footers), then Markdown with an id line before every\nparagraph (`p12`, the body's paragraph 12) and an id on every\ntracked change and comment (`r3+4` is the two marks with `w:id` 3 and 4, `c5`\nis comment 5, `header1.r1` a change in a header). A table cell's paragraph is\n`t0.row1.cell2`, a footnote's `footnotes.p0`, and `c5.text` the text comment\n5 covers. No id needs quoting in bash, zsh or csh.\n\n`--json` prints the snapshot instead: document metadata, story and\nparagraph coordinates, `source_sha256`, runs, structural limitations,\ntables, content controls, and the changes and comments with their short\n`ref`. The selection flags (`-p`, `--head`, `--tail`, `--changed`, `--by`)\nnarrow it as they narrow the view. `-o FILE.md` or `-o FILE.json` writes\neither to a file.\n\nThe snapshot uses `schema_version: 3`. `changes` lists logical changes:\na change Word wrote as several marks is one entry with its `members`,\nand a deletion followed by its author's insertion is one `replacement`.\n`summary.tables` and `tables[]`\ncount top-level body tables only; each `index` is the view's `tN`.\nEvery table has a `nested` array (empty for a leaf), containing its cell tables.\nA nested entry has `parent` (for example `t0.row2.cell0`) and no `index`.\nA deeper parent includes the cell-local table ordinal, for example\n`t0.row2.cell0.t0.row0.cell1`. Paragraph ids and edit-plan schemas are unchanged.\n\n`--tables` numbers only top-level tables as `table N`, matching `tN` in\nthe view and `-p tN`. Nested tables follow their containing cell row,\nindented two spaces per nesting level and labelled `nested in CELL_PATH`.\nFor example, `nested in t0.row2.cell0`; a further level uses\n`t0.row2.cell0.t0.row0.cell1`. `--tables -p t0` includes this whole tree.\n\n```text\n<!-- p0 center -->\n# Consulting Agreement\n\n<!-- p1 justify -->\nThis Consulting Agreement (the “Agreement”) is made between Harbor Point Analytics LLC (\"Consultant\") and Juniper Freight Co. (\"Client\").\n\n<!-- p2 -->\n## 1. Services\n\n<!-- p3 -->\nConsultant will deliver the services in each Statement of Work, including {++quarterly++}{r0 @AC} route-cost reports and a {~~weekly~>monthly~~}{r1+2 @AC} review call.\n```\n\nAttribution uses braces after the change closer: `{++new++}{r1 @AL}`.\n`{>>c5 @AC: note<<}` remains a comment. A deletion inside another author's\ninsertion names its parent with `{r3 @BO re r1 @AL}`. Distinct revision ids\nstay separate; only a deletion directly followed in the rendered stream by\na live insertion from the same author forms `{~~old~>new~~}{r4+5 @AL}`.\nDifferent inline dates keep the two marks separate. An inserted paragraph\nmark is `¶{r7 @AL}`. To write literal attribution-shaped text after a closer,\nescape the opening brace: `{++new++}\\{r1 @AL}`; write literal `¶\\{` likewise.\n\nSee [docs/MARKDOWN.md](docs/MARKDOWN.md#agent-view) for the grammar.\n\n### Validate\n\n```sh\njubarte validate contract.docx\njubarte validate contract.docx --json\njubarte validate contract.docx --repair fixed.docx\njubarte validate review/redline.docx --original contract.docx --author Claude\n```\n\n`validate` lists what makes Word refuse or repair a file, beyond what an\nXSD sees: one line per finding (`code`, `part#path`, message, a `*` when\nit is Word-fatal), or one JSON object each with `--json`. `--repair` writes\na copy with every repairable finding fixed and lists what remains;\n`--original` with `--author` audits that every text change against the\noriginal is a revision by that author (`UNTRACKED_EDIT`, `FOREIGN_AUTHOR`).\nThe `edits` rules also report permission endpoints lost from any part\n(`PERMISSION_RANGE_DROPPED`); losing an editable region is not Word-invalid.\n`--rules a11y,style,structure` adds accessibility, style and structure\nfindings (heading skips, images without alt text, tables without a header\nrow, literal bullets, stale caches), each located by paragraph id;\n`--rules` also takes single rule codes.\n\n`NESTED_SAME_REVISION` is non-fatal: direct same-kind nesting is `info`\n(Word opens and reads it faithfully); alternating nesting such as\n`ins > del > ins` is a `warning` because Word opens it but misreads\nreject-all (#1134, Word probes 2026-10-17).\n\n`NESTED_TEXT_BOX` is a Word-fatal Ring-1 error: a DrawingML or VML text box\ninside another box's readable content prevents Word from opening the file\n(#1132, Word probes 2026-10-18). The check covers every story part and ignores\nnesting only in `mc:Fallback`; `--repair` leaves it unchanged.\n\nAny `word` or `edits` finding exits 2, and so does any `error`; `--strict`\nfails on warnings too. A file that cannot be read exits 1.\n\n| Option | Purpose |\n|---|---|\n| `--json` | JSON Lines: one object per finding, nothing when there is none |\n| `--rules SETS` | `word` (the default), `edits`, `a11y`, `style`, `structure`, or rule codes, comma-separated |\n| `--strict` | Fail on warnings too |\n| `--repair FILE` | Write the repaired package; remaining findings still exit 2 |\n| `--original FILE` | Audit tracked edits against this original (needs `--author`) |\n| `--author NAME` | The author every change must carry |\n| `--force` | Replace an existing `--repair` output |\n\n`jubarte audit FILE` still runs, as `validate --rules a11y,style,structure`\nwith a note; it is removed in 0.14.\n\n### Scrub\n\n```sh\njubarte scrub contract.docx -o outgoing.docx\njubarte scrub contract.docx -o outgoing.docx --rsids --docprops\n```\n\nRemoves who touched a document before it goes out: author names (as one\nalias, `--author-alias NAME`), rsids, the people and dates in the document\nproperties, and comments. Text and tracked changes stay. Without a flag all\nfour go, under the alias \"Author\"; with flags, only those given.\n\n### Append documents\n\n```sh\njubarte append a.docx b.docx c.docx -o combined.docx\njubarte append a.docx b.docx -o combined.docx --section-break continuous --keep-sections\n```\n\nB after A, then C after that, carrying images, links, styles, lists and\nnotes. Comments are dropped with a warning unless `--carry-comments`.\n`--section-break` is `next-page` (the default), `continuous` or `none`;\n`--keep-sections` keeps each document's page setup, headers and footers.\n\n### Comments\n\n```sh\njubarte comments contract.docx\njubarte comments contract.docx --json --author \"Reviewer\" --latest\n```\n\nEvery comment with its thread (`parent`, `done`) and the text it is\nanchored to. Edit plans reply to, resolve, edit and delete comments (see\nthe operation table below).\n\n### Fields\n\n```sh\njubarte convert contract.docx -o updated.docx --update-fields --report fields.json\n```\n\n`--update-fields` refreshes the cached results of `PAGEREF`, `REF`, `NUMPAGES`, `SEQ` and\n`TOC` fields from jubarte's layout; TOCs are rebuilt from the headings. Field\ncodes stay, so Word can update them again. Page numbers are jubarte's layout,\nnot Word's ([`docs/WORD_DIFFERENCES.md`](docs/WORD_DIFFERENCES.md)). It\nruns after `--track-changes accept|reject`; `--report` lists the fields\nwritten with their old and new results.\n\n### Compare rendered pages\n\n```sh\njubarte visual-diff before.docx after.docx\njubarte visual-diff before.docx after.docx --out-dir pages --dpi 150 --json\n```\n\nLays out and rasterizes both documents at one resolution and compares them\npixel for pixel. Exit 0 when every page is the same, 5 when any page\ndiffers; `--out-dir` writes the changed pages, overlays and `diff.json`.\n\n### Apply an edit plan\n\nFirst read the source:\n\n```sh\njubarte read contract.docx -o contract.json\n```\n\nCreate `plan.json`:\n\n```json\n{\n  \"schema_version\": 1,\n  \"source_sha256\": \"<the sha256: line of jubarte read>\",\n  \"author\": \"Reviewer\",\n  \"operations\": [\n    {\n      \"id\": \"term\",\n      \"kind\": \"replace\",\n      \"paragraph\": \"p12\",\n      \"find\": \"two years\",\n      \"replacement\": \"three years\"\n    }\n  ]\n}\n```\n\nOr record it from flags, one command at a time. Nothing is edited until\nthe plan runs:\n\n```sh\njubarte edit contract.docx --plan plan.json -p p12 --anchor \"two years\" --content \"three years\"\njubarte add contract.docx --plan plan.json -p p14 --comment --content \"Why three?\"\n```\n\nEach recording is checked against `contract.docx` and pins its\n`source_sha256`; one that does not apply leaves `plan.json` as it was.\n`--consume` deletes the plan once it has been applied.\n\nPreview it:\n\n```sh\njubarte edit contract.docx \\\n  --plan plan.json \\\n  --out-dir review \\\n  --dry-run\n```\n\nApply and render:\n\n```sh\njubarte edit contract.docx \\\n  --plan plan.json \\\n  --out-dir review \\\n  --pdf \\\n  --png \\\n  --dpi 100\n```\n\nA successful edit can produce:\n\n```text\nreview/\n  clean.docx\n  redline.docx\n  patch.diff\n  report.jsonl\n  clean.pdf\n  redline.pdf\n  clean-page-01.png\n  redline-page-01.png\n  ...\n```\n\nOperation kinds (`jubarte capabilities` lists the ones the installed build\nsupports):\n\n| Kind | What it does |\n|---|---|\n| `replace` | Replace `find` with `replacement` in one paragraph; only the words that differ are written, so kept words keep their formatting and characters (a curly quote or a non-breaking space stays where the replacement has the plain one); optional `format` for the new text, `\"whole\": true` for one deletion then one insertion as typed |\n| `insert` | Insert text `after` or `before` a match, or at `position` `start`/`end` |\n| `delete` | Delete a match |\n| `rewrite` | Give a paragraph's whole new text; only the words that differ are edited |\n| `format_run` | Restyle existing text as a tracked formatting change |\n| `comment` | Comment on a match, a whole paragraph, or every paragraph up to `through` |\n| `reply_comment`, `resolve_comment`, `edit_comment`, `delete_comment` | Work on a comment thread by `comment_id`; `edit_comment` on another author's comment needs `\"rewrite_others_comments\": true` (it keeps their name) |\n| `strike` | Reject another author's insertion `revision` visibly: your tracked deletion inside it, with an optional `comment` on the struck words |\n| `restore` | Reject another author's deletion `revision` visibly: your tracked copy of its words right after it, with an optional `comment` |\n| `insert_paragraph` | A new paragraph after the anchor, with its properties (or those `like` selects) |\n| `delete_paragraph` | Delete a paragraph, optionally commenting on the deleted text |\n| `format_paragraph` | Style, alignment, line spacing, space before and after, as a tracked property change |\n| `merge_paragraphs` | Join the next paragraph onto this one |\n| `insert_table` | A table before or after a body paragraph, tracked as inserted rows |\n| `list` | Bulleted, numbered or lettered list, tracked as property changes |\n| `insert_footnote` | A footnote after an anchor |\n| `insert_image` | A picture paragraph (PNG, JPEG, GIF, BMP or TIFF) |\n| `insert_toc` | A table of contents field; with `\"update_fields\": true` it is filled from the headings |\n| `page_setup` | Page size, orientation and margins |\n| `watermark` | Word's diagonal text watermark in every default header (untracked) |\n| `fill_control` | Fill a content control (text, choice, checkbox or date) by id, tag or alias |\n| `redact` | Replace text with `█` blocks in both copies, untracked; refused if the text still occurs anywhere. No report, refusal or confirmation repeats the text or the document's copy of it: a plan with a redaction confirms with the published view, not the before/after diff |\n| `settings` | `trackRevisions`, `updateFields` and document protection in `word/settings.xml` |\n\nPlans are atomic: stale sources, ambiguous anchors, overlapping edits or\nunsupported structures refuse the plan instead of making a guessed edit.\n\nSee\n[`skills/jubarte-documents/SKILL.md`](skills/jubarte-documents/SKILL.md)\nand\n[`examples/agents/acme-letter`](examples/agents/acme-letter)\nfor the full plan schema and a complete example.\n\n### Capabilities\n\n```sh\njubarte capabilities          # one line per capability\njubarte capabilities --json   # the manifest: formats, ids, validate rules, operation kinds\n```\n\nUse this when an application or agent needs to discover the exact surface\nsupported by the installed build.\n\n### Self-update\n\n```sh\njubarte self-update --check\njubarte self-update\n```\n\nOptional:\n\n```text\n-y, --yes\n--version VERSION\n```\n\nSee [`docs/SELF_UPDATE.md`](docs/SELF_UPDATE.md).\n\n### Debugging DOCX behavior\n\n```sh\njubarte debug FILE.docx --list\njubarte debug FILE.docx --check render\njubarte debug FILE.docx -c text\njubarte debug FILE.docx -c runs\njubarte debug FILE.docx -c xml\n\njubarte debug diff A.docx B.docx\njubarte debug diff A.docx B.docx C.docx --full\n```\n\n`debug` is hidden from `jubarte --help`: it is a diagnostic tool for\nengine work, not part of the stable surface. Debug catalogs cover package structure, fields, bookmarks, IDs, styles,\ntext boxes, revision changes, numbering, normalized XML/text/runs and render\ninformation.\n\nUse `jubarte <command> --help` for the authoritative option list for the\ninstalled release.\n\n## Rendering and fonts\n\nThe PDF engine reconstructs Word-oriented layout directly; it does not call\nMicrosoft Word or LibreOffice.\n\nThe documented rendering surface includes:\n\n- tracked changes, and comments as Word's balloons in the markup pane\n  (a resolved comment faded, a reply numbered under its thread);\n- paragraph/run formatting and advanced line layout;\n- CJK and RTL/complex-script text;\n- installed and embedded fonts;\n- merged, vertically merged, autofit and floating tables;\n- DrawingML/VML graphics, text boxes, charts and SmartArt;\n- raster and EMF/WMF images;\n- headers, footers and floating frames;\n- sections, columns, backgrounds and page borders;\n- footnotes and selected fields.\n\nRendering fidelity still depends on fonts and on document features.\nWebAssembly has no installed fonts: `docxToPdf` paints with the fonts a\ndocument embeds and the bundled Carlito and Liberation faces, so Chinese,\nJapanese or Korean text without an embedded font is not painted (see\n[`KNOWN_ISSUES.md`](KNOWN_ISSUES.md), item 9).\n\nSupplemental font lookup can be configured with:\n\n```sh\nexport JUBARTE_FONT_DIR=/path/to/jubarte/fonts\nexport JUBARTE_FONT_INDEX=/path/to/font-index.tsv\n```\n\nSet:\n\n```sh\nexport JUBARTE_FONT_INDEX=off\n```\n\nto disable the persistent font index.\n\nDefault per-user font directories are documented in the installation section\nof this repository.\n\nFor known Word-layout differences, see:\n\n- [`docs/WORD_LAYOUT_RULES.md`](docs/WORD_LAYOUT_RULES.md)\n- [`docs/WORD_DIFFERENCES.md`](docs/WORD_DIFFERENCES.md)\n- [`docs/WORD_COMMENT_BALLOONS.md`](docs/WORD_COMMENT_BALLOONS.md)\n\n## Comparison modes\n\nThe default comparison mode is:\n\n```sh\n--mode word\n```\n\nIt targets Word-like comparison behavior.\n\nClassic PowerTools behavior is available with:\n\n```sh\n--mode powertools\n```\n\nChoose explicitly if exact comparison semantics matter to a regression test\nor downstream workflow.\n\n## Existing revisions in edit plans\n\nAn edit plan can refuse documents that already contain tracked changes, or\nresolve them according to an explicit policy.\n\nList changes before editing:\n\n```sh\njubarte changes source.docx --json\n```\n\nSelective resolution can be part of the plan, for example:\n\n```json\n{\n  \"resolve_revisions\": {\n    \"accept\": {\n      \"ids\": [\"r12\"]\n    },\n    \"reject\": {\n      \"authors\": [\"Previous Reviewer\"]\n    }\n  }\n}\n```\n\nConflicting selections are rejected instead of silently choosing a side.\n\nSettling a revision that removes a comment's whole anchor removes the thread\nand its replies, as Word does. Edit receipts report each removed thread as\n`removed_comments` (using source ids `c0`, `c1`, etc.), each saying `why`:\n`anchor removed by accepting r13`, the change that held its mark. Legacy `edit --dry-run`\nprints the JSONL preview; `edit --out-dir` writes the summary event in\n`report.jsonl`. Typed `edit apply --json` includes the same records in `data`.\nTo preserve the thread, set `\"removed_anchor_comments\": \"keep\"` in a v1 or\nv2 plan. Its range markers and reference runs move together to an empty,\nuntracked anchor where the removed text was. A reply in the same plan can\nthen use that anchor. The receipt reports `kept_comments` with `anchor: \"empty\"`.\nComments the plan subsequently deletes are not listed; deleted replies leave\nthe kept thread's `replies`, while its surviving root stays listed.\nThis opt-in is a jubarte convention that Word opens with threaded balloons;\nthe default `\"remove\"` follows Word's removal behavior. Partial overlaps\nkeep the existing behavior. Unknown values are refused as `INVALID_PLAN`.\nThe policy is available in plans; `accept`/`reject` keep their existing warnings.\nA reply to a comment whose paragraph the same plan deletes goes on the\ndeleted text beside its parent, where Word shows the thread; a v2 plan with\n`\"track\": \"off\"` deletes the anchor outright, and is refused with\n`COMMENT_ANCHOR_REMOVED`.\nComment and bookmark ids stay stable while a plan runs, so later operations\nstill address the source comments. After all operations finish, the preserving\npath numbers the revision-free working document once; its clean copy, tracked\nreplay and operation receipts share that allocation. Pending source revisions\nretain their ids. The comparer path retains ids in both outputs: it unions\ncomments from its original and edited inputs, so numbering only the edited\ninput would change comment matching. Settlement receipts retain source comment\nids; newly added comments report their written ids.\n\nIf settlement removes a kept thread's row, cell or whole table, its empty\nanchor moves to the end of the last surviving paragraph before that container\nin the same story, or the start of the first paragraph after it. Removed and\nkept receipts never list the same comment. Removal text names the acceptance\nor rejection that removed the thread; kept text names its published paragraph.\n\nThe v1 plan envelope is documented in `schemas/edit-plan-v1.schema.json`,\nand the typed v2 schema in `schemas/edit-plan-v2.schema.json`.\n\n## Examples\n\n### CLI\n\n```sh\njubarte original.docx revised.docx \\\n  -o redline.docx \\\n  --author \"Legal\"\n\njubarte changes redline.docx --json\n\njubarte convert redline.docx \\\n  -o redline.pdf \\\n  --revisions word\n```\n\n### Python `Document`\n\n```python\nimport jubarte_redlines as jubarte\n\ndoc = jubarte.read(\"contract.docx\")\n\nprint(doc.markdown())\nsnapshot = doc.inspect()\nprint(snapshot)\n\npages = doc.to_png(dpi=120)\n```\n\n### Agent-style document editing\n\nSee\n[`examples/agents/acme-letter`](examples/agents/acme-letter), which includes\nan edit plan, generated report and rendered redline page.\n\n## Safety and validation\n\nCI currently includes:\n\n- `cargo fmt --check`\n- Clippy with `-D warnings` on the crate and on the Python, WASM\n  (`wasm32-unknown-unknown`) and in-process bench bindings\n- all-feature Rust tests on Linux, macOS and Windows\n- source-based code coverage with a line-coverage floor\n- MSRV testing on Rust 1.94 (the all-feature test suite, on Linux)\n- `cargo publish --dry-run`\n- `cargo-deny`\n- REUSE/SPDX checks\n- Python binding tests\n\nThe project also maintains package/schema validation and real-Microsoft-Word\nopening probes for release work because an OOXML document can be schema-valid\nand still trigger Word repair behavior.\n\nSee:\n\n- [`KNOWN_ISSUES.md`](KNOWN_ISSUES.md)\n- [`docs/VERSIONING.md`](docs/VERSIONING.md)\n- [`docs/bench_classes.md`](docs/bench_classes.md)\n\n## Benchmarks\n\nJubarte maintains Word-oracle benchmarks for both document comparison and\nDOCX rendering.\n\nThe benchmark methodology, corpus provenance, current numbers and historical\nresults belong in:\n\n- the [neurotic_docx_bench RESULTS.md](https://github.com/jandira-tech/neurotic_docx_bench/blob/main/RESULTS.md)\n- the [page-by-page comparison site](https://jandira-tech.github.io/neurotic_docx_bench/)\n\nTreat these as reproducible project-maintained measurements rather than as a\nsubstitute for testing your own document corpus.\n\nFor important production workloads, benchmark representative documents from\nyour own environment before choosing an engine.\n\n## Supported environments\n\n| Surface | Supported/tested target |\n|---|---|\n| Rust / CLI | CI tests Linux, macOS and Windows |\n| Rust toolchain | Rust 1.94+ |\n| Python | CPython 3.10+ |\n| Python release wheels | macOS x86_64/arm64, manylinux_2_28 x86_64/arm64, musllinux_1_2 x86_64/arm64, Windows x86_64 (abi3, CPython 3.10+) |\n| Node | Node 18+ |\n| Browser | WebAssembly builds |\n| CLI release workflow | Linux x86_64/arm64, macOS x86_64/arm64, Windows x86_64 targets |\n\nRelease assets can vary by tag. Check the\n[release page](https://github.com/jandira-tech/jubarte-redlines/releases)\nbefore scripting a binary download.\n\nA Word 97-2003 `.doc` converts to `.docx` with the native binary's\n`jubarte convert old.doc` (or `jubarte::legacy_doc::doc_to_docx` in Rust):\ntext, headings, lists, bold, italic and tables. Every other command, and\nthe Python and JavaScript packages (the npm command line too), refuse a `.doc` (or an encrypted document of any Word\nversion) with `LEGACY_DOC` and the hint to save it as `.docx` without a\npassword, and RTF with `UNSUPPORTED_PACKAGE`. Convert them to `.docx` first.\n\n## Troubleshooting\n\n| Problem | What to check |\n|---|---|\n| PDF layout differs from Word | Verify required fonts; inspect `--font-report`; read `docs/WORD_DIFFERENCES.md` |\n| Text is missing or wraps differently | Check font resolution and embedded/system font availability |\n| Edit exits with a refusal | Read `report.jsonl` / stdout for `STALE_SOURCE`, `ANCHOR_NOT_FOUND`, `AMBIGUOUS_ANCHOR`, `OVERLAPPING_EDITS`, `UNSUPPORTED_STRUCTURE`, etc. |\n| `STALE_SOURCE` | Re-run `jubarte read` and regenerate the plan from its new `sha256:` line |\n| `AMBIGUOUS_ANCHOR` | Use a paragraph ID or a more specific exact anchor |\n| Document already contains revisions | List them with `jubarte changes`; explicitly accept/reject them or set an edit-plan revision policy |\n| Comment is present in DOCX but missing from rendered markup | Check the documented comment-balloon limitations and `docs/WORD_COMMENT_BALLOONS.md` |\n| Output page count is not exactly Word's | The renderer targets Word behavior but is independent; inspect known differences before treating page count as an invariant |\n| Prebuilt archive is absent for a platform | Install with Cargo or build from source; then check the release assets for a later tag |\n| Need exact package differences | Use `jubarte debug diff` and the `text`, `runs`, `xml` or `render` debug catalogs |\n\n## Contributing\n\nContributions that improve Word compatibility, package validity, diagnostics,\ndocumentation, examples or platform support are welcome.\n\nBefore opening a PR:\n\n```sh\ncargo fmt --check\ncargo clippy --all-targets --all-features -- -D warnings\ncargo test --all-features --no-fail-fast\ncargo publish --dry-run\n```\n\nIf you change any CLI flag, subcommand or public API, also run\n`scripts/gen_docs.sh` and commit the regenerated guide pages — the CI docs\njob fails when they drift.\n\nFor Python binding changes, run the Python test suite from `jubarte-python`.\n\nPlease include a minimal fixture or regression test for document-behavior\nchanges. For Word-compatibility changes, describe what Microsoft Word does and\nhow the fixture demonstrates it.\n\nFor security vulnerabilities, use a private GitHub security advisory or the\nprivate contact documented by the project rather than a public issue.\n\n## Roadmap\n\nProposed areas of focus:\n\n- [ ] Stabilize and document a `1.0` compatibility policy.\n- [ ] Keep every advertised binary/wheel target release-complete.\n- [ ] Expand newcomer examples for CLI, Rust, Python, Node and browser.\n- [ ] Improve editable coverage for currently unsupported DOCX structures.\n- [ ] Continue closing documented Word-layout differences.\n- [ ] Add a polished browser demo for compare/review/render workflows.\n- [ ] Make benchmark environments easier for third parties to reproduce.\n- [ ] Expand community documentation and contributor onboarding.\n\nRoadmap items are goals, not compatibility guarantees.\n\n## Project structure\n\n```text\nsrc/\n  lib.rs                 public Rust crate\n  document_comparer.rs   compare / revisions\n  comparer/              comparison engine\n  changes.rs             tracked-change listing / resolution\n  inspect.rs             document inspection, edit-plan anchors\n  edit.rs + edit/        validated JSON edit plans\n  markdown/              Markdown in and out: convert, diff, patch\n  convert/               DOCX → PDF/PNG layout engine\n  opc/                   DOCX package layer\n  xmllinq/               shared XML model\n  bin/jubarte.rs         CLI (compare, edit, convert, diff, debug, …)\n\njubarte-python/           PyO3 / maturin Python package\njubarte-wasm/             wasm-bindgen / npm package\njubarte-app/              Tauri desktop shell: its own repository (arthrod/jubarte-app), cloned here untracked\nexamples/                 examples and profiling tools\ntests/                    integration tests, goldens and corpus\ndocs/                     compatibility and engineering documentation\ntools/                    validation / benchmark tooling\nscripts/                  installation, release and Word-probe scripts\n```\n\n## License\n\n`jubarte-redlines` is licensed under\n[GNU Affero General Public License v3.0 only](LICENSE)\n(`AGPL-3.0-only`).\n\nReview the license requirements before embedding or deploying the software in\na product or network service.\n\n## Links\n\n[Engine comparison site](https://jandira-tech.github.io/neurotic_docx_bench/) ·\n[jandira.tech](https://www.jandira.tech) · [arthur.law](https://arthur.law) ·\n[Cicero](https://www.cicero.im) · [LinkedIn](https://linkedin.com/in/arthrod) ·\n`contact@arthur.law`\n- [GitHub](https://github.com/jandira-tech/jubarte-redlines)\n- [crates.io](https://crates.io/crates/jubarte-redlines)\n- [docs.rs](https://docs.rs/jubarte-redlines)\n- [PyPI](https://pypi.org/project/jubarte-redlines/)\n- [npm](https://www.npmjs.com/package/jubarte-wasm)\n- [Releases](https://github.com/jandira-tech/jubarte-redlines/releases)\n- [npm CLI](https://www.npmjs.com/package/jubarte-redlines)\n",
  "bytes": 48654,
  "sha": "1696158ec9c82dbc8994e9380a1f96b041e3dc4615430047bce58e35c6cf68f9",
  "repo_slug": "jandira-tech/jubarte-redlines",
  "fonte": "repo",
  "truncated": false,
  "api": "https://api.agentalog.com/api/listings/plg_jandira_tech_jubarte_redlines_0501e1dd/readme"
}