Vai al contenuto principale
Ricetta numero 180

Ricettario · Capitolo 2 · Caratteri e testo

Evidenziazioni a colori in un libro di letture

Un libro di letture di storia le cui parole chiave hanno tre colori (verde per i termini, ambra per le date, blu per i nomi) presi da tre markStyles.

  • Esempio in inglese: non c’è ancora un’edizione italiana
  • Formato 170 × 240 mm
  • 1 colonna
  • Source Serif 4 10,5/14,5
  • Source Sans 3
  • 4 pagine
  • Livello
  • Postext 1.65.0
  • Impaginato in 127 ms
  • 164 righe di codice

In breve

Una lettura scolastica sulla storia della stampa. I termini chiave sono evidenziati in verde, le date in ambra, le persone e i luoghi in blu, e una legenda nella prima pagina dice che cosa significa ogni colore.

Che cosa comporrai

La lettura 2 di un’unità di un libro scolastico di storia, Readings in Early Modern History: quattro pagine su come la stampa si diffuse in Europa da Magonza tra il 1450 e il 1550, su una pagina di 170 × 240 mm. I curatori hanno segnato il testo come farebbe uno studente attento, con un codice che resta lo stesso in tutto il libro: i termini chiave su una fascia verde, le date sull’ambra, le persone e i luoghi sull’azzurro. Una legenda sotto il titolo spiega il codice con i tre colori stessi, e il glossario dell’ultima pagina apre ogni voce con il suo termine verde. I segni sono fasce sotto testo normale, quindi le righe vanno a capo, si sillabano e si giustificano come se le fasce non ci fossero.

Questa ricetta risponde a

  • Come evidenzio le parole chiave di un testo di studio con colori che abbiano ciascuno un significato (termini, date, nomi)?

La risposta breve

script.js · righe 37–52nel codice completo
// :mark[Mainz]{style="name"} in the text picks a style by id. The band is painted under
// words that stay ordinary text, so the lines break, hyphenate and justify as if the
// mark were not there, and a mark that runs over a line end gets a band on each line.
const band = (id, name) => ({
  id, name,
  background: col(id), // pale enough for ink at full contrast on top
  color: col('ink'), // the words keep the colour of the text
  // borderRadius: 0 is the default (square ends, as a highlighter pen leaves them)
  paddingX: em(0.12), // the band reaches a little past the first and the last letter
  paddingTop: em(0.04), paddingBottom: em(0.1), // and down past the descenders
});
const markStyles = [
  band('term', t({ en: 'Key term', es: 'Término clave' })),
  band('date', t({ en: 'Date', es: 'Fecha' })),
  band('name', t({ en: 'Name', es: 'Nombre' })),
];

Ingredienti

Tipo
Source Serif 4, Source Sans 3 (SIL OFL 1.1)
Risorse
  • press-1400.jpg
  • The printing workshop on the opening page, a painting (Generated With Diffusion Models, originale)

Preparazione

#1 · Uno stile per ogni tipo di parola

Il codice è nella risposta breve qui sopra. markStyles dichiara tre stili con nome, e il testo ne sceglie uno per ogni segno: :mark[Johann Fust]{style="name"}, :mark[1455]{style="date"}, :mark[colophon]{style="term"} (evidenziazioni). Ogni stile dice che cosa significa (name è ciò che vede chi cura il testo), così il Markdown registra perché una parola è segnata e non di che colore è. Se cambi il colore di uno stile, cambiano con lui tutte le date del libro. Le estremità sono dritte, come di default da postext 1.52 (stili di evidenziazione): un evidenziatore lascia estremità dritte, e una fascia arrotondata si legge come un chip.

#2 · Tre tinte dalla tavolozza

script.js · righe 14–29nel codice completo
const palette = {
  ink: '#1f1c19', // text: a warm near-black
  accent: '#8a3220', // kickers, rules, numbers: an iron-gall red
  tint: '#f5f0e7', // the key's background
  rule: '#d3cabc', // hairlines
  muted: '#6b645b', // running heads, colophon
  paper: '#ffffff',
  term: '#cce8c8', // key terms: a pale green
  date: '#fbe0a1', // dates: amber
  name: '#cfe0f4', // people and places: a pale blue
};
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' } })),
  { id: 'main-color', name: 'accent (defaults)', value: { hex: palette.accent, model: 'hex' } },
];

Le tre fasce sono voci della tavolozza come l’inchiostro e l’accento, quindi chi apre il libro nel Sandbox può ricolorare il codice da un solo campione. Sono chiare, vicine alla luminosità del fondo del riquadro, e il testo sopra di esse mantiene un contrasto di 12,6:1 o più; le tre restano distinte quando si incontrano su una riga, come in «In 1517 Martin Luther» a pagina 3. Un segno non occupa spazio: paddingX entra di 0,12 em nello spazio accanto alla frase e paddingBottom porta la fascia sotto i discendenti, entrambi dipinti in uno spazio che c’era già.

#3 · L’apertura: un dipinto sopra il titolo

script.js · righe 56–81nel codice completo
const opener = {
  enabled: true,
  minHeight: mm(122), // the floor of the opener: the key starts on the same line
  marginBottom: pt(0),
  slot: {
    elements: [
      { kind: 'image', id: 'press', resourceId: 'press', fit: 'cover',
        placement: { anchor: { to: 'page', edge: 'top-left' },
          size: { width: mm(170), height: mm(96) } } },
      { kind: 'text', id: 'kicker', content: '{attr.kicker}', fontFamily: SANS,
        fontSize: pt(8.5), fontWeight: 700, letterSpacing: pt(1.6),
        textTransform: 'uppercase', color: col('accent'), align: 'left',
        placement: { anchor: { to: 'container', edge: 'top-left' },
          offset: { x: mm(0), y: mm(82) } } },
      { kind: 'text', id: 'title', content: '{titleText}', fontFamily: SERIF,
        fontSize: pt(26), lineHeight: 1.08, fontWeight: 700, color: col('ink'), align: 'left',
        placement: { anchor: { to: '#kicker', edge: 'below' }, offset: { x: mm(0), y: mm(2) },
          size: { width: mm(126), height: 'auto' } } },
      { kind: 'text', id: 'standfirst', content: '{attr.standfirst}', fontFamily: SERIF,
        italic: true, fontSize: pt(10.5), lineHeight: LEAD / 10.5, color: col('ink'),
        align: 'left',
        placement: { anchor: { to: '#title', edge: 'below' }, offset: { x: mm(0), y: mm(3) },
          size: { width: mm(118), height: 'auto' } } },
    ],
  },
};

Il titolo di primo livello stampa un design. Il dipinto è ancorato alla pagina, quindi va al vivo in alto e sui due lati, 170 per 96 mm, con fit: 'cover'. L’occhiello e il sommario vengono da attributi della riga del titolo (attributi dei titoli), e la legenda segue come un normale :::callout le cui voci di elenco cominciano con i tre segni. minHeight fissa la profondità: la legenda comincia sulla stessa riga per quanto lungo sia il titolo.

#4 · Testatine secondo la parità

script.js · righe 85–106nel codice completo
const head = (id, content, parity, edge, x, extra = {}) => ({
  kind: 'text', id, content, parity, pages: 'body',
  fontFamily: SANS, fontSize: pt(7.5), fontWeight: 600, letterSpacing: pt(1.2),
  textTransform: 'uppercase', color: col('muted'),
  placement: { anchor: { to: 'page', edge }, offset: { x: mm(x), y: mm(13) } },
  ...extra,
});
const folio = { fontWeight: 700, color: col('ink') };
const header = {
  elements: [
    head('verso-folio', '{pageNumber}', 'even', 'top-left', OUTER, folio),
    head('verso-title', '{title}', 'even', 'top-left', OUTER + 9),
    head('recto-title', '{chapterTitle}', 'odd', 'top-right', -(OUTER + 9)),
    head('recto-folio', '{pageNumber}', 'odd', 'top-right', -OUTER, folio),
  ],
};
const footer = {
  elements: [head('drop-folio', '{pageNumber}', 'all', 'top', 0, {
    ...folio, pages: 'opener',
    placement: { anchor: { to: 'container', edge: 'top' }, offset: { x: mm(0), y: mm(9) } },
  })],
};

