Esa Kataja 97c8e8a709 Add LilyPond slice replacement with a structured engrave window
Re-engraving is a rescue path for the handful of systems a scan cannot
deliver, so the window is an editing surface rather than an automation
project. Three full-width rows - the scanned system, the render, the
form - because a system is wide and short and the job is comparing one
against the other bar by bar. The render is shown scaled to the scan's
staff height, which is what export does anyway, so it previews the real
thing.

A form rather than a text box. Key and time are slice-level, clef,
notes and lyrics per voice: every staff in a system carries the same key
signature, and Kaipaava proves it across five-staff and two-staff
systems alike. Notes and lyrics stay raw LilyPond, so slurs, dynamics,
tuplets and the laissezVibrer/repeatTie idiom for ties crossing into the
next slice all work untouched.

Notes are entered in \relative mode, referenced to the middle of each
clef's staff, so a part needs no octave marks at all in the common case.

The time signature is used for spacing and bar checks but not printed:
the printed score repeats the key at every system and the time only at
the first, so a re-engraved middle slice showing one would stand out.

Seeded from what can be known reliably. Voice count comes from counting
staves in the slice; key, time and clefs are inherited from the song,
because the slices being re-engraved are the illegible ones and reading
a key signature off them is exactly the measurement that fails. After
the first replacement in a song only the notes need typing.

Staff counting needed two corrections against the corpus: compare gaps
against line spacing rather than staff height, since adjacent staves can
sit closer together than one staff is tall; and require five lines in a
group, since Engel's 'uh______' lyric extenders are long horizontal runs
too and each counted as a staff. Kaipaava now reads 2,2,2,2,5 on page 1,
Ketun 6, Engel 4.

Also in this change:

- Title is required for export, every other metadata field optional,
  enforced in bundle.write so the CLI and the editor both get it. Tempo
  added; noteman already has a free-form column for it.
- The panel is a splitter rather than a fixed width, sections collapse
  under bold grey disclosure headers, and it scrolls.
- A re-engraved slice is washed amber with an ENGRAVED badge, and
  markers get badges too. Thin coloured text was invisible against a
  scan.

Closes #31
Closes #32
Closes #33
Closes #34
2026-07-29 01:29:43 +03:00

noteman-slicer

Turns a score PDF into the ordered slice images noteman consumes, plus the navigation markers that sit on them.

A slice is one system — one full line of music across all voices, typically 412 bars with lyrics intact. noteman displays them as a continuous vertical scroll, so the slicer's job is to cut a printed page into systems, clean them up enough to read on a tablet, and tag them with the score's navigation symbols.

Status: design only. No code yet. The design is settled; see below.

How it works

Open a PDF, and the tool proposes cuts between systems, a skew correction, and a content rectangle. You correct all of it — source quality varies too much for unattended processing, so detection is an accelerator that nothing depends on being right. You mark the header and footer regions discarded, set black and white points until the paper disappears and the notes go solid, place the rehearsal letters and jump markers, fill in the title block, and export.

Out comes one zip: the slices in order, their markers, the original PDF, and the song metadata. That bundle is the only channel to noteman — there's no API between the two tools.

Erasing previous-owner pencil marks, chord letters and breath marks stays in GIMP. That's the irreducible manual part, and GIMP with a stylus is already good at it.

Installation

Not yet installable. When it is:

uv tool install --editable .

That puts a noteman-slicer command on PATH which runs from any directory — no venv to activate. Dependencies (PyMuPDF, PySide6, OpenCV, numpy) are all wheels; nothing needs a system package.

Documentation

CONTEXT.md Glossary. What a slice, cut, discard, bundle and song scale actually mean here. Start here.
docs/spec.md The specification: pipeline, geometry model, detection, editor, bundle format, and what noteman has to change.

Deferred work is tracked as issues and milestones on the Gitea repo, not in this tree.

Decisions that were expensive to reach, each with the evidence behind it:

ADR 0001 The slicer owns all image processing; the bundle is the only channel to noteman.
ADR 0002 Raster only in release 1 — measured SVG slice sizes and what they showed.
ADR 0003 Lossless WebP beats every lossy option and every alternative format here.
ADR 0004 No unattended mode: detection suggests, a human confirms.
ADR 0005 PyMuPDF for all PDF access, accepting AGPL.
ADR 0006 Systems are found by vertical brackets; row-darkness gaps get it wrong.
ADR 0007 A project is spent once exported; reopening starts fresh. Reverses an earlier decision.
S
Description
No description provided
Readme
195 KiB
Languages
Python 100%