Engrave window: bar numbers, and two silent LilyPond faults
A system can now be given the measure it starts at, in a First bar field beside key and time. Per slice, since it is the one thing about a replacement that cannot be inherited from the song. Bar numbering is a Score property, so it is set once on the first staff, and made visible only at a line beginning — that vector is fussy: #(#f #t #t) also prints a number mid-system and #(#f #t #f) prints the second bar's rather than the first's. It travels in the bundle's engraving object as `bar`. Two things LilyPond 2.24 was quietly refusing to draw: `\bar ":|"` and the other old repeat names produce nothing at all — no error, no warning, exit status 0, just a missing repeat that you find on the tablet. Every book and forum answer still uses them, so translate them to the modern spellings. `\clef treble_8` unquoted is not an octavated clef either. It parses as a plain treble plus a stray "8" markup that lands under the first note, and the staff then reads an octave off — a tenor line engraved at soprano pitch. Quote it. The source pane, which is where either of those would have been visible, is now a collapsed section at the bottom rather than a permanent slab. It uses the panel's own disclosure helper, lifted out of Editor so both can call it.
This commit is contained in:
@@ -12,6 +12,7 @@ scaling.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
@@ -63,6 +64,25 @@ RELATIVE_REFERENCE = {
|
||||
"bass": "c",
|
||||
}
|
||||
|
||||
# LilyPond renamed the repeat barlines and silently draws *nothing* for the old
|
||||
# names — no error, no warning, just a missing repeat that you find on the
|
||||
# tablet. Every book, every forum answer and every score anyone has typed before
|
||||
# uses the old ones, so translate them.
|
||||
_BAR_ALIASES = {
|
||||
"|:": ".|:",
|
||||
":|": ":|.",
|
||||
":|:": ":|.|:",
|
||||
"||:": ".|:",
|
||||
":||": ":|.",
|
||||
":||:": ":|.|:",
|
||||
}
|
||||
_BAR = re.compile(r'(\\bar\s*")([^"]*)(")')
|
||||
|
||||
|
||||
def _modernise_bars(notes: str) -> str:
|
||||
return _BAR.sub(lambda m: m[1] + _BAR_ALIASES.get(m[2], m[2]) + m[3], notes)
|
||||
|
||||
|
||||
_PREAMBLE = """\\version "2.24.0"
|
||||
\\paper {
|
||||
indent = 0\\mm
|
||||
@@ -85,17 +105,35 @@ def generate(replacement, key: str, time: str) -> str:
|
||||
key = replacement.key or key
|
||||
time = replacement.time or time
|
||||
|
||||
# Bar numbering is a Score property, so it is set once, on the first staff.
|
||||
# Visible at the beginning of a line and nowhere else — which in a
|
||||
# one-system slice means exactly one number, above the first bar, the way a
|
||||
# printed score numbers its systems. The empty bar line is what gives the
|
||||
# number a line beginning to attach to.
|
||||
number = ""
|
||||
if replacement.bar:
|
||||
number = (
|
||||
f" \\set Score.currentBarNumber = #{int(replacement.bar)}\n"
|
||||
" \\override Score.BarNumber.break-visibility = #'#(#f #f #t)\n"
|
||||
' \\bar ""\n'
|
||||
)
|
||||
|
||||
staves = []
|
||||
for voice in replacement.voices:
|
||||
hide = "" if replacement.print_time else " \\omit Staff.TimeSignature\n"
|
||||
body = voice.notes.strip() or "s1"
|
||||
body = _modernise_bars(voice.notes.strip()) or "s1"
|
||||
reference = RELATIVE_REFERENCE.get(voice.clef, "c'")
|
||||
staff = (
|
||||
" \\new Staff {\n"
|
||||
f"{hide}"
|
||||
f" \\clef {voice.clef}\n"
|
||||
# Quoted, because an octavated name has to be: unquoted,
|
||||
# `\clef treble_8` parses as a plain treble clef with a stray "8"
|
||||
# markup that lands under the first note, and the staff then reads
|
||||
# an octave off.
|
||||
f' \\clef "{voice.clef}"\n'
|
||||
f" \\key {key} \\major\n"
|
||||
f" \\time {time}\n"
|
||||
f"{number if not staves else ''}"
|
||||
f" \\relative {reference} {{ {body} }}\n"
|
||||
" }\n"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user