Martin Pitt [Wed, 23 Sep 2026 20:51:09 +0000 (22:51 +0200)]
Keep the song content local to the renderer
The comment handler appended to a module level array, which the renderer had
to reset on every call. Directive handlers now return the content to render
instead; lit ignores the undefined results of handlers that only set headings.
Martin Pitt [Wed, 23 Sep 2026 20:47:42 +0000 (22:47 +0200)]
Scope chord styling to verses with chords
The empty chord span of a line without chords still got the chord padding,
which indented every chordless verse by 0.3ex. Chords only exist in .chords
verses, so all their styling moves into that block, written with CSS nesting.
Martin Pitt [Wed, 23 Sep 2026 20:45:53 +0000 (22:45 +0200)]
Recognize directives without argument
Directives like `{start_of_chorus}` or `{eoc}` did not match the
directive pattern, so they were rendered literally as lyrics. They now
get the same "unknown directive" warning as other unsupported ones.
Martin Pitt [Wed, 23 Sep 2026 20:44:59 +0000 (22:44 +0200)]
Flush open verse on directives and at end of file
Verses were only emitted on a blank line. A directive directly after a
lyrics line, such as {comment: Chorus}, thus appeared before that verse,
and a file without a trailing newline lost its last verse.
Martin Pitt [Wed, 23 Sep 2026 20:30:13 +0000 (22:30 +0200)]
Lay out chords and lyrics as segments
Zero-width chords overlapped whenever the text under them, or even
empty: adjacent chords (intros/bridges without text), chords separated by
a single space, or a long chord name over a short syllable. The rule from dc37808 only widened the second chord of a run, so the first pair still
collided.
Group each chord with the lyrics up to the next chord into a segment with
two rows. Its width is the wider of the two, which fixes the overlap.