Kurz gesagt
Ein kleines Liederbuch zum Singen am Tisch. Jedes Lied steht als einfacher Text in einer Notenschrift namens ABC, und Postext zeichnet die Notenzeile, die Noten, die Gitarrenakkorde und den Text unter den Noten.
Was Sie setzen
Songs for the Long Table, ein Liederbuch im Taschenformat A5: eine krapprote Titelseite, ein Wort an die Singenden mit dem Inhaltsverzeichnis, drei Lieder und Anmerkungen dazu, woher jedes stammt. Jedes Lied beginnt unter einer großen krapproten Nummer, einem Titel in der Fraunces und einer Zeile mit den Urhebern in Kapitälchen. Darunter läuft die Melodie auf einer 5,5 mm hohen Notenzeile in Leland, mit den Gitarrenakkorden über den Takten und der ersten Strophe unter den Noten in der Spectral, der Textschrift des Buches. Die übrigen Strophen stehen in zwei Spalten, sodass man vom letzten Takt aus gerade nach unten weiterliest. Amazing Grace, dessen lange Verse in einer Spalte umbrechen würden, setzt seine Strophen zentriert untereinander. Die spanische Ausgabe ist ein Geburtstagsliederbuch mit drei kürzeren Liedern, zwei auf einer Seite.
Dieses Rezept beantwortet
- Wie setze ich ein Liederbuch mit Melodie, Text unter den Noten und Akkordsymbolen?
Die kurze Antwort
// A song is an ```abc fence in the Markdown: the melody, its chords written "G" before the note
// they fall on, and the first verse on a w: line under it. The look is set here, once.
const scoreStyle = {
staffSize: mm(5.5), // a songbook rastral; the words under it come out at about 8 pt
musicFont: 'Leland', // lighter noteheads than Bravura, close to Spectral's colour
textFont: TEXT, // words and chord names in the text face, not the engraver's Times
spacing: 1, // the engraver's own: five or six bars of 3/4 to a system on this measure
barNumbers: 'none', // a table of singers counts verses, not bars
systemGap: mm(4.5), // room for the chord names between one system's words and the next
marginTop: pt(4),
marginBottom: pt(LEAD),
color: col('ink'),
minSystemsAtBreak: 2, // never a lone system at a page foot or head
};
// Two habits of Verovio's ABC reader shape the w: lines. Every sung note takes the next
// syllable in order: the `_` and `*` holds are read as nothing, so the second note of a
// slurred pair (B/G/ under "-ing") gets a no-break space, which prints nothing. A tied note
// takes none. `~` joins two syllables on one note: "de~a-trás".
Zutaten
- Funktionen
- NotensatzNotenstilVerse Zeile für ZeileGestaltete AuftakteÜberschriftenattributeNummerierte ÜberschriftenÜberschriftenformateKapitel ohne NummerUmschläge, Titelseiten und ImpressumDokument-MetadatenInhaltsverzeichnisKolumnentitel und SeitenzahlenKopfzeilen nach SeitenrolleAbsatzformateGespiegelte RänderSemantische FarbpalettePapierfarbeText, Linien und Kästen in SeitengestaltungenPDF-Export
- Nutzt außerdem
- Spalten in einem Kasten oder im TextCode-ListingsIm PDF eingebettete SchriftenKolumnentitel je Abschnitt
- Schrift
- Spectral, Spectral SC, Fraunces (SIL OFL 1.1)
- Dateien
- Keine: Jedes Bild wird im Code gezeichnet
Zubereitung
#1 · Das Lied schreiben, den Notenstil einmal festlegen
Der Notenstil steht in der kurzen Antwort oben. Im Markdown ist jedes Lied ein ```abc-Block: Die Kopfzeilen geben Taktart, Grundnotenwert und Tonart an; ein Akkordname in doppelten Anführungszeichen ("D7"A) steht über der Note, der er vorangeht; eine w:-Zeile unter der Musik setzt eine Silbe unter jede Note, mit Bindestrichen getrennt. Eine Melodie mit Strophe und Refrain besteht aus zwei Musikzeilen, jede mit ihrer eigenen w:-Zeile. Größe der Notenzeile, Notenschrift, die Schrift des Textes, die Taktzahlen und der Abstand zwischen den Systemen kommen aus scoreStyle. So passen die drei Lieder zusammen, und die Blöcke enthalten nur Musik.
#2 · Jedes Lied unter seiner Nummer und seinen Urhebern beginnen
// # Amazing Grace {credit="Words John Newton, 1779 · Tune New Britain, American, 1835"}
// The songs run on, three lines apart: a short song shares its page with the next one.
const at = (to, edge, x = 0, y = 0) => ({ anchor: { to, edge }, offset: { x: mm(x), y: mm(y) } });
const text = (id, content, font, size, color, placement, extra = {}) => ({ kind: 'text', id,
content, fontFamily: font, fontSize: pt(size), color: col(color), align: 'left', placement,
...extra });
const songHead = { enabled: true, minHeight: mm(21), slot: { elements: [
text('number', '{number}', DISPLAY, 26, 'madder', at('container', 'top-left', 0, 1),
{ fontWeight: 600, lineHeight: 1 }),
text('title', '{titleText}', DISPLAY, 21, 'ink', { ...at('container', 'top-left', 12, 2),
size: { width: mm(100) } }, { fontWeight: 600, lineHeight: 1.05 }),
text('credit', '{attr.credit}', LABEL, 8.4, 'madder', { ...at('#title', 'below', 0, 2.2),
size: { width: mm(100) } }, { fontWeight: 600, letterSpacing: pt(0.6) }),
] } };
const songs = { level: 1, numberingTemplate: '{1}', advancedDesign: songHead,
marginTop: pt(LEAD * 3), marginBottom: pt(0), breakBefore: { enabled: false } };
Das Lied ist eine Überschrift erster Ebene mit einem Attribut credit, und ihr Design setzt daraus die Nummer, den Titel und die Urheberzeile. minHeight gibt jedem Lied denselben 21 mm hohen Kopf, sodass die Notenzeilen auf jeder Seite in derselben Höhe beginnen. Die Lieder laufen fortlaufend weiter, mit drei Zeilen Abstand über jedem Titel, und ein Notensatz wird nie vor seinem zweiten System umbrochen (minSystemsAtBreak: 2): Die englischen Lieder füllen je eine Seite, und zwei der kurzen spanischen Lieder teilen sich eine.
#3 · Die übrigen Strophen in zwei Spalten setzen
// :::columns{count=2} holds one :::verse block per stanza; each line of the stanza is a
// line of Markdown, the turned lines indented two spaces (one em). A hymn in long lines
// (Amazing Grace) drops the columns: its stanzas stand one under another, centred.
const verse = { id: 'verse', fontSize: pt(9.4), lineHeight: pt(13), hyphenation: false,
marginBottom: pt(13 / 2) };
const chorus = { id: 'chorus', fontSize: pt(9.4), lineHeight: pt(13), italic: true,
hyphenation: false, marginBottom: pt(LEAD / 2) };
const colophon = { id: 'colophon', fontFamily: LABEL, fontSize: pt(7.8), lineHeight: pt(11),
color: col('muted'), textAlign: 'left', firstLineIndent: pt(0), marginTop: pt(LEAD * 2) };
Jede Strophe ist ein :::verse-Block, sodass ihre Zeilen dort umbrechen, wo der Dichter sie umbrochen hat, und die zweite und vierte Zeile um ein Geviert eingezogen sind. Eine Gruppe :::columns{count=2 gap=4mm} stellt sie in 9,4 pt nebeneinander. Zählen Sie vorher die Zeichen: Die Verse von Burns passen in eine 55 mm breite Spalte, Newtons Langvers nicht, deshalb behält Amazing Grace einen einzigen zentrierten :::verse-Block, in dem Leerzeilen die Strophen trennen.
#4 · Die festen Seitenelemente zurückhaltend halten
const head = (id, content, parity, edge, x, style = {}) => ({
kind: 'text', id, content, parity, pages: 'all', // a song's first page carries them too
fontFamily: LABEL, fontSize: pt(8.4), fontWeight: 600, letterSpacing: pt(0.9),
color: col('muted'), ...style,
placement: { anchor: { to: 'page', edge }, offset: { x: mm(x), y: mm(12.5) } },
});
const folio = { fontFamily: TEXT, fontWeight: 600, letterSpacing: pt(0), color: col('madder') };
const header = { elements: [
head('verso-folio', '{pageNumber}', 'even', 'top-left', OUTER, folio),
head('verso-title', '{title}', 'even', 'top-left', OUTER + 8),
head('recto-song', '{chapterTitle}', 'odd', 'top-right', -(OUTER + 8)),
head('recto-folio', '{pageNumber}', 'odd', 'top-right', -OUTER, folio),
] };
Die Kolumnentitel stehen auf jeder Seite, die die Lieder erreichen, der Buchtitel auf der linken und das Lied auf der rechten Seite, mit der Pagina im Krapprot der Liednummern. Die Titelseite und das Wort an die Singenden entfernen sie mit einem leeren header in ihren Überschriftenstilen.
Das ganze Rezept
// ═══ Postext Cookbook · Nº 164 · Songbook: melody, words under the notes, chords ═══════
// https://postext.dev/en/cookbook/songbook-melody-words-chords
// Code: MIT · Words and tunes: public domain (see the notes in each edition) · Prose: CC BY 4.0
// Fonts: Spectral, Spectral SC, Fraunces (SIL OFL 1.1); Leland (music) · Needs postext ≥ 1.54.0
import {
buildDocumentWithFonts, renderPageToCanvas, initMusicEngine,
} from 'https://esm.sh/postext';
import { renderToPdf, decompressWoff2 } from 'https://esm.sh/postext-pdf';
const LANG = 'en'; // @lang: the language of the sample document ('en' | 'es')
const RECIPE = 'songbook-melody-words-chords';
// ─── 1 · Design ─────────────────────────────────────────────────────────────
const palette = { // every colour in the config links to one of these
ink: '#211e1b', // text and notes: a warm near-black
madder: '#8a3324', // the one accent: song numbers, the title page, credit lines
tint: '#f1e7d8', // the subtitle on the madder ground (8.2:1)
rule: '#cbbca6', // hairlines
muted: '#675e55', // running heads, notes and the colophon (5.9:1 on the paper)
paper: '#fbf8f1', // a cream stock
};
const col = (id) => ({ hex: palette[id], model: 'hex', paletteId: id });
const colorPalette = [
...Object.entries(palette).map(([id, hex]) => ({ id, name: id, value: { hex, model: 'hex' } })),
// The engine's defaults link to 'main-color': point it at the accent, so nothing prints blue.
{ id: 'main-color', name: 'madder (defaults)', value: { hex: palette.madder, model: 'hex' } },
];
const [TEXT, LABEL, DISPLAY] = ['Spectral', 'Spectral SC', 'Fraunces'];
const LEAD = 14; // pt: the body's leading
const OUTER = 15; // mm: the outer margin, where the running heads and folios align
// #region answer: the score style: a 5 mm staff in Leland, the words in the book's face
// A song is an ```abc fence in the Markdown: the melody, its chords written "G" before the note
// they fall on, and the first verse on a w: line under it. The look is set here, once.
const scoreStyle = {
staffSize: mm(5.5), // a songbook rastral; the words under it come out at about 8 pt
musicFont: 'Leland', // lighter noteheads than Bravura, close to Spectral's colour
textFont: TEXT, // words and chord names in the text face, not the engraver's Times
spacing: 1, // the engraver's own: five or six bars of 3/4 to a system on this measure
barNumbers: 'none', // a table of singers counts verses, not bars
systemGap: mm(4.5), // room for the chord names between one system's words and the next
marginTop: pt(4),
marginBottom: pt(LEAD),
color: col('ink'),
minSystemsAtBreak: 2, // never a lone system at a page foot or head
};
// Two habits of Verovio's ABC reader shape the w: lines. Every sung note takes the next
// syllable in order: the `_` and `*` holds are read as nothing, so the second note of a
Das zusammengesetzte script.js läuft unverändert: Fügen Sie es in das Modulskript einer beliebigen Seite ein, oder öffnen Sie das Rezept auf CodePen. Ordner des Rezepts auf GitHub ↗ (öffnet sich in einem neuen Tab)
Varianten
#In Bravura stechen
Bravura hat kräftigere Notenköpfe und wirkt wie von einer gestochenen Platte gedruckt; sie passt zu einem Gesangbuch in einer dunkleren Textschrift.
- musicFont: 'Leland', // lighter noteheads than Bravura, close to Spectral's colour
+ musicFont: 'Bravura',#Die Takte nummerieren
Ein Chor probt nach Taktzahlen; drucken Sie eine am Anfang jedes Systems.
- barNumbers: 'none', // a table of singers counts verses, not bars
+ barNumbers: 'system',Häufige Fehler
Häufiger Fehler
Ein Überschriftenformat erbt den Seitenumbruch seiner Ebene
Ein Eintrag in headingStyles übernimmt jedes Feld, das er auslässt, von seiner Überschriftenebene, breakBefore eingeschlossen. Ein Inhaltsverzeichnis oder Impressum, das nach einem :::pagebreak über eine H1 gestaltet wird, erbt die Parität 'odd' und landet hinter einer Vakatseite. Geben Sie einem solchen Format breakBefore: { enabled: false }. Überschriftenformate →
- Der ABC-Leser von Verovio übergeht die Haltezeichen
_und*einerw:-Zeile: Jede Note nimmt die nächste Silbe. Schreiben Sie unter die zweite Note eines Bogens ein geschütztes Leerzeichen (U+00A0) als eigene Silbe; es druckt nichts. Übergebundene Noten bekommen keine Silbe. ~verbindet zwei Silben unter einer Note (de~a-trás), aber der Notenstecher druckt sie mit einem normalen Leerzeichen, ohne Verbindungsbogen.- Schreiben Sie Akkordnamen möglichst ohne ♭ oder ♯: Die meisten Textschriften haben diese Zeichen nicht, und die Seite weicht auf eine Systemschrift aus. Wählen Sie Tonarten, deren Akkorde ohne Vorzeichen auskommen (G, C, D7, Em), oder nennen Sie B-Dur im Fließtext mit Worten.
Nachweise
- Rezept
- Ignacio Ferro
- Text
- Amazing Grace: words (1779, five of the six stanzas, in the Olney Hymns spelling) · John Newton · gemeinfrei
- Amazing Grace: the tune New Britain (Southern Harmony, 1835), melody as in E. O. Excell's setting of 1900, chord symbols added · Traditional American; William Walker; Edwin O. Excell · gemeinfrei
- Oh My Darling, Clementine: words and tune (Oliver Ditson, Boston, 1884) · Percy Montrose · gemeinfrei
- Auld Lang Syne: words (1788) and the Scots tune of George Thomson's Select Songs of Scotland (1799) · Robert Burns; traditional · gemeinfrei
- Cumpleaños feliz: the tune of Good Morning to All (Song Stories for the Kindergarten, Chicago, 1893); Spanish words traditional · Mildred J. Hill; traditional · gemeinfrei
- Martinillo: the French tune of Frère Jacques (18th century) with the traditional Spanish words · Traditional · gemeinfrei
- La cucaracha: tune, chorus and verse as in the Spanish Wikipedia transcription; two traditional Mexican coplas · Traditional · gemeinfrei
- The preface, the notes on the songs and the chord symbols · Ignacio Ferro · CC BY 4.0
- Schriften
- Spectral (SIL OFL 1.1) · Spectral SC (SIL OFL 1.1) · Fraunces (SIL OFL 1.1)
- Code
- MIT, wie Postext
Diesen Text bearbeiten ↗ (öffnet sich in einem neuen Tab)Ordner des Rezepts auf GitHub ↗ (öffnet sich in einem neuen Tab)


