Saltar al contenido principal
Receta número 163

Recetario · Capítulo 12 · Libros de texto

Un manual de armonía con ejemplos musicales en ABC

Un capítulo sobre las cadencias cuyos ejemplos son bloques ABC en el Markdown, grabados al ancho de la columna; uno de ellos sigue en la página siguiente.

En esta página
Salida
Canvas · PDF
Postext
Probada con Postext 1.54.0
Requiere ≥ 1.54.0 · postext-pdf ≥ 1.54.0
Licencia
Actualizada el 22 oct 2026
Código MIT · Texto CC BY 4.0

pp. 2–3 de 4

  • Formato 180 × 250 mm
  • 1 columna
  • Libre Caslon Text 10,5/14,5
  • Libre Caslon Display
  • Libre Franklin
  • 4 páginas
  • Nivel
  • Postext 1.54.0
  • Compuesto en 15 ms
  • 152 líneas de código

En pocas palabras

Un capítulo de un manual de teoría musical sobre cómo terminan las frases. Los ejemplos se escriben como texto dentro del capítulo y Postext los dibuja como pentagramas; el más largo sigue en la página siguiente.

Lo que vas a componer

El capítulo 5 de un curso de armonía al teclado, de 180 × 250 mm en Libre Caslon, sobre las cinco cadencias: perfecta, imperfecta, semicadencia, plagal y rota. Cada cadencia lleva dos párrafos breves y un ejemplo a tres voces con sus números romanos bajo el pentagrama, escrito en ABC dentro del propio Markdown. El capítulo termina con Greensleeves en la menor, con un número romano sobre cada compás, y esa melodía no cabe en lo que queda de la página 3: pone allí tres sistemas y los dos últimos en la cabeza de la página 4, partida entre sistemas igual que un párrafo se parte entre líneas. El tamaño del pentagrama, la fuente musical y el espaciado se fijan una sola vez en la configuración, así que los cinco ejemplos y la melodía comparten el mismo aspecto.

Esta receta responde a

  • ¿Cómo pongo ejemplos musicales en el texto de un libro de texto, escritos como notación?

La respuesta corta

script.js · líneas 36–51en el código completo
// Each ```abc fence in the chapter is engraved at the width of the text column and cut
// into systems. The style is set once here; the Markdown only holds the notation.
const scoreStyle = {
  staffSize: mm(5.5), // a textbook's rastral: examples read at arm's length on a desk
  musicFont: 'Bravura', // the traditional engraved look, heavy enough beside Caslon
  textFont: 'Libre Caslon Text', // the Roman numerals of `w:` lines, in the text face
  spacing: 1.6, // air between the chords: an example reads as a progression, not a cluster
  barNumbers: 'system',
  systemGap: mm(4),
  marginTop: pt(LEAD / 2),
  marginBottom: pt(LEAD / 2),
  color: col('ink'),
  // A long example runs on into the next page between two systems, never leaving one
  // system alone at the foot of a page or at the head of the next.
  minSystemsAtBreak: 2,
};

Ingredientes

Tipografía
Libre Caslon Text, Libre Caslon Display, Libre Franklin (SIL OFL 1.1)
Recursos
Ninguno: todas las imágenes se dibujan en código

Elaboración

#1 · Escribe el ejemplo donde lo pide el texto

Un bloque marcado abc contiene la notación, y el texto sigue después. L:1/2 hace de cada acorde sin duración una blanca, [Bdg] apila tres notas en una sola voz y una línea w: pone una palabra bajo cada acorde, aquí los números romanos. El atributo alt es lo que leen un lector de pantalla y el PDF etiquetado en lugar de la imagen.

```abc {alt="Cadencia perfecta en sol mayor: I, IV, V, I"}
X:1
M:4/4
L:1/2
K:G
[Bdg] [ceg] | [Adf] [Bdg] |]
w: I IV V I
```

#2 · Da a cada partitura el aspecto del libro

La respuesta corta es todo el diseño de la música: un pentagrama de 5,5 mm, el que usan los manuales de armonía para ejemplos que se leen sentado al piano, Bravura junto al texto en Caslon y los números en la letra del texto en lugar de la Times del grabador. spacing: 1.6 reparte cuatro acordes de blanca por un tercio de la caja, de modo que la progresión se lee acorde a acorde. El mismo ajuste decide cuántos compases de Greensleeves caben en un sistema: tres, en una caja de 125 mm.

#3 · Deja que un ejemplo largo continúe

minSystemsAtBreak: 2 es lo que mantiene legible Greensleeves al pasar la página. La melodía sale en cinco sistemas; tres caben al pie de la página 3, así que dos pasan a la 4, y ninguna página se queda con un sistema suelto. Una partitura de menos de cuatro sistemas pasa entera a la página siguiente, como harían los ejemplos breves de cadencias.

#4 · Arranca el grabador antes de componer

script.js · líneas 263–269en el código completo
// The engraver (Verovio) loads only for books with music: start it before the build,
// or every score is laid out as a grey placeholder box.
await initMusicEngine();
const doc = await buildDocumentWithFonts({ markdown }, config, kitFonts(FONTS));
showPages(doc, { title: t({ en: 'Harmony textbook', es: 'Manual de armonía' }) });
// The PDF draws every system as vector paths, the numerals in the embedded text face.
offerPdf(() => renderToPdf(doc, { fontProvider: fontsourceProvider }), `${RECIPE}.pdf`);

Verovio ocupa unos 3,7 MB de WebAssembly, así que el motor solo lo carga cuando se lo pides. Sin initMusicEngine() la composición se hace igual y cada partitura es un recuadro gris del tamaño correcto. renderToPdf no necesita nada más: el PDF dibuja cada sistema como trazados vectoriales y pone los números en la Caslon incrustada.

#5 · Abre el capítulo con el título hundido

script.js · líneas 55–72en el código completo
const opener = {
  enabled: true,
  minHeight: mm(48),
  slot: { elements: [
    { kind: 'text', id: 'kicker', content: '{attr.kicker}', fontFamily: LABEL, fontSize: pt(8.5),
      fontWeight: 700, letterSpacing: pt(1.7), textTransform: 'uppercase', color: col('accent'),
      align: 'left', placement: { anchor: { to: 'container', edge: 'top-left' },
        offset: { x: mm(0), y: mm(12) } } },
    { kind: 'text', id: 'title', content: '{titleText}', fontFamily: 'Libre Caslon Display',
      fontSize: pt(34), lineHeight: 1.05, color: col('ink'), align: 'left', overflow: 'wrap',
      placement: { anchor: { to: '#kicker', edge: 'below' }, offset: { x: mm(0), y: mm(3) },
        size: { width: mm(110), height: 'auto' } } },
    { kind: 'rule', id: 'rule', direction: 'horizontal', thickness: pt(1.5),
      color: col('accent'),
      placement: { anchor: { to: '#title', edge: 'below' }, offset: { x: mm(0), y: mm(5) },
        size: { width: mm(16) } } },
  ] },
};

La apertura toma el antetítulo del atributo kicker del título y reserva 48 mm, lo justo para el título y su filete con el primer ejemplo todavía en la página 1.

La receta completa

Sandbox
// ═══ Postext Cookbook · Nº 163 · Harmony textbook with ABC examples ═════════════
// https://postext.dev/en/cookbook/harmony-textbook-abc-examples
// Code: MIT · Text: original (CC BY 4.0) · Music: Greensleeves (traditional, PD)
// Fonts: Libre Caslon Text & Display, Libre Franklin (SIL OFL 1.1) · 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 = 'harmony-textbook-abc-examples';

// ─── 1 · Design ─────────────────────────────────────────────────────────────
// #region palette: a conservatory green for the accents, warm ink for text and notes
const palette = {
  ink: '#1f1c19', // text and notation: a warm near-black
  accent: '#2f5d4f', // kickers, rules, Roman numerals in the table
  tint: '#edf2ef', // the box of key terms
  rule: '#c3cfc9', // hairlines
  muted: '#5c6863', // running heads, colophon
  paper: '#ffffff',
};
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, never the default blue.
  { id: 'main-color', name: 'accent (defaults)', value: { hex: palette.accent, model: 'hex' } },
];
// #endregion
const TRIM = { width: 180, height: 250 };
const MARGIN = { top: 22, bottom: 24, inner: 22, outer: 33 }; // a 125 mm measure
const LEAD = 14.5; // body leading in pt: the baseline grid
const LABEL = 'Libre Franklin';

// #region answer: one score style for every example in the text
// Each ```abc fence in the chapter is engraved at the width of the text column and cut
// into systems. The style is set once here; the Markdown only holds the notation.
const scoreStyle = {
  staffSize: mm(5.5), // a textbook's rastral: examples read at arm's length on a desk
  musicFont: 'Bravura', // the traditional engraved look, heavy enough beside Caslon
  textFont: 'Libre Caslon Text', // the Roman numerals of `w:` lines, in the text face
  spacing: 1.6, // air between the chords: an example reads as a progression, not a cluster
  barNumbers: 'system',
  systemGap: mm(4),
  marginTop: pt(LEAD / 2),
  marginBottom: pt(LEAD / 2),
  color: col('ink'),
  // A long example runs on into the next page between two systems, never leaving one

El script.js compuesto funciona tal cual: pégalo como script de módulo en cualquier página o abre la receta en CodePen. Carpeta de la receta en GitHub ↗ (se abre en una nueva pestaña)

Variantes

#Usa Leland para una página más ligera

Leland, la fuente de MuseScore, tiene plicas más finas y cabezas más pequeñas que Bravura; va bien con un libro compuesto en una letra de texto ligera.

-  musicFont: 'Bravura',
+  musicFont: 'Leland',

#Escribe una segunda voz en otro formato

El lector de ABC toma una sola voz. Para un soprano y un bajo en pentagramas distintos, escribe el ejemplo en Humdrum o en MusicXML; el método de conservatorio compone así corales a cuatro voces.

Errores frecuentes

  • Escribe la duración de un acorde dentro de los corchetes, [B2d2g2], o ajusta L: al valor del acorde: una duración tras el corchete, [Bdg]2, se lee como la duración por defecto.
  • El lector de ABC de Verovio da cada sílaba de una línea w: a la nota siguiente e ignora * y _, así que una línea w: no puede saltarse notas. Para señalar unos pocos compases, escribe las marcas como cifrados sobre el pentagrama, como hace el ejemplo de Greensleeves.
  • Una letra de texto rara vez trae los signos ♯ y ♭: escribe «fa sostenido» en la prosa, o el navegador pondrá el signo con una fuente del sistema.

Créditos

Texto
  • El capítulo sobre las cadencias y sus ejemplos, escritos para esta receta · Ignacio Ferro · CC BY 4.0
  • Greensleeves, canción inglesa del siglo XVI, en su forma moderna habitual · Traditional · dominio público
Fuentes
Libre Caslon Text (SIL OFL 1.1) · Libre Caslon Display (SIL OFL 1.1) · Libre Franklin (SIL OFL 1.1)
SandboxPDF