中文说明 · Repair guide · Research
Comic dialogue order you can diff, lint, localize, and review.
BalloonOrder compiles a structured comic page into a deterministic reading order, a localization CSV, a script, and a visual proof. It catches geometry that still needs a human decision instead of silently guessing.
The preview above is generated from examples/ltr-page.json by the shipped CLI. Browse the complete offline demo, JSON report, script, or localization CSV.
Letterers, editors, translators, and accessibility teams often receive the same dialogue in different ad-hoc formats. Visual placement alone becomes ambiguous when balloons overlap, layouts break the grid, or a translated edition reads in another direction.
BalloonOrder makes the page contract reviewable before expensive downstream work begins:
- Deterministic: the same JSON produces byte-for-byte identical artifacts.
- Direction-aware: LTR and RTL page order are first-class inputs.
- Human-correctable:
afterconstraints record creative intent in source control. - Actionable: stable diagnostic codes identify boundary, overlap, tail, and cycle problems.
- Portable: the runtime uses only the Python standard library; the HTML demo needs no server or network.
It is deliberately not an OCR engine, manga translator, inpainting model, or drawing editor. Image-first tools recover structure from finished pages; BalloonOrder validates structure that creators already own and turns it into durable handoff artifacts.
Requires Python 3.11+ and uv.
git clone https://github.com/KanadeK/balloon-order.git
cd balloon-order
uv sync --extra dev --python 3.12
uv run balloon-order check examples/ltr-page.json
uv run balloon-order compile examples/ltr-page.json --out out/ltrExpected result:
OK examples/ltr-page.json: 0 errors, 0 warnings, 4 balloons
Wrote 5 artifacts to out/ltr
Now exercise the failure path:
uv run balloon-order check examples/broken-page.jsonIt returns exit code 1 with PANEL_OUTSIDE_PAGE, ORDER_AMBIGUOUS, and TAIL_OUTSIDE_PAGE. See the repair guide for exact fixes.
| Artifact | Purpose |
|---|---|
report.json |
Stable machine-readable order, summary, and diagnostics |
script.md |
Reviewable panel-by-panel dialogue script |
localization.csv |
Ordered source/translation handoff with spreadsheet formula protection |
preview.svg |
Scalable visual proof of panel and balloon order |
index.html |
Self-contained offline review page with no JavaScript or network calls |
compile creates no output directory when blocking diagnostics exist.
One versioned JSON file represents one page. Geometry is rectangular in v0.1.
{
"schema_version": "1",
"page": {
"id": "page-01",
"width": 1200,
"height": 1600,
"reading_direction": "ltr"
},
"panels": [
{
"id": "p1",
"box": { "x": 80, "y": 80, "width": 1040, "height": 620 }
}
],
"balloons": [
{
"id": "b1",
"panel_id": "p1",
"box": { "x": 150, "y": 150, "width": 340, "height": 160 },
"speaker": "Mina",
"text": "The map says left.",
"tail": { "x": 410, "y": 410 }
}
]
}To state that b2 must be read after b1, place the constraint on the later item:
{ "id": "b2", "after": ["b1"] }Panel constraints work the same way. Balloon constraints cannot cross panel boundaries.
validated JSON
│
├── geometry diagnostics
│
└── visual row priority ──► stable topological sort
│
▼
JSON / Markdown / CSV / SVG / HTML
- Items are grouped into top-to-bottom visual rows by vertical overlap.
- A row reads left-to-right or right-to-left from the page setting.
afteredges are hard constraints and take precedence over visual priority.- An overlap without a constraint is blocking because geometry alone cannot prove intent.
- A constraint cycle is blocking; BalloonOrder never invents a fallback order.
| Code | Severity | Meaning |
|---|---|---|
PANEL_OUTSIDE_PAGE |
error | A panel extends beyond the page |
BALLOON_OUTSIDE_PANEL |
error | A balloon extends beyond its panel |
PANEL_OVERLAP |
warning | Two panels share interior area |
BALLOON_OVERLAP |
warning | Two balloons share interior area |
ORDER_AMBIGUOUS |
error | An overlap lacks an explicit order constraint |
TAIL_OUTSIDE_PAGE |
error | A tail endpoint lies beyond the page |
TAIL_CROSSES_BALLOON |
warning | A tail segment intersects another balloon |
ORDER_CYCLE |
error | after constraints contain a cycle |
| Exit | Meaning |
|---|---|
0 |
Clean or warnings only |
1 |
Valid source with blocking analysis errors |
2 |
Invalid JSON/schema, CLI usage, encoding, or I/O failure |
Use balloon-order check PAGE.json --json for automation.
uv sync --extra dev --python 3.12
uv run python scripts/verify.pyThe release verifier runs format/lint, strict types, tests with branch coverage, package build, dependency audit, wheel smoke installation, bundled examples, and repository hygiene. CI executes the same release-critical path on Python 3.11–3.13.
When a command fails, start with docs/REPAIR.md. Architectural and input-contract details live in docs/SPEC.md and ADR 0001.
v0.1 intentionally supports one page, rectangular geometry, explicit LTR/RTL direction, and JSON source. Deferred work includes spreads, polygon geometry, and authoring-tool importers. OCR, translation, inpainting, accounts, telemetry, and hosted services are out of scope.
If BalloonOrder fits a real lettering or localization handoff, a small anonymized fixture or issue is more valuable than a vague feature request. See CONTRIBUTING.md.