Vai al contenuto principale
Ricetta numero 164

Ricettario · Capitolo 9 · Pubblicazioni complete

Un canzoniere con melodia, parole e accordi

Ogni canzone è un blocco ABC: la melodia, gli accordi sul pentagramma e la prima strofa sotto le note, incisi alla larghezza di colonna da un unico stile.

In questa pagina
Output
Canvas · PDF
Livello
Intermedio
Postext
Provata con Postext 1.54.0
Richiede ≥ 1.54.0 · postext-pdf ≥ 1.54.0
Licenza
Aggiornata il 22 ott 2026
Codice MIT · Testo CC BY 4.0

pp. 2–3 di 6

  • Esempio in inglese: non c’è ancora un’edizione italiana
  • Formato 148 × 210 mm
  • 1 colonna
  • Spectral 10,3/14
  • Fraunces
  • Spectral SC
  • 6 pagine
  • Livello
  • Postext 1.54.0
  • Impaginato in 300 ms
  • 164 righe di codice

In breve

Un piccolo canzoniere per cantare attorno a una tavola. Ogni canzone si scrive come testo semplice in una notazione musicale chiamata ABC, e Postext disegna il pentagramma, le note, gli accordi per chitarra e le parole sotto le note.

Che cosa comporrai

Songs for the Long Table, un canzoniere tascabile in formato A5: un frontespizio color robbia, una nota per chi canta con l'indice, tre canzoni e le note sulla provenienza di ciascuna. Ogni canzone si apre sotto un grande numero color robbia, un titolo in Fraunces e una riga di crediti in maiuscoletto. Sotto, la melodia corre su un pentagramma di 5,5 mm in Leland, con gli accordi per chitarra sopra le battute e la prima strofa sotto le note in Spectral, il carattere del testo del libro. Le strofe restanti stanno su due colonne, così chi canta legge dritto verso il basso dall'ultima battuta. Amazing Grace, i cui versi lunghi andrebbero a capo in una colonna, mette le strofe una sotto l'altra, centrate. L'edizione spagnola è un canzoniere per un compleanno con tre canzoni più brevi, due per pagina.

Questa ricetta risponde a

  • Come compongo un canzoniere con la melodia, le parole sotto le note e le sigle degli accordi?

La risposta breve

script.js · righe 33–50nel codice completo
// 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".

Ingredienti

Tipo
Spectral, Spectral SC, Fraunces (SIL OFL 1.1)
Risorse
Nessuna: ogni immagine è disegnata nel codice

Preparazione

#1 · Scrivi la canzone, definisci la partitura una volta sola

Lo stile di partitura è la risposta breve qui sopra. Nel Markdown ogni canzone è un blocco ```abc: le righe di intestazione danno il tempo, il valore di nota di riferimento e la tonalità; il nome di un accordo tra virgolette doppie ("D7"A) si stampa sopra la nota che precede; una riga w: sotto la musica mette una sillaba sotto ogni nota, separate da trattini. Un motivo con strofa e ritornello sono due righe di musica, ciascuna con la sua riga w:. La dimensione del pentagramma, il font musicale, il carattere delle parole, i numeri di battuta e lo spazio tra i sistemi vengono da scoreStyle, quindi le tre canzoni si somigliano e i blocchi contengono solo musica.

#2 · Apri ogni canzone sotto il suo numero e i suoi crediti

script.js · righe 66–81nel codice completo
// # 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 } };

La canzone è un titolo di primo livello con un attributo credit, e il suo design ne ricava il numero, il titolo e la riga dei crediti. minHeight dà a ogni canzone la stessa testa di 21 mm, così i pentagrammi cominciano alla stessa altezza su ogni pagina. Le canzoni si susseguono con tre righe di spazio sopra ogni titolo, e una partitura non si spezza mai prima del suo secondo sistema (minSystemsAtBreak: 2): le canzoni inglesi riempiono una pagina ciascuna, e due delle brevi canzoni spagnole ne condividono una.

#3 · Metti le altre strofe su due colonne

script.js · righe 54–62nel codice completo
// :::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) };

Ogni strofa è un blocco :::verse, perciò i suoi versi vanno a capo dove il poeta li ha spezzati e il secondo e il quarto rientrano di un quadratone. Un gruppo :::columns{count=2 gap=4mm} le affianca in corpo 9,4. Conta prima i caratteri: i versi di Burns entrano in una colonna di 55 mm, il metro lungo di Newton no, e per questo Amazing Grace tiene un solo blocco :::verse centrato e lascia che le righe vuote separino le strofe.

#4 · Tieni sobri gli elementi fissi

script.js · righe 119–131nel codice completo
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),
] };

Le testatine sono su ogni pagina che le canzoni raggiungono, il titolo del libro sulla pagina pari e la canzone sulla dispari, con il numero di pagina nel color robbia dei numeri delle canzoni. Il frontespizio e la nota per chi canta le tolgono con un header vuoto nei loro stili di titolo.

La ricetta completa

Sandbox
// ═══ 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

Lo script.js composto funziona così com’è: incollalo nello script modulo di qualsiasi pagina, oppure apri la ricetta su CodePen. Cartella della ricetta su GitHub ↗ (si apre in una nuova scheda)

Varianti

#Incidi in Bravura

Bravura ha teste di nota più spesse e l'aspetto di una lastra incisa; si addice a un innario composto in un carattere di testo più scuro.

-  musicFont: 'Leland', // lighter noteheads than Bravura, close to Spectral's colour
+  musicFont: 'Bravura',

#Numera le battute

Un coro prova seguendo i numeri di battuta; stampane uno all'inizio di ogni sistema.

-  barNumbers: 'none', // a table of singers counts verses, not bars
+  barNumbers: 'system',

Errori frequenti

Errore frequente

Uno stile di titolo eredita l’interruzione di pagina del suo livello

Una voce di headingStyles prende dal suo livello di titolo ogni campo che omette, breakBefore compreso. Un indice o un colophon con lo stile di un H1 dopo un :::pagebreak eredita parity 'odd' e finisce dietro una pagina bianca. Dai a uno stile del genere breakBefore: { enabled: false }. Stili di titolo →

  • Il lettore ABC di Verovio ignora i segni di prolungamento _ e * di una riga w:: ogni nota prende la sillaba successiva. Sotto la seconda nota di una legatura scrivi uno spazio non divisibile (U+00A0) come sillaba a sé; non stampa nulla. Le note unite da una legatura di valore non prendono sillaba.
  • ~ unisce due sillabe sotto una stessa nota (de~a-trás), ma l'incisore le stampa con uno spazio normale, senza il segno di sinalefe.
  • Scrivi i nomi degli accordi senza ♭ né ♯ quando puoi: la maggior parte dei caratteri di testo non ha quei segni e la pagina ripiega su un font di sistema. Scegli tonalità con accordi naturali (G, C, D7, Em) o scrivi «si bemolle» nel testo.

Crediti

Testo
Font
Spectral (SIL OFL 1.1) · Spectral SC (SIL OFL 1.1) · Fraunces (SIL OFL 1.1)
SandboxPDF