Saltar al contingut principal
Recepta número 164

Receptari · Capítol 9 · Publicacions completes

Un cançoner amb melodia, lletra i acords

Cada cançó és un bloc ABC: melodia, xifrats sobre el pentagrama i primera estrofa sota les notes, gravats a l'amplada de columna amb un estil de partitura.

En aquesta pàgina
Sortida
Canvas · PDF
Nivell
Intermedi
Postext
Provada amb Postext 1.54.0
Requereix ≥ 1.54.0 · postext-pdf ≥ 1.54.0
Llicència
Actualitzada el 22 d’oct. del 2026
Codi MIT · Text CC BY 4.0
  • Mostra en castellà: encara no hi ha edició en català
  • Format 148 × 210 mm
  • 1 columna
  • Spectral 10,3/14
  • Fraunces
  • Spectral SC
  • 5 pàgines
  • Nivell
  • Postext 1.54.0
  • Compost en 335 ms
  • 164 línies de codi

En poques paraules

Un cançoner petit per a un berenar. Cada cançó s'escriu com a text en una notació musical anomenada ABC, i Postext dibuixa el pentagrama, les notes, els acords de guitarra i la lletra sota les notes.

Què compondràs

El Cancionero de la merienda, un quadernet en A5 per a la tarda d'un aniversari: una portada en vermell garança, una nota per a qui canta amb l'índex, tres cançons i, al final, d'on ve cadascuna. Cada cançó s'obre sota un número gran en garança, el títol en Fraunces i una línia de crèdits en versaletes. A sota, la melodia en un pentagrama de 5,5 mm amb la font musical Leland, els acords de guitarra sobre els compassos i la primera estrofa sota les notes en Spectral, la lletra del llibre. Les cobles restants van a dues columnes. Com que les tres cançons són curtes, dues comparteixen pàgina. L'edició anglesa és un cançoner de sobretaula amb tres cançons llargues, una per pàgina.

Aquesta recepta respon a

  • Com componc un cançoner amb la melodia, la lletra sota les notes i els xifrats d'acords?

La resposta curta

script.js · línies 33–50al codi complet
// 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".

Ingredients

Tipografia
Spectral, Spectral SC, Fraunces (SIL OFL 1.1)
Recursos
Cap: totes les imatges es dibuixen en codi

Elaboració

#1 · Escriu la cançó i defineix la partitura una sola vegada

L'estil de partitura és la resposta curta de més amunt. Al Markdown cada cançó és un bloc ```abc: les línies de capçalera donen el compàs, la figura de referència i la tonalitat; un acord entre cometes ("C7"B) s'imprimeix sobre la nota que el segueix, i una línia w: sota la música posa una síl·laba sota cada nota, separades amb guionets. Una cançó amb tornada i cobla són dues línies de música, cadascuna amb la seva w:. La mida del pentagrama, la font musical, la lletra de les paraules, els números de compàs i l'espai entre sistemes surten de scoreStyle: les tres cançons lliguen i els blocs només porten música.

#2 · Obre cada cançó amb el seu número i els seus crèdits

script.js · línies 66–81al codi complet
// # 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 cançó és un títol de primer nivell amb un atribut credit, i el seu disseny hi compon el número, el títol i la línia de crèdits. minHeight dona a totes la mateixa capçalera de 21 mm, de manera que els pentagrames comencen a la mateixa altura. Les cançons van seguides, amb tres línies d'aire sobre cada títol, i una partitura no es talla mai abans del segon sistema (minSystemsAtBreak: 2): Cumpleaños feliz i Martinillo caben a la mateixa pàgina, i La cucaracha passa sencera a la següent.

#3 · Posa les altres cobles a dues columnes

script.js · línies 54–62al codi complet
// :::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) };

Cada cobla és un bloc :::verse, així que els versos es tallen on els va tallar la tradició i el segon i el quart entren un quadratí. Un grup :::columns{count=2 gap=4mm} les posa l'una al costat de l'altra a 9,4 pt. Compta abans els caràcters: els octosíl·labs de La cucaracha caben de sobres en una columna de 55 mm; els versos llargs d'Amazing Grace, a l'edició anglesa, no, i per això aquesta cançó deixa les estrofes en un sol bloc centrat.

#4 · Deixa tranquils els elements fixos

script.js · línies 119–131al codi complet
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),
] };

Les capçaleres són a totes les pàgines de cançons: el títol del llibre a la pàgina parell i la cançó a la senar, amb el foli en el garança dels números. La portada i la nota per a qui canta les treuen amb un header buit en els seus estils de títol.

La recepta 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 = 'es'; // @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

L'script.js compost funciona tal com és: enganxa'l com a script de mòdul en qualsevol pàgina o obre la recepta a CodePen. Carpeta de la recepta a GitHub ↗ (s'obre en una pestanya nova)

Variants

#Grava en Bravura

Bravura té caps de nota més gruixuts i un aire de planxa gravada; li escau a un cantoral compost en una lletra més fosca.

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

#Numera els compassos

Un cor assaja per números de compàs; imprimeix-ne un al començament de cada sistema.

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

Errors freqüents

Error freqüent

Un estil de títol hereta el salt de pàgina del seu nivell

Una entrada de headingStyles pren del seu nivell de títol tot allò que no fixa, també breakBefore. Un índex o un colofó amb estil sobre un H1 després d'un :::pagebreak hereta la paritat 'odd' i cau darrere d'una pàgina en blanc. Dona a aquest estil breakBefore: { enabled: false }. Estils de títol →

  • El lector ABC de Verovio no fa cas de les marques _ i * d'una línia w:: cada nota pren la síl·laba següent. Sota la segona nota d'una lligadura escriu un espai no separable (U+00A0) com a síl·laba pròpia; no imprimeix res. Les notes lligades per - no prenen síl·laba.
  • ~ uneix dues síl·labes sota una mateixa nota (de~a-trás), però el gravador les imprimeix amb un espai normal, sense el signe de sinalefa.
  • Escriu els acords sense ♭ ni ♯ quan puguis: la majoria de les lletres de text no tenen aquests signes i la pàgina recorre a una font del sistema. Tria tonalitats amb acords naturals (sol, do, re7, mi menor) o escriu «si bemoll» al text.

Crèdits

Text
Fonts
Spectral (SIL OFL 1.1) · Spectral SC (SIL OFL 1.1) · Fraunces (SIL OFL 1.1)
SandboxPDF