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
// :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
- Funzionalità
- EvidenziazioniRiquadriTavolozza di colori semanticaAperture progettateImmagini nei progetti di paginaAttributi dei titoliTestatine e folioTestatine secondo il ruolo della paginaMargini speculariStili di paragrafoVedove, orfane e righe corte
- Usa anche
- Bibliografie e glossariFigura e Tabella nella tua linguaTipi di risorsa personalizzatiFigure e tabelle come risorse
- 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
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
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à
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
// ═══ 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 bandErrori 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
markStylesnon dichiara prende il primo stile, senza errori sulla pagina (il Sandbox lo segnala). Usa id brevi e controlla come li scrivi nel testo.
Crediti
- Ricetta
- Ignacio Ferro
- 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)
- Codice
- MIT, come Postext
Modifica questo testo ↗ (si apre in una nuova scheda)Cartella della ricetta su GitHub ↗ (si apre in una nuova scheda)


