Skip to content

Commit 6ef989e

Browse files
committed
📝 docs: expand README and add repository guidelines
1 parent a9a15e7 commit 6ef989e

2 files changed

Lines changed: 67 additions & 1 deletion

File tree

AGENTS.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Repository Guidelines
2+
3+
## Project Structure & Module Organization
4+
The core library lives in `sdiff/` (parser, comparer, renderer, and models). Tests are in `tests/`, with shared fixtures in `tests/fixtures/`. Reference PDFs sit in `docs/`. Packaging and tooling are defined in `setup.py`, `setup.cfg`, and the `Makefile`; `CHANGELOG` tracks releases.
5+
6+
## Build, Test, and Development Commands
7+
- `make env` creates the local `venv/` (Python 3.11+).
8+
- `make dev` installs the package plus test/dev extras (`.[tests,devtools]`) into the venv.
9+
- `make test` runs linting and the full pytest suite with coverage.
10+
- `make vtest` runs pytest verbosely.
11+
- `make flake` runs flake8 on `sdiff/` and `tests/`.
12+
- `make cov` prints the coverage report.
13+
- `make clean` removes build artifacts and the venv.
14+
15+
Example flow:
16+
```sh
17+
make dev
18+
make test
19+
```
20+
21+
## Coding Style & Naming Conventions
22+
Use standard Python conventions: 4-space indentation, `snake_case` for modules/functions/variables, and `PascalCase` for classes. Flake8 enforces a 120-character line limit (see `setup.cfg`). `autopep8` is available for formatting. Keep new modules in `sdiff/` and new tests in `tests/` with filenames like `test_<area>.py`.
23+
24+
## Testing Guidelines
25+
The suite uses `pytest` with `coverage`. Coverage is expected to stay high (current config fails under 96%). Add or update tests for behavior changes, and prefer small, focused unit tests. Place reusable data in `tests/fixtures/`. Run `make test` before submitting changes.
26+
27+
## Commit & Pull Request Guidelines
28+
Commit messages in this repo are short and often use a type prefix (e.g., `chore: ...`, `fixes: ...`, `hotfix: ...`, `refactors: ...`). Follow that pattern where practical, and keep the summary concise. For PRs, include a brief description, list tests run (e.g., `make test`), and link related issues or tickets when available.

README.md

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,40 @@
11
# md-sdiff
2-
Diffs to markdown texts only based on their structure. Ignores content. Helpful to diff 2 files that contain the same content in different languages.
2+
3+
Structural diffs for Markdown. The library parses two Markdown inputs into a lightweight tree and compares the *shape* (headings, lists, paragraphs, links, etc.) instead of the text content. This is useful when you expect the same document structure across translations or when you want to validate formatting consistency without caring about the wording.
4+
5+
## What it does
6+
- Parses Markdown into an AST-like node tree using `mistune`.
7+
- Compares trees node-by-node and flags insertions/deletions in structure.
8+
- Returns a rendered view of each document plus a list of structural errors.
9+
- Supports a Zendesk-specific parser (`ZendeskHelpMdParser`) for `<callout>`, `<steps>`, and `<tabs>` blocks.
10+
11+
## Example usage
12+
```python
13+
from sdiff import diff, TextRenderer, MdParser
14+
15+
left = "# Title\n\n- One\n- Two"
16+
right = "# Title\n\n- One\n- Two\n- Three"
17+
18+
rendered_left, rendered_right, errors = diff(left, right, renderer=TextRenderer(), parser_cls=MdParser)
19+
print(errors[0]) # "There is a missing element `li`."
20+
```
21+
22+
## Renderers
23+
`TextRenderer` returns the original Markdown structure as text. `HtmlRenderer` wraps the output and marks structural insertions/deletions with `<ins>` and `<del>`.
24+
25+
## One-off usage
26+
```sh
27+
python - <<'PY'
28+
from sdiff import diff, TextRenderer
29+
30+
left = open("left.md", "r", encoding="utf-8").read()
31+
right = open("right.md", "r", encoding="utf-8").read()
32+
_, _, errors = diff(left, right, renderer=TextRenderer())
33+
34+
for err in errors:
35+
print(err)
36+
PY
37+
```
38+
39+
## Notes
40+
This project is a library (no CLI). If you need different token handling, you can provide a custom parser class that extends `MdParser`.

0 commit comments

Comments
 (0)