Kurz gesagt
Ein kleiner gedruckter Führer zu fünf Gemälden. Wo der Text eine Webseite nennt, führt eine kleine Ziffer an den Fuß der Seite, wo ein quadratischer Code diese Seite auf dem Handy öffnet.
Was Sie setzen
Ein Taschenführer durch die holländischen Säle des Metropolitan Museum of Art: fünf Gemälde, eine Stunde zu Fuß, ein Gemälde je Seite. Den Umschlag bildet Vermeers junge Frau am Fenster, vom oberen Seitenrand angeschnitten. Jede Station beginnt mit Saalnummer, Titel und Maler, dann folgt das Bild mit dem Saaltext daneben, dann drei kurze Absätze. Der Text verlinkt auf den Katalog des Museums wie jede Webseite. Auf Papier wird jeder Link zu einer kleinen Ziffer, und am Fuß der Seite nennt die Anmerkung die Kurzadresse und einen QR-Code, den der Besucher vor dem Bild mit dem Handy erfasst.
Dieses Rezept beantwortet
- Wie drucke ich die Webadressen der Links eines Buchs als nummerierte Anmerkungen oder als QR-Codes, die der Leser scannen kann?
Die kurze Antwort
const links = {
print: 'notes', // a note marker after the link text, the address in a note at the foot
show: 'both', // the short address for reading, the code for the phone
urlDisplay: 'short', // metmuseum.org/art/collection/search/436616: no https://, no www.
repeat: 'first', // an address noted once is cited again by its number, never noted twice
qr: { size: mm(16), side: 'start', gap: em(1.2), color: col('ink') },
};
// Link notes are footnotes: they take the note style and the numbering below. 'document'
// numbers them through the walk, so the five stops print notes 3 to 7, not five notes 1.
const footnotes = { placement: 'column', numbering: 'document', fontSize: pt(8),
lineHeight: pt(10.5), color: col('muted'), spaceAbove: pt(LEAD), spaceBetween: pt(5),
separator: { enabled: true, width: 0.18, lineWidth: pt(0.5), color: col('rule') } };
Zutaten
- Funktionen
- Linkadressen im DruckFußnotenGestaltete AuftakteÜberschriftenattributeBilder in SeitengestaltungenLeitwörter im KolumnentitelKolumnentitel und SeitenzahlenKopfzeilen nach SeitenrolleAbbildungen genau hierSeitliche BildunterschriftenEigene RessourcentypenQuellen- und BildnachweiseSemantische FarbpalettePDF-Export
- Nutzt außerdem
- Kapitelband über die ganze BreiteAbsatzformateIm PDF eingebettete SchriftenAbbildungen und Tabellen als Ressourcen
- Schrift
- Newsreader, Instrument Serif, Archivo (SIL OFL 1.1)
- Dateien
hals-1200.jpgrembrandt-1200.jpgruisdael-1400.jpgsteen-1200.jpgvermeer-1600.jpgvermeer-cover-1800.jpg- Johannes Vermeer, Young Woman with a Water Pitcher, about 1662 (the cover, cropped) (The Metropolitan Museum of Art, CC0 1.0)
- Frans Hals, Young Man and Woman in an Inn, 1623 (stop 1) (The Metropolitan Museum of Art, CC0 1.0)
- Jan Steen, Merry Company on a Terrace, about 1670 (stop 2) (The Metropolitan Museum of Art, CC0 1.0)
- Rembrandt, Aristotle with a Bust of Homer, 1653 (stop 3) (The Metropolitan Museum of Art, CC0 1.0)
- Johannes Vermeer, Young Woman with a Water Pitcher, about 1662 (stop 4) (The Metropolitan Museum of Art, CC0 1.0)
- Jacob van Ruisdael, Wheat Fields, about 1670 (stop 5) (The Metropolitan Museum of Art, CC0 1.0)
Zubereitung
#1 · Links schreiben, Anmerkungen drucken
Der Code steht oben in der kurzen Antwort. Das Markdown behält gewöhnliche Links, [Der Katalogeintrag](https://www.metmuseum.org/…/436616), und links.print: 'notes' macht aus jedem eine nummerierte Anmerkung mit Adresse und Code (Links im Druck). Die Anmerkungen sind Fußnoten: numbering: 'document' zählt sie über den ganzen Rundgang, der Leser trifft also auf 1 bis 7, und repeat: 'first' lässt die letzte Station den Hals mit seiner Anmerkung 3 zitieren, statt denselben Code zweimal zu drucken. Im PDF ist der Code als Vektorgrafik gezeichnet und selbst ein Link.

#2 · Eine Station je Seite
const stop = { enabled: true, minHeight: pt(4 * LEAD), slot: { elements: [
{ kind: 'text', id: 'stop', content: '{attr.stop}', ...caps(7.5), color: col('delft'),
align: 'left', placement: at('container', 'top-left', 0, 0) },
{ kind: 'text', id: 'title', content: '{titleText}', fontFamily: DISPLAY, fontSize: pt(22),
lineHeight: 1.05, color: col('ink'), align: 'left', placement: at('#stop', 'below', 0, 1.6) },
{ kind: 'text', id: 'artist', content: '{attr.artist}', fontFamily: TEXT, italic: true,
fontSize: pt(10.5), color: col('muted'), align: 'left',
placement: at('#title', 'below', 0, 0.8) },
] } };
Jede Station ist eine Überschrift zweiter Ebene, deren breakBefore eine neue Seite beginnt, links oder rechts, sodass der Besucher je Gemälde ein Blatt umschlägt. Saalnummer und Maler sind Attribute der Überschrift; die Gestaltung setzt sie über und unter den Titel, und minHeight hält das Bild auf jeder Seite auf derselben Höhe.
#3 · Der Saaltext neben dem Bild
// Paintings are not numbered: their own type, with no caption prefix and no number.
const paintingType = { id: 'painting', name: t({ en: 'Painting', es: 'Cuadro' }),
shortLabel: t({ en: 'painting', es: 'cuadro' }), captionPrefix: '', numberingTemplate: '',
resetOn: 'never', counterFormat: 'decimal' };
// Set where the ::resource line stands, under the stop's heading; caption and note beside it.
const HERE = { position: 'here', captionSide: 'inside' };
const cm = (n) => (LANG === 'es' ? String(n).replace('.', ',') : String(n)); // decimal comma
// The wall label: medium, size in cm (no-break spaces) and the museum's credit line.
const painting = (id, w, h, [cmH, cmW], credit, alt, width = 0.5) => ({
id, typeId: 'painting', kind: 'bitmap', createdAt: 0, updatedAt: 0, placement: { ...HERE, width },
bitmap: { fileId: `${id}-${Math.max(w, h)}.jpg`, format: 'jpeg', width: w, height: h },
caption: `${OIL}, ${cm(cmH)}\u00a0×\u00a0${cm(cmW)}\u00a0cm. ${credit}`, altText: alt,
note: 'The Metropolitan Museum of Art, Open Access (CC0)' });
const OIL = t({ en: 'Oil on canvas', es: 'Óleo sobre lienzo' });
const ALTMAN = t({ en: 'Bequest of Benjamin Altman, 1913', es: 'Legado de Benjamin Altman, 1913' });
const resources = [
painting('hals', 908, 1200, [105.4, 79.4], `${ALTMAN} (14.40.602)`, t({
en: 'A laughing young man raises a glass; a young woman leans on his shoulder.',
es: 'Un joven ríe y alza una copa; una joven se apoya en su hombro.' }), 0.4), // portrait
painting('steen', 1115, 1200, [141, 131.4], 'Fletcher Fund, 1958 (58.89)', t({
en: 'A crowded party under a vine, with a lute player, a child and a dog.',
es: 'Una fiesta concurrida bajo una parra, con un laudista, un niño y un perro.' })),
painting('rembrandt', 1139, 1200, [143.5, 136.5], t({
en: 'Purchase, special contributions and funds given or bequeathed by friends of the Museum',
es: 'Compra con aportaciones y fondos donados o legados por amigos del Museo' })
+ ', 1961 (61.198)', t({ en: 'A bearded man in a black hat rests his hand on a marble bust.',
es: 'Un hombre barbado con sombrero negro apoya la mano en un busto de mármol.' })),
painting('vermeer', 1422, 1600, [45.7, 40.6], t({ en: 'Marquand Collection, gift of',
es: 'Colección Marquand, donación de' }) + ' Henry G. Marquand, 1889 (89.15.21)', t({
en: 'A young woman at an open window holds a gilt pitcher over a basin.',
es: 'Una joven junto a una ventana abierta sujeta una jarra dorada sobre una jofaina.' })),
painting('ruisdael', 1400, 1084, [100, 130.2], `${ALTMAN} (14.40.623)`, t({
en: 'A sandy road between wheat fields under a tall bank of cloud.',
es: 'Un camino de arena entre campos de trigo bajo un alto banco de nubes.' }), 0.6),
// The cover: the Vermeer cut to the box's 4 : 3 (160 × 120 mm), since the opener fits a
// picture inside its box. Drawn by the cover design, never cited.
{ ...painting('vermeer-cover', 1800, 1350, [], '', t({
en: 'Detail of Vermeer’s young woman at the window, in blue and white.',
es: 'Detalle de la joven de Vermeer junto a la ventana, en azul y blanco.' })),
caption: '', note: '' },
];
captionSide: 'inside' setzt Bildunterschrift und Nachweis neben das Bild, wie ein Museum seinen Saaltext hängt, und width gibt jedem Bild seinen Anteil an der Satzbreite: weniger für den hohen Hals, mehr für den breiten Ruisdael, damit die fünf Seiten eine ähnliche Textmenge tragen. Der Saaltext setzt sich aus Technik, Maßen in Zentimetern mit geschützten Leerzeichen und der Erwerbungszeile des Museums zusammen, in der spanischen Ausgabe mit Dezimalkomma.
#4 · Die Station im Kolumnentitel
const head = (id, content, parity, edge, x, extra = {}) => ({
kind: 'text', id, content, parity, pages: 'body', ...caps(7, 600), color: col('muted'),
placement: at('page', edge, x, 13), ...extra,
});
const folio = { ...caps(8, 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-stop', '{firstMark.h2}', 'odd', 'top-right', -(OUTER + 9)),
head('recto-folio', '{pageNumber}', 'odd', 'top-right', -OUTER, folio),
] };
{firstMark.h2} druckt den Titel der Station, die auf der Seite beginnt: Die rechte Seite nennt das Gemälde, die linke den Führer. Kein Kolumnentitel erreicht den Umschlag, eine Seite in der Rolle eines Auftakts.
Das ganze Rezept
// ═══ Postext Cookbook · Nº 175 · A museum walk whose links print as QR notes ═════
// https://postext.dev/en/cookbook/museum-guide-qr-link-notes
// Code: MIT · Text: original (CC BY 4.0) · Paintings: The Metropolitan Museum of Art (CC0)
// Fonts: Newsreader, Instrument Serif, Archivo (SIL OFL 1.1) · Needs postext ≥ 1.65.0
// A pocket gallery guide: five paintings, one to a page. The Markdown writes the museum's
// catalogue pages as ordinary links; the print edition turns each one into a numbered note at
// the foot of the page, with the short address and a code a phone can scan.
import {
buildDocumentWithFonts, renderPageToCanvas, registerResourceImage,
} 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 = 'museum-guide-qr-link-notes';
// ─── 1 · Design ─────────────────────────────────────────────────────────────
// #region palette: Delft blue on warm paper, every colour linked by id
const palette = {
ink: '#1f1d1a', // text: a warm near-black
delft: '#2b4a7a', // the one accent: kickers, stop numbers, rules (8.6:1 on paper)
rule: '#c6c9cf', // hairlines
muted: '#5f6168', // running heads, notes, credits (6.1:1 on paper)
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, so nothing prints blue.
{ id: 'main-color', name: 'delft (defaults)', value: { hex: palette.delft, model: 'hex' } },
];
// #endregion
const TRIM = { w: 160, h: 240 }; // a large pocket guide, in mm
const TOP = 22; // top margin in mm: the cover's container starts here
const OUTER = 22; // outer margin in mm: folios and running heads align to it
const LEAD = 14; // body leading in pt: the baseline grid
const [TEXT, DISPLAY, LABEL] = ['Newsreader', 'Instrument Serif', 'Archivo']; // three voices
// #region answer: every web link of the guide prints as a numbered note with a code to scan
const links = {
print: 'notes', // a note marker after the link text, the address in a note at the foot
show: 'both', // the short address for reading, the code for the phone
urlDisplay: 'short', // metmuseum.org/art/collection/search/436616: no https://, no www.
repeat: 'first', // an address noted once is cited again by its number, never noted twice
qr: { size: mm(16), side: 'start', gap: em(1.2), color: col('ink') },
};
// Link notes are footnotes: they take the note style and the numbering below. 'document'
// numbers them through the walk, so the five stops print notes 3 to 7, not five notes 1.
const footnotes = { placement: 'column', numbering: 'document', fontSize: pt(8),
Das zusammengesetzte script.js läuft unverändert: Fügen Sie es in das Modulskript einer beliebigen Seite ein, oder öffnen Sie das Rezept auf CodePen. Ordner des Rezepts auf GitHub ↗ (öffnet sich in einem neuen Tab)
Varianten
#Die Adresse in der Zeile drucken
Für einen Führer, den man zu Hause liest, setzt 'inline' die Adresse in Klammern hinter den Linktext, ohne Anmerkung und ohne Code.
- print: 'notes', // a note marker after the link text, the address in a note at the foot
- show: 'both', // the short address for reading, the code for the phone
+ print: 'inline', // (metmuseum.org/…) after the link text#Codes ohne Adresse
show: 'qr' druckt nur den Code neben der Anmerkungsziffer, für ein Plakat oder ein Schild, auf dem die Adresse nur Platz kosten würde.
- show: 'both', // the short address for reading, the code for the phone
+ show: 'qr', // the code aloneHäufige Fehler
Eine Anmerkung mit Code ist mindestens so hoch wie der Code. Hat die Zeile mit dem Link auf der Seite keinen Platz mehr für ihre Anmerkung darunter, wandert die Zeile mit ihrer Anmerkung auf die nächste Seite. Halten Sie Links daher aus den letzten Zeilen einer Seite heraus, die an ihrer Stelle enden muss, wie der erste Absatz auf dem Umschlag dieses Führers.
Nachweise
- Rezept
- Ignacio Ferro
- Text
- Eigener Text, CC BY 4.0
- Bilder
- Johannes Vermeer, Young Woman with a Water Pitcher, about 1662 (the cover, cropped) · The Metropolitan Museum of Art · CC0 1.0
- Frans Hals, Young Man and Woman in an Inn, 1623 (stop 1) · The Metropolitan Museum of Art · CC0 1.0
- Jan Steen, Merry Company on a Terrace, about 1670 (stop 2) · The Metropolitan Museum of Art · CC0 1.0
- Rembrandt, Aristotle with a Bust of Homer, 1653 (stop 3) · The Metropolitan Museum of Art · CC0 1.0
- Johannes Vermeer, Young Woman with a Water Pitcher, about 1662 (stop 4) · The Metropolitan Museum of Art · CC0 1.0
- Jacob van Ruisdael, Wheat Fields, about 1670 (stop 5) · The Metropolitan Museum of Art · CC0 1.0
- Schriften
- Newsreader (SIL OFL 1.1) · Instrument Serif (SIL OFL 1.1) · Archivo (SIL OFL 1.1)
- Code
- MIT, wie Postext
Diesen Text bearbeiten ↗ (öffnet sich in einem neuen Tab)Ordner des Rezepts auf GitHub ↗ (öffnet sich in einem neuen Tab)