La pagina pari porta il titolo della collana e la dispari quello della lettura, filtrati con parity e tenuti fuori dall’apertura da pages: 'body' (elementi di testo). L’apertura porta il numero di pagina al piede.

La ricetta completa

Sandbox
// ═══ Postext Cookbook · Nº 180 · Colour-coded highlights in a study reader ════════
// https://postext.dev/en/cookbook/colour-coded-study-highlights
// Code: MIT · Text: original (CC BY 4.0) · Picture: painting made for the recipe
// Fonts: Source Serif 4, Source Sans 3 (SIL OFL 1.1) · Needs postext ≥ 1.65.0
import {
  buildDocumentWithFonts, renderPageToCanvas, registerResourceImage, defaultResourceTypes,
} from 'https://esm.sh/postext';

const LANG = 'en'; // @lang: the language of the sample document ('en' | 'es')
const RECIPE = 'colour-coded-study-highlights';

// ─── 1 · Design ─────────────────────────────────────────────────────────────
// #region palette: semantic colours, three of them for the highlighter
const palette = {
  ink: '#1f1c19', // text: a warm near-black
  accent: '#8a3220', // kickers, rules, numbers: an iron-gall red
  tint: '#f5f0e7', // the key's background
  rule: '#d3cabc', // hairlines
  muted: '#6b645b', // running heads, colophon
  paper: '#ffffff',
  term: '#cce8c8', // key terms: a pale green
  date: '#fbe0a1', // dates: amber
  name: '#cfe0f4', // people and places: a pale blue
};
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' } })),
  { id: 'main-color', name: 'accent (defaults)', value: { hex: palette.accent, model: 'hex' } },
];
// #endregion
const OUTER = 20; // outer margin in mm: the running heads align to it
const LEAD = 14.5; // body leading in pt
const SANS = 'Source Sans 3';
const SERIF = 'Source Serif 4';

// #region answer: three highlight styles, one per kind of word, linked to the palette
// :mark[Mainz]{style="name"} in the text picks a style by id. The band is painted under
// words that stay ordinary text, so the lines break, hyphenate and justify as if the
// mark were not there, and a mark that runs over a line end gets a band on each line.
const band = (id, name) => ({
  id, name,
  background: col(id), // pale enough for ink at full contrast on top
  color: col('ink'), // the words keep the colour of the text
  // borderRadius: 0 is the default (square ends, as a highlighter pen leaves them)
  paddingX: em(0.12), // the band reaches a little past the first and the last letter
  paddingTop: em(0.04), paddingBottom: em(0.1), // and down past the descenders
});
const markStyles = [

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

#Arrotonda le estremità delle fasce

Un raggio di un quinto del corpo dà le estremità morbide di un pennarello.

-  // borderRadius: 0 is the default (square ends, as a highlighter pen leaves them)
+  borderRadius: em(0.2), // soft ends, as a felt-tip pen leaves them

#Dai a ogni riga la sua fascia

Con decorationBreak: 'clone', un segno che va a capo riceve il margine alle due estremità di ogni pezzo, come a pagina 3, dove «pamphlets» si spezza dopo «pam-».

   paddingX: em(0.12), // the band reaches a little past the first and the last letter
+  decorationBreak: 'clone', // each line piece gets a whole band

Errori frequenti

  • Il colore da solo non sopravvive a una fotocopia in bianco e nero, che è il modo in cui molte letture arrivano in classe. Il glossario mette in più i termini in neretto; se i tuoi lettori fotocopieranno le pagine, dai a uno dei tre tipi un secondo segno tutto suo.
  • Un id di stile che markStyles non dichiara prende il primo stile, senza errori sulla pagina (il Sandbox lo segnala). Usa id brevi e controlla come li scrivi nel testo.

Crediti

Testo
  • The reading, its key, the review questions and the colophon · Ignacio Ferro · CC BY 4.0
Immagini
  • The printing workshop on the opening page, a painting · Generated With Diffusion Models · originale
Font
Source Serif 4 (SIL OFL 1.1) · Source Sans 3 (SIL OFL 1.1)
Sandbox