Skip to content

Commit a70c136

Browse files
authored
Merge pull request #19 from JSv4/add-docxodus-engine
Add DocxodusEngine as a second comparison engine
2 parents 254e742 + 3e96ebd commit a70c136

16 files changed

Lines changed: 723 additions & 157 deletions

File tree

.github/workflows/ci.yml

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
test:
14+
runs-on: ${{ matrix.os }}
15+
strategy:
16+
fail-fast: false
17+
matrix:
18+
os: [ubuntu-latest, windows-latest, macos-latest]
19+
python-version: ['3.9', '3.11', '3.12']
20+
21+
steps:
22+
- uses: actions/checkout@v4
23+
with:
24+
submodules: recursive
25+
26+
- name: Set up Python ${{ matrix.python-version }}
27+
uses: actions/setup-python@v5
28+
with:
29+
python-version: ${{ matrix.python-version }}
30+
31+
- name: Set up .NET
32+
uses: actions/setup-dotnet@v4
33+
with:
34+
dotnet-version: '8.0.x'
35+
36+
- name: Install dependencies
37+
run: |
38+
python -m pip install --upgrade pip
39+
pip install hatch
40+
41+
- name: Build engine binaries
42+
run: python build_differ.py
43+
44+
- name: Run tests
45+
run: hatch run test
46+
47+
build:
48+
runs-on: ubuntu-latest
49+
steps:
50+
- uses: actions/checkout@v4
51+
with:
52+
submodules: recursive
53+
54+
- name: Set up Python
55+
uses: actions/setup-python@v5
56+
with:
57+
python-version: '3.11'
58+
59+
- name: Set up .NET
60+
uses: actions/setup-dotnet@v4
61+
with:
62+
dotnet-version: '8.0.x'
63+
64+
- name: Install build dependencies
65+
run: |
66+
python -m pip install --upgrade pip
67+
pip install hatch hatchling
68+
69+
- name: Build package
70+
run: hatch build
71+
72+
- name: Check package
73+
run: |
74+
pip install twine
75+
twine check dist/*

.github/workflows/python-publish.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,16 @@ jobs:
1414

1515
steps:
1616
- uses: actions/checkout@v3
17+
with:
18+
submodules: recursive
1719
- name: Set up Python
1820
uses: actions/setup-python@v3
1921
with:
2022
python-version: '3.x'
23+
- name: Setup .NET
24+
uses: actions/setup-dotnet@v3
25+
with:
26+
dotnet-version: '8.0.x'
2127
- name: Install dependencies
2228
run: |
2329
python -m pip install --upgrade pip
@@ -26,4 +32,4 @@ jobs:
2632
run: hatch build
2733
- name: Publish package
2834
run: |
29-
hatch publish -u "__token__" -a ${{ secrets.PYPI_API_TOKEN }}
35+
hatch publish -u "__token__" -a ${{ secrets.PYPI_API_TOKEN }}

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ __pycache__/
66
# C# Build Dirs
77
csproj/bin/*
88
csproj/obj/*
9+
docxodus/**/bin/*
10+
docxodus/**/obj/*
911

1012
# C extensions
1113
*.so

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "docxodus"]
2+
path = docxodus
3+
url = https://github.com/JSv4/Docxodus.git

CLAUDE.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
Python-Redlines is a Python wrapper around compiled C# binaries that generate `.docx` redline/tracked-changes documents by comparing two Word files. The Python layer handles platform detection, binary extraction, temp file management, and subprocess execution.
8+
9+
Two comparison engines are available:
10+
- **XmlPowerToolsEngine** — wraps Open-XML-PowerTools WmlComparer (original engine)
11+
- **DocxodusEngine** — wraps Docxodus, a modernized .NET 8.0 fork with better move detection
12+
13+
## Commands
14+
15+
```bash
16+
# Run tests
17+
hatch run test
18+
19+
# Run a single test
20+
hatch run test tests/test_openxml_differ.py::test_run_redlines_with_real_files
21+
22+
# Run tests with coverage
23+
hatch run cov
24+
25+
# Type checking
26+
hatch run types:check
27+
28+
# Build C# binaries for all platforms (requires .NET 8.0 SDK)
29+
hatch run build
30+
31+
# Build Python package (triggers C# build via custom hook)
32+
hatch build
33+
34+
# Initialize Docxodus submodule (required before building)
35+
git submodule update --init --recursive
36+
```
37+
38+
## Architecture
39+
40+
The system uses a two-layer wrapper pattern with a shared base class:
41+
42+
1. **Python layer** (`src/python_redlines/engines.py`):
43+
- `BaseEngine` — shared logic for binary extraction, subprocess invocation, and temp file management
44+
- `XmlPowerToolsEngine(BaseEngine)` — sets constants for the Open-XML-PowerTools binary (`dist/`, `bin/`, `redlines`)
45+
- `DocxodusEngine(BaseEngine)` — sets constants for the Docxodus binary (`dist_docxodus/`, `bin_docxodus/`, `redline`)
46+
47+
Both engines expose `run_redline(author_tag, original, modified, **kwargs)`. `DocxodusEngine` overrides `_build_command()` to translate kwargs (e.g. `detect_moves`, `detail_threshold`) into CLI flags for the Docxodus binary. `XmlPowerToolsEngine` uses the legacy 4-positional-arg format and ignores kwargs.
48+
49+
2. **C# binaries**:
50+
- `csproj/Program.cs` — Open-XML-PowerTools CLI tool
51+
- `docxodus/tools/redline/Program.cs` — Docxodus CLI tool (git submodule)
52+
53+
Pre-compiled binaries for 6 platform targets (linux/win/osx x x64/arm64) are stored as archives in `src/python_redlines/dist/` and `src/python_redlines/dist_docxodus/`, included in the wheel. The build script `build_differ.py` compiles both engines using `dotnet publish`.
54+
55+
## Key Files
56+
57+
- `src/python_redlines/engines.py` — BaseEngine, XmlPowerToolsEngine, and DocxodusEngine classes
58+
- `src/python_redlines/__init__.py` — Exports all engine classes
59+
- `src/python_redlines/__about__.py` — Single source of truth for package version
60+
- `csproj/Program.cs` — Open-XML-PowerTools C# comparison utility
61+
- `docxodus/` — Docxodus git submodule (tools/redline/ contains the CLI)
62+
- `build_differ.py` — Cross-platform C# build orchestration for both engines
63+
- `hatch_run_build_hook.py` — Hatch build hook that triggers C# compilation
64+
- `tests/fixtures/` — Test `.docx` files (original, modified, expected_redline)
65+
66+
## Testing Notes
67+
68+
Tests must be run from the project root (fixtures use relative paths like `tests/fixtures/original.docx`). The XmlPowerToolsEngine integration test validates that comparing the fixture documents produces exactly 9 revisions. Docxodus uses a different stdout format (`"revision(s) found"` vs `"Revisions found: 9"`).
69+
70+
## Stdout Format Differences
71+
72+
- **XmlPowerToolsEngine**: `"Revisions found: 9"`
73+
- **DocxodusEngine**: `"Redline complete: 9 revision(s) found"`

0 commit comments

Comments
 (0)