# Ein historischer Essay mit Chicago-Noten

> Ein vierseitiger historischer Essay, dessen Zitate [@key, 87] zu Chicago-Noten am Seitenfuß werden: beim ersten Mal vollständig, danach kurz, mit Bibliografie.

- HTML-Fassung: https://postext.dev/de/cookbook/history-essay-chicago-notes
- Rezept Nº 089 · Buchaufbau · Stufe 2 (Mittel) · Ausgaben: Canvas, PDF
- Gattungen: Fachartikel und Wissenschaft
- Benötigt postext ≥ 1.25.0, postext-pdf ≥ 1.25.0 · getestet mit 1.31.0, postext-pdf 1.31.0 am 2026-10-13
- Seiten: [1](https://postext.dev/cookbook/history-essay-chicago-notes/en/p01.webp?v=82363864), [2](https://postext.dev/cookbook/history-essay-chicago-notes/en/p02.webp?v=82363864), [3](https://postext.dev/cookbook/history-essay-chicago-notes/en/p03.webp?v=82363864), [4](https://postext.dev/cookbook/history-essay-chicago-notes/en/p04.webp?v=82363864)
- PDF: https://postext.dev/cookbook/history-essay-chicago-notes/en/history-essay-chicago-notes.pdf?v=82363864
- In der Sandbox öffnen: https://postext.dev/de/sandbox#recipe=history-essay-chicago-notes&lang=en (.postext: https://postext.dev/cookbook/history-essay-chicago-notes/en/history-essay-chicago-notes.postext)
- Zuletzt aktualisiert: 2026-10-11
- Andere Sprachen: [en](https://postext.dev/en/cookbook/history-essay-chicago-notes.md), [es](https://postext.dev/es/cookbook/history-essay-chicago-notes.md), [ca](https://postext.dev/ca/cookbook/history-essay-chicago-notes.md), [fr](https://postext.dev/fr/cookbook/history-essay-chicago-notes.md), [it](https://postext.dev/it/cookbook/history-essay-chicago-notes.md), [pt](https://postext.dev/pt/cookbook/history-essay-chicago-notes.md), [zh](https://postext.dev/zh/cookbook/history-essay-chicago-notes.md), [ja](https://postext.dev/ja/cookbook/history-essay-chicago-notes.md), [ar](https://postext.dev/ar/cookbook/history-essay-chicago-notes.md)

## Kurz gesagt

Ein Essay darüber, wie britische Städte zur Londoner Zeit kamen. Jede Quelle, die der Autor zitiert, wird zu einer nummerierten Note am Fuß der Seite, und die Liste der Werke steht am Ende.

## Was Sie setzen

Ein Sonderdruck aus der technikgeschichtlichen Reihe einer Zeitschrift: ein Essay von etwa 1.100 Wörtern darüber, wie britische Städte zwischen 1840 und 1880 ihren eigenen Mittag für den Londoner aufgaben. Die Seite misst 156 × 234 mm, gespiegelt, in Crimson Pro mit 11/14 pt, mit einem Band in Eisenbahngrün über der oberen Hälfte der ersten Seite. Der Autor schreibt jede Quelle als Schlüssel, `[@howse1980, 87]`, und Postext setzt jede als nummerierte Note am Fuß der Seite im Chicago-Stil „notes and bibliography“. Die erste Note zu einem Werk nennt Autor, Titel und Verlag; jede spätere die Kurzform. Die eigenen erläuternden Noten des Autors nehmen ihre Nummern aus derselben Folge, und die Bibliografie schließt den Essay ab.

**Dieses Rezept beantwortet:**

- Wie setze ich Zitate als Chicago-Fußnoten, mit Kurzformen für spätere Zitate?
- Wie zitiere ich Werke und erstelle das Literaturverzeichnis nach APA, IEEE oder einem anderen Zitierstil?

## Die kurze Antwort

```js
// script.js, Zeilen 32–49
// The text cites with [@howse1980, 87]; a note style turns every citation into a
// footnote. The first note for a work gives it in full, later ones in the short form
// (author, short title, page), and the bibliography lists the works by author.
registerCitationEngine(createCiteprocEngine({ styles: STYLES, locales: LOCALES }));
const citations = {
  style: 'chicago-notes-bibliography', // CMOS 18th edition, notes and bibliography
  notes: 'footnote', // each citation in a note at the foot of the page
  link: true, // a note's citation jumps to its bibliography entry
  bibliography: { fontSize: em(0.92), lineHeight: pt(13), hangingIndent: em(1.8),
    entrySpacing: pt(3) },
};
// The citation notes share the numbering and the look of the author's own [^notes].
const footnotes = {
  placement: 'column', numbering: 'chapter',
  fontSize: pt(8.5), lineHeight: pt(10.75), spaceBetween: pt(2),
  textAlign: 'left', // ragged: the gap after a note's number stays the same in every note
  separator: { width: 0.3, lineWidth: pt(0.5), color: col('rule') },
};
```

## Zutaten

**Zeigt**

- [Zitate in Fußnoten](https://postext.dev/de/docs/document-format.md#zitate-und-literaturverzeichnis): Ein Fußnotenstil (Chicago notes, OSCOLA, GB/T 7714 notes) setzt jedes Zitat als Fußnote, mit Kurzformen für spätere Zitate, oder als zweizeilige Anmerkung in einer chinesischen Zeile.
- [Zitate in einem Zitierstil](https://postext.dev/de/docs/document-format.md#zitate-und-literaturverzeichnis): Werke, zitiert als [@key, p. 33] und in einem CSL-Stil formatiert (APA, Chicago, MLA, IEEE, Vancouver, ISO 690, GB/T 7714…), der in den Einstellungen gewählt wird, mit Links zu ihren Einträgen.

**Verwendet außerdem**

- [Literaturverzeichnis aus den Quellen](https://postext.dev/de/docs/document-format.md#zitate-und-literaturverzeichnis)
- [Fußnoten](https://postext.dev/de/docs/document-format.md#fußnoten)
- [Gestaltete Auftakte](https://postext.dev/de/docs/configuration-text.md#seitenbreite-und-erweiterte-gestaltung)
- [Überschriftenattribute](https://postext.dev/de/docs/document-format.md#attribute-von-überschriften)
- [Kolumnentitel und Seitenzahlen](https://postext.dev/de/docs/configuration-page-layout.md#kopf--und-fußzeilen)
- [Gespiegelte Ränder](https://postext.dev/de/docs/configuration-page-layout.md#gespiegelte-ränder)
- [Absatzformate](https://postext.dev/de/docs/configuration-styles.md#absatzformate)
- [Semantische Farbpalette](https://postext.dev/de/docs/configuration-fonts-colors-viewers.md#farbpalette)
- [PDF-Export](https://postext.dev/de/docs/configuration-programmatic-usage.md#pdfs-erzeugen)
- [Querverweise](https://postext.dev/de/docs/document-format.md#querverweise-und-anker)
- [Papierfarbe](https://postext.dev/de/docs/configuration-page-layout.md#seite)
- [Kopfzeilen nach Seitenrolle](https://postext.dev/de/docs/configuration-page-layout.md#textelemente)
- [Im PDF eingebettete Schriften](https://postext.dev/de/docs/configuration-programmatic-usage.md#warum-ein-font-provider)

**Die Konfiguration auf einen Blick**

- [`bodyText`](https://postext.dev/de/docs/configuration-text.md#fließtext), [`citations`](https://postext.dev/de/docs/configuration-notes-references.md#zitationen), [`colorPalette`](https://postext.dev/de/docs/configuration-fonts-colors-viewers.md#farbpalette), [`footer`](https://postext.dev/de/docs/configuration-page-layout.md#kopf--und-fußzeilen), `footnotes`, [`header`](https://postext.dev/de/docs/configuration-page-layout.md#kopf--und-fußzeilen), [`headings`](https://postext.dev/de/docs/configuration-text.md#überschriften), [`layout`](https://postext.dev/de/docs/configuration-page-layout.md#layout), [`locale`](https://postext.dev/de/docs/configuration-text.md#silbentrennung), [`page`](https://postext.dev/de/docs/configuration-page-layout.md#seite), [`paragraphStyles`](https://postext.dev/de/docs/configuration-styles.md#absatzformate)

**APIs**

- [`LOCALES`](https://postext.dev/de/docs/document-format.md#zitate-und-literaturverzeichnis), [`STYLES`](https://postext.dev/de/docs/document-format.md#zitate-und-literaturverzeichnis), [`buildDocumentWithFonts`](https://postext.dev/de/docs/configuration-programmatic-usage.md#schriften-vor-dem-layout-laden), [`createCiteprocEngine`](https://postext.dev/de/docs/document-format.md#zitate-und-literaturverzeichnis), [`decompressWoff2`](https://postext.dev/de/docs/configuration-programmatic-usage.md#font-provider-im-browser-fontsource--woff2), [`registerCitationEngine`](https://postext.dev/de/docs/document-format.md#zitate-und-literaturverzeichnis), [`renderPageToCanvas`](https://postext.dev/de/docs/configuration-programmatic-usage.md#eine-seite-als-bitmap-rendern), [`renderToPdf`](https://postext.dev/de/docs/configuration-programmatic-usage.md#pdfs-erzeugen)

**Schriften**

- Crimson Pro (OFL-1.1), IBM Plex Sans Condensed (OFL-1.1)

## Zubereitung

### 1 · Eine Note für jedes Zitat

Der Code steht in [der kurzen Antwort](https://postext.dev/de/cookbook/history-essay-chicago-notes.md#die-kurze-antwort) oben. `chicago-notes-bibliography` ist ein Notenstil, also hinterlässt ein Zitat im Text eine hochgestellte Nummer, und sein Wortlaut geht in eine Fußnote, die mit den eigenen `[^notes]` des Autors durchgezählt wird; `notes: 'footnote'` sagt das ausdrücklich. citeproc-js merkt sich, welche Werke es bereits zitiert hat, sodass Note 3 *Derek Howse, Greenwich Time and the Discovery of the Longitude (Oxford University Press, 1980), 87* lautet und Note 4, die dasselbe Buch erneut zitiert, *Howse, Greenwich Time and the Discovery of the Longitude, 90–91*. Der mitgelieferte Stil ist die 18. Auflage des Chicago Manual, die *Ibid.* abschafft und die Kurzform wiederholt, also drucken die Noten 11 und 12 zweimal die Kurzform.

### 2 · Auch Noten des Autors zitieren

Ein Zitat in einer `[^note]` bleibt in dieser Note und wird inline gesetzt, vollständig, wenn das Werk zum ersten Mal erscheint: Note 1 ist der Satz des Autors, gefolgt von der vollständigen Angabe zu Schivelbusch. Jedes Zitat endet mit dem Schlusspunkt des Stils, also braucht eine Note, die mit einem Zitat endet, im Markdown keinen eigenen Punkt.

### 3 · Präfixe, Suffixe und Fundstellen

`[see @simmons1991, 346–47; and @bartky2000, chap. 9]` setzt *see* vor das erste Werk, trennt die beiden mit einem Semikolon und behält die Fundstelle jedes Werks. Eine bloße Zahl ist eine Seite; `chap.` und `cap.` bezeichnen in beiden Sprachen ein Kapitel. Text nach der Fundstelle ist ein Suffix: `[@howse1980, 82–84, on the mail-coach timepieces]` druckt die Wendung nach den Seiten.

### 4 · Der Auftakt sitzt in einem Band

```js
// script.js, Zeilen 53–74
const BAND = 122; // mm from the trim's top
const opener = {
  enabled: true,
  minHeight: mm(BAND - MARGIN.top + 9), // the text starts 9 mm under the band
  slot: { elements: [
    { kind: 'box', id: 'band', style: { backgroundColor: col('green') },
      placement: { ...at('page', 'top-left'), size: { width: 'fill', height: mm(BAND) } } },
    { kind: 'text', id: 'kicker', content: '{attr.kicker}', fontFamily: LABEL, fontWeight: 600,
      fontSize: pt(7.5), letterSpacing: pt(1.4), textTransform: 'uppercase', color: col('tint'),
      align: 'left', placement: at('container', 'top-left', 0, 4) },
    { kind: 'text', id: 'years', content: '{attr.years}', fontFamily: TEXT, fontWeight: 300,
      fontSize: pt(54), lineHeight: 1, color: col('tint'), align: 'left',
      placement: at('container', 'top-left', -1, 16) },
    { kind: 'text', id: 'title', content: '{titleText}', fontFamily: TEXT, fontWeight: 600,
      fontSize: pt(25), lineHeight: 1.08, color: col('paper'), align: 'left', overflow: 'wrap',
      placement: { ...at('container', 'top-left', 0, 47),
        size: { width: mm(112), height: 'auto' } } },
    { kind: 'text', id: 'byline', content: '{attr.byline}', fontFamily: LABEL, fontWeight: 600,
      fontSize: pt(9), letterSpacing: pt(0.6), color: col('tint'), align: 'left',
      placement: at('container', 'top-left', 0, 92) },
  ] },
};
```

Das Band reicht 122 mm vom Endformat herab, und der Text beginnt 9 mm darunter. Die Jahreszahlen kommen aus einem Attribut der Überschrift, `years="1840–1880"`, gesetzt in Crimson Pro Light mit 54 pt, sodass die Karte eine Zahl so groß wie ein Titel zeigt; das Attribut für die Autorenzeile speist auch den Kolumnentitel der linken Seiten.

```js
// script.js, Zeilen 16–23
const palette = {
  ink: '#211d1a', green: '#24493d', tint: '#dfe8e2', rule: '#b7b0a4', muted: '#6a645b',
  paper: '#fbf9f4',
};
// col() links a colour to its palette entry; the hex is the value the entry holds today.
const col = (id) => ({ hex: palette[id], model: 'hex', paletteId: id });
const colorPalette = Object.entries({ ...palette, 'main-color': palette.green })
  .map(([id, hex]) => ({ id, name: id, value: { hex, model: 'hex' } }));
```

## Das ganze Rezept

Eine Datei, aus dem Ordner des Rezepts zusammengesetzt, mit dem Beispieltext und dem gemeinsamen Baukasten der Rezepte bereits eingebettet; sie baut ihre eigene Seite auf. Zum Ausführen setzen Sie sie in ein `<script type="module">` auf einer leeren Seite oder fügen sie in das JS-Feld eines neuen CodePen-Pens ein (als Modul). Sie importiert postext von esm.sh, es gibt also nichts zu installieren oder zu bauen.

- Quellordner: https://github.com/drnachio/postext/tree/main/cookbook/history-essay-chicago-notes

### script.js

```js
// ═══ Postext Cookbook · Nº 089 · A history essay with Chicago notes ═══════════════
// https://postext.dev/en/cookbook/history-essay-chicago-notes
// Code: MIT · Text: original (CC BY 4.0) · Pictures: none
// Fonts: Crimson Pro, IBM Plex Sans Condensed (SIL OFL 1.1) · Needs postext ≥ 1.25.0
import {
  buildDocumentWithFonts, renderPageToCanvas, registerCitationEngine,
} from 'https://esm.sh/postext';
import { renderToPdf, decompressWoff2 } from 'https://esm.sh/postext-pdf';
import { createCiteprocEngine, STYLES, LOCALES } from 'https://esm.sh/postext-citeproc';

const LANG = 'en'; // @lang: the language of the sample document ('en' | 'es')
const RECIPE = 'history-essay-chicago-notes';

// ─── 1 · Design ─────────────────────────────────────────────────────────────
// #region palette: a railway green for the opener band, ink and warm paper for the rest
const palette = {
  ink: '#211d1a', green: '#24493d', tint: '#dfe8e2', rule: '#b7b0a4', muted: '#6a645b',
  paper: '#fbf9f4',
};
// col() links a colour to its palette entry; the hex is the value the entry holds today.
const col = (id) => ({ hex: palette[id], model: 'hex', paletteId: id });
const colorPalette = Object.entries({ ...palette, 'main-color': palette.green })
  .map(([id, hex]) => ({ id, name: id, value: { hex, model: 'hex' } }));
// #endregion
const TEXT = 'Crimson Pro', LABEL = 'IBM Plex Sans Condensed';
const TRIM = { width: 156, height: 234 }; // a journal offprint, trimmed like a trade book
const MARGIN = { top: 22, bottom: 22, inner: 20, outer: 17 };
const LEAD = 14; // pt
const at = (to, edge, x = 0, y = 0) => ({ anchor: { to, edge }, offset: { x: mm(x), y: mm(y) } });

// #region answer: Chicago notes and bibliography, one note per citation
// The text cites with [@howse1980, 87]; a note style turns every citation into a
// footnote. The first note for a work gives it in full, later ones in the short form
// (author, short title, page), and the bibliography lists the works by author.
registerCitationEngine(createCiteprocEngine({ styles: STYLES, locales: LOCALES }));
const citations = {
  style: 'chicago-notes-bibliography', // CMOS 18th edition, notes and bibliography
  notes: 'footnote', // each citation in a note at the foot of the page
  link: true, // a note's citation jumps to its bibliography entry
  bibliography: { fontSize: em(0.92), lineHeight: pt(13), hangingIndent: em(1.8),
    entrySpacing: pt(3) },
};
// The citation notes share the numbering and the look of the author's own [^notes].
const footnotes = {
  placement: 'column', numbering: 'chapter',
  fontSize: pt(8.5), lineHeight: pt(10.75), spaceBetween: pt(2),
  textAlign: 'left', // ragged: the gap after a note's number stays the same in every note
  separator: { width: 0.3, lineWidth: pt(0.5), color: col('rule') },
};
// #endregion

// #region opener: the green band holds the kicker, the dates and the title
const BAND = 122; // mm from the trim's top
const opener = {
  enabled: true,
  minHeight: mm(BAND - MARGIN.top + 9), // the text starts 9 mm under the band
  slot: { elements: [
    { kind: 'box', id: 'band', style: { backgroundColor: col('green') },
      placement: { ...at('page', 'top-left'), size: { width: 'fill', height: mm(BAND) } } },
    { kind: 'text', id: 'kicker', content: '{attr.kicker}', fontFamily: LABEL, fontWeight: 600,
      fontSize: pt(7.5), letterSpacing: pt(1.4), textTransform: 'uppercase', color: col('tint'),
      align: 'left', placement: at('container', 'top-left', 0, 4) },
    { kind: 'text', id: 'years', content: '{attr.years}', fontFamily: TEXT, fontWeight: 300,
      fontSize: pt(54), lineHeight: 1, color: col('tint'), align: 'left',
      placement: at('container', 'top-left', -1, 16) },
    { kind: 'text', id: 'title', content: '{titleText}', fontFamily: TEXT, fontWeight: 600,
      fontSize: pt(25), lineHeight: 1.08, color: col('paper'), align: 'left', overflow: 'wrap',
      placement: { ...at('container', 'top-left', 0, 47),
        size: { width: mm(112), height: 'auto' } } },
    { kind: 'text', id: 'byline', content: '{attr.byline}', fontFamily: LABEL, fontWeight: 600,
      fontSize: pt(9), letterSpacing: pt(0.6), color: col('tint'), align: 'left',
      placement: at('container', 'top-left', 0, 92) },
  ] },
};
// #endregion

const head = (id, content, parity, edge, x, align) => ({
  kind: 'text', id, content, parity, pages: 'body', fontFamily: LABEL, fontWeight: 600,
  fontSize: pt(7.5), letterSpacing: pt(1.1), textTransform: 'uppercase', color: col('muted'),
  align, placement: at('page', edge, x, 12),
});

const config = () => ({
  locale: t({ en: 'en-us', es: 'es' }), // the hyphenation patterns of each edition
  colorPalette,
  citations,
  footnotes,
  page: {
    sizePreset: 'custom', width: mm(TRIM.width), height: mm(TRIM.height), dpi: 150,
    backgroundColor: col('paper'),
    margins: { top: mm(MARGIN.top), bottom: mm(MARGIN.bottom), left: mm(MARGIN.inner),
      right: mm(MARGIN.outer), mirror: true },
  },
  layout: { layoutType: 'single' },
  bodyText: {
    fontFamily: TEXT, fontSize: pt(11), lineHeight: pt(LEAD), color: col('ink'),
    boldColor: col('ink'), italicColor: col('ink'), referenceColor: col('ink'),
    textAlign: 'justify', firstLineIndent: mm(5), indentAfterHeading: false,
    hyphenation: { enabled: true }, optimalLineBreaking: true,
    avoidWidows: true, avoidOrphans: true, avoidRunts: true,
  },
  headings: {
    fontFamily: TEXT, fontWeight: 600, color: col('ink'),
    levels: [
      // parity 'any': the H1 opens on the next page, either side (the default waits for a recto).
      { level: 1, fontSize: pt(25), breakBefore: { enabled: true, parity: 'any' },
        advancedDesign: opener },
      { level: 2, fontFamily: LABEL, fontWeight: 600, fontSize: pt(8.5), letterSpacing: pt(1.3),
        textTransform: 'uppercase', color: col('green'), lineHeight: pt(LEAD),
        marginTop: pt(LEAD), marginBottom: pt(LEAD / 2) },
    ],
  },
  paragraphStyles: [
    { id: 'colophon', fontFamily: LABEL, fontSize: pt(7), lineHeight: pt(9.5),
      color: col('muted'), textAlign: 'left', firstLineIndent: pt(0), marginTop: pt(LEAD) },
  ],
  header: { elements: [
    head('verso-folio', '{pageNumber}', 'even', 'top-left', MARGIN.outer, 'left'),
    head('verso-author', '{attr.byline}', 'even', 'top-left', MARGIN.outer + 8, 'left'),
    head('recto-title', '{title}', 'odd', 'top-right', -(MARGIN.outer + 8), 'right'),
    head('recto-folio', '{pageNumber}', 'odd', 'top-right', -MARGIN.outer, 'right'),
  ] },
  footer: { elements: [] },
});

// ─── 2 · Content ────────────────────────────────────────────────────────────
const markdown = String.raw`---
title: "Railway Time"
author: "Clara Whitcombe"
---

# Railway Time: How British Towns Came to Keep London’s Hour {#essay kicker="Essays in the History of Technology · No. 14" years="1840–1880" byline="Clara Whitcombe"}

In the autumn of 1840 a traveller who left Paddington on the Great Western Railway carried two times with him. The timetable in his pocket gave the hours of London; the church clock at Bath or Bristol, when he arrived, gave the hours of the place, a few minutes behind. Bristol stood a little over two and a half degrees west of Greenwich, and its noon, the moment the sun crossed the local meridian, came about ten minutes after London’s. For centuries the difference had not mattered. A stagecoach that took a day to cover the distance lost more than ten minutes to a lame horse. A train that covered it in four hours could not.[^frame]

This essay follows the forty years in which that difference was settled, from the Great Western’s first timetables to the act of Parliament that made Greenwich time the legal time of Great Britain in 1880. The story has usually been told as a triumph of engineering over custom. It reads better as a negotiation, in which railway companies, telegraph companies, town councils and courts each settled the question for their own purposes, and not always in the same direction.

[^frame]: For the railway’s effect on the sense of time and distance, see [@schivelbusch1986, chap. 3]

## The companies decide

The first railways ran their trains by the clocks of their own stations. On a line of a few miles this caused no trouble, and the early timetables did not say which time they meant. The difficulty came with the long trunk lines of the late 1830s, which joined towns whose clocks disagreed by a quarter of an hour.[@simmons1991, 345]

The Great Western printed London time in its timetables from November 1840 and asked its station clocks to keep it.[@howse1980, 87] In 1847 the Railway Clearing House, the body through which the companies settled their accounts for through traffic, recommended that every member adopt Greenwich time from the first of December. By the end of 1848 nearly all of them had.[@howse1980, 90–91]

The decision was commercial before it was scientific. A company that kept one time along its line needed one timetable and one set of instructions for its staff, and it could publish connections with other lines without a table of corrections. Greenwich was chosen because London was where the companies had their offices and the Post Office its mail coaches, not because the observatory stood there.[^post]

[^post]: The Post Office had sent its guards out with watches set to London time since the 1790s; see [@howse1980, 82–84, on the mail-coach timepieces]

## The wire carries the hour

A time that every station is meant to keep has to reach every station. At first it travelled by hand: a guard on the morning down train carried a watch set at Paddington, and the stationmasters along the line set their clocks from it.

The electric telegraph changed the means. From 1852 the Royal Observatory sent a signal each day along the wires of the Electric Telegraph Company, and the company passed it on to the railway stations and post offices on its network.[@standage1998, 59] A clock in Manchester or Edinburgh could now be checked against Greenwich within a second or two of the event. The signal made Greenwich time available everywhere the wires went; it did not oblige anyone to keep it.[@schivelbusch1986, 43]

## The towns hesitate

Most towns on a main line gave way within a few years, since a clock that disagreed with the station made people miss trains. Some held out. In 1852 the clock on the Corn Exchange at Bristol was given a second minute hand, one for Bristol and one for London, and it still has both.[@simmons1991, 346] At Exeter, which the railway reached in 1844, the cathedral clock went on keeping the time of the city for some years after the station clock had changed.[^exeter]

[^exeter]: On the British towns, and on the same quarrel in American towns thirty years later, see [@simmons1991, 346–47; and @bartky2000, chap. 9]

The holdouts were not cranks. Local mean time followed the sun, and the sun still ordered the working day of farmers, fishermen and anyone whose hours depended on daylight. An hour fixed in London was an imposition on them. The historian of factory discipline has argued that the clock had already become a means of controlling labour by the eighteenth century;[@thompson1967, 80–82] the dispute over railway time extended that argument to whole towns, which were asked to accept an hour set elsewhere.

## The courts decline

The law was slower than the towns. Statutes that named a time meant the time of the place, and that time was local mean time. In 1858 a trial at Dorchester began at ten by the court’s clock, which kept London time, and judgment was given against a defendant who arrived at ten by the time of the town, some minutes later. On appeal the judges held that the hour meant was the local one, and the judgment was set aside.[@howse1980, 113] For twenty more years a contract, a polling station or a public house could be bound by one time while the trains ran by another.

The Statutes (Definition of Time) Act of 1880 closed the gap. It declared that any expression of time in an act of Parliament, deed or other legal instrument meant, unless stated otherwise, Greenwich mean time in Great Britain and Dublin mean time in Ireland.[@howse1980, 114]

## A settlement, not a conquest

Seen from 1840, railway time was one of several possible arrangements. The companies might have kept local times and printed tables of corrections, as some American railroads did until 1883,[@bartky2000, 140–45] and the international system of zones that followed the Washington conference of 1884 took half a century to reach most of the world.[@ogle2015] In Britain the distances were short, the companies were few enough to agree through a single clearing house, and the telegraph reached the stations as the trains did. Those conditions, more than any principle, account for the speed with which a country of local noons came to keep one hour.[@ogle2015, 25; see also @schivelbusch1986, chap. 3]

## Bibliography

:::bibliography{title=""}

:::paragraphs{style="colophon"}
A sample essay written for the Postext Cookbook (CC BY 4.0). The cited works are real; the page numbers in the notes are illustrative. Set in Crimson Pro and IBM Plex Sans Condensed (SIL OFL).
:::

:::references{format=csl-yaml}
- id: schivelbusch1986
  type: book
  author: [{family: Schivelbusch, given: Wolfgang}]
  title: "The Railway Journey: The Industrialization of Time and Space in the 19th Century"
  publisher: University of California Press
  publisher-place: Berkeley
  issued: 1986
- id: thompson1967
  type: article-journal
  author: [{family: Thompson, given: E. P.}]
  title: "Time, Work-Discipline, and Industrial Capitalism"
  container-title: Past & Present
  issue: 38
  page: 56-97
  issued: 1967
- id: howse1980
  type: book
  author: [{family: Howse, given: Derek}]
  title: Greenwich Time and the Discovery of the Longitude
  publisher: Oxford University Press
  publisher-place: Oxford
  issued: 1980
- id: simmons1991
  type: book
  author: [{family: Simmons, given: Jack}]
  title: The Victorian Railway
  publisher: Thames and Hudson
  publisher-place: London
  issued: 1991
- id: standage1998
  type: book
  author: [{family: Standage, given: Tom}]
  title: The Victorian Internet
  publisher: Walker
  publisher-place: New York
  issued: 1998
- id: bartky2000
  type: book
  author: [{family: Bartky, given: Ian R.}]
  title: "Selling the True Time: Nineteenth-Century Timekeeping in America"
  publisher: Stanford University Press
  publisher-place: Stanford, CA
  issued: 2000
- id: ogle2015
  type: book
  author: [{family: Ogle, given: Vanessa}]
  title: The Global Transformation of Time, 1870–1950
  publisher: Harvard University Press
  publisher-place: Cambridge, MA
  issued: 2015
:::
`;

// ─── 3 · Fonts ──────────────────────────────────────────────────────────────
// Every face the design uses.
const FONTS = {
  'Crimson Pro': ['300', '400', '400i', '600', '600i'],
  'IBM Plex Sans Condensed': ['400', '600'],
};

// ─── 4 · Build & show ───────────────────────────────────────────────────────
const doc = await buildDocumentWithFonts({ markdown }, config(), kitFonts(FONTS));
const title = t({ en: 'A history essay with Chicago notes',
  es: 'Un ensayo de historia con notas de Chicago' });
showPages(doc, { title });
offerPdf(() => renderToPdf(doc, { fontProvider: fontsourceProvider }), `${RECIPE}.pdf`);

// ─── Kit ── helpers shared by every Cookbook recipe · postext.dev/cookbook ─────

// ─── Kit · core v1 ── the same in every recipe · postext.dev/cookbook
function mm(value) { return { value, unit: 'mm' }; }
function pt(value) { return { value, unit: 'pt' }; }
function em(value) { return { value, unit: 'em' }; }
/** The sample language's string: t({ en: 'Figure', es: 'Figura' }). */
function t(strings) { return strings[LANG] ?? Object.values(strings)[0]; }
/** A file in this recipe's assets folder, served from the Postext repo by jsDelivr. */
function asset(file) { return `https://cdn.jsdelivr.net/gh/drnachio/postext@main/cookbook/${RECIPE}/assets/${file}`; }

// ─── Kit · fonts v3 ── the same in every recipe · postext.dev/cookbook
// Postext loads the faces a config asks for before layout (prepareFonts,
// buildDocumentWithFonts) and asks the kit for the files: Fontsource's, the
// files the PDF embeds too.

/** The options of buildDocumentWithFonts / prepareFonts / withLoadedFonts:
 *  the Fontsource resolver, and the faces of FONTS loaded with the ones the
 *  config names. FONTS = { 'Family Name': ['400', '400i', '700'] }. */
function kitFonts(FONTS = {}) {
  const faces = Object.entries(FONTS).flatMap(([family, specs]) => specs.map((spec) =>
    ({ family, weight: parseInt(spec, 10), style: spec.endsWith('i') ? 'italic' : 'normal' })));
  return { resolve: fontsourceResolver, faces };
}

/** A face's Fontsource files, in a fixed order: latin, then latin-ext and greek
 *  when `text` needs them and the family ships them (kitSubsetsFor), each with
 *  its unicode-range. Null for a weight or slant Fontsource does not ship. */
async function fontsourceResolver(family, weight, style, { text = '' } = {}) {
  const id = fontsourceId(family);
  const meta = await fontsourceMeta(family);
  if (meta && !(meta.weights.includes(weight) && meta.styles.includes(style))) return null;
  kitStatus('Loading fonts…');
  const at = await fontsourceAt(id);
  return ['latin', ...kitSubsetsFor(text, meta)].map((subset) => ({
    source: `${at}files/${id}-${subset}-${weight}-${style}.woff2`,
    unicodeRange: kitRanges()[subset],
  }));
}

/** The unicode-range of each Fontsource file the kit loads (a function: the
 *  kit is inlined after the pen's code, which runs before a const would be set). */
function kitRanges() {
  return {
    latin: 'U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,'
      + 'U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD',
    'latin-ext': 'U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,'
      + 'U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF',
    greek: 'U+0370-03FF',
  };
}

/** For the cjk, arabic and comics blocks, which add their own files: the
 *  faces of `faces` = { 'Family Name': ['400', '400i', '700'] }. `text` is the sample:
 *  č ł † α χ also load latin-ext and greek files (kitSubsetsFor). With
 *  `optional`, a face Fontsource does not ship is skipped instead of failing.
 *  The files are added once all have loaded, in the order asked (latin, then
 *  latin-ext, then greek), whatever order they arrive in: the last one added
 *  wins a character two files hold. Resolves to the number of faces added. */
async function loadFonts(faces, text = '', { optional = false } = {}) {
  kitStatus('Loading fonts…');
  const ranges = kitRanges();
  const jobs = [];
  for (const [family, specs] of Object.entries(faces)) {
    const id = fontsourceId(family);
    const todo = [...new Set(specs)].map((spec) => [parseInt(spec, 10), spec.endsWith('i') ? 'italic' : 'normal'])
      .filter(([weight, style]) => !hasFace(family, weight, style)); // before any await
    const at = fontsourceAt(id);
    const meta = optional || /[^\0-ÿ]/u.test(text) ? await fontsourceMeta(family) : null;
    const subsets = ['latin', ...kitSubsetsFor(text, meta)];
    for (const [weight, style] of todo) {
      if (optional && !(meta?.weights.includes(weight) && meta.styles.includes(style))) continue;
      for (const subset of subsets) {
        const url = `${await at}files/${id}-${subset}-${weight}-${style}.woff2`;
        const face = new FontFace(family, `url(${url}) format('woff2')`,
          { weight: String(weight), style, unicodeRange: ranges[subset] });
        jobs.push(face.load().catch(() => {
          if (subset === 'latin' && !optional) throw new Error(`Fontsource has no ${family} ${weight} ${style}`);
        }));
      }
    }
  }
  const ready = await Promise.all(jobs).catch((error) => { kitFail(error); throw error; });
  return ready.filter((face) => face && document.fonts.add(face)).length;
}

/** A loaded FontFace covers this family, weight and style (fonts.check() would
 *  also say yes for families nobody declared). */
function hasFace(family, weight, style) {
  for (const face of document.fonts) {
    if (face.status !== 'loaded' || face.style !== style) continue;
    if (face.family.replace(/^["']|["']$/g, '') !== family) continue;
    const [low, high = low] = face.weight.split(' ').map(Number);
    if (weight >= low && weight <= high) return true;
  }
  return false;
}

/** The files beyond latin `text` needs that `meta`'s family ships. */
function kitSubsetsFor(text, meta) {
  return [[/[Ā-˿ᴀ-ᶿḀ-ỿ†ℓⱠ-Ɀ꜠-ꟿ]/u, 'latin-ext'], [/[Ͱ-Ͽ]/u, 'greek']]
    .filter(([re, x]) => re.test(text) && meta?.subsets?.includes(x)).map(([, x]) => x);
}

/** Fontsource's id for a family: 'Source Serif 4' → 'source-serif-4'. */
function fontsourceId(family) { return family.toLowerCase().replace(/\s+/g, '-'); }

/** A package's folder at the one version @5 names now (#766). */
function fontsourceAt(id, u = `https://cdn.jsdelivr.net/npm/@fontsource/${id}@`) {
  return (fontsourceAt.c ??= {})[id] ??= fetch(u + '5/package.json').then((r) => r.json())
    .then((p) => p.version || 5, () => 5).then((v) => `${u}${v}/`);
}

/** The family's Fontsource metadata (weights, styles, subsets), or null. */
function fontsourceMeta(family) {
  fontsourceMeta.cache ??= new Map();
  const id = fontsourceId(family);
  if (!fontsourceMeta.cache.has(id)) {
    fontsourceMeta.cache.set(id, fetch(`https://api.fontsource.org/v1/fonts/${id}`)
      .then((res) => (res.ok ? res.json() : null), () => null));
  }
  return fontsourceMeta.cache.get(id);
}

// ─── Kit · viewer v2 ── the same in every recipe · postext.dev/cookbook
/** The pages as spreads on a dark desk, page 1 alone, then verso | recto,
 *  each painted when it scrolls near. Other options go to renderPageToCanvas. */
function showPages(docs, { title, width = 460, ...render } = {}) {
  const root = viewer(title);
  const pages = [docs].flat().flatMap((doc) =>
    doc.pages.map((page) => ({ doc, page, n: (doc.pageIndexOffset ?? 0) + page.index })));
  const spreads = [];
  let verso = null;
  for (const p of pages) {
    if (p.n % 2 === 1) { if (verso) spreads.push([verso, null]); verso = p; }
    else { spreads.push([verso, p]); verso = null; }
  }
  if (verso) spreads.push([verso, null]);
  const density = Math.min(window.devicePixelRatio || 1, 2);
  showPages.painter?.disconnect();
  const painter = new IntersectionObserver((entries) => {
    for (const { isIntersecting, target } of entries) {
      if (!isIntersecting) continue;
      painter.unobserve(target);
      const { doc, page } = target.postext;
      renderPageToCanvas(page, doc, target, { ...render, scale: (width * density) / page.width });
    }
  }, { rootMargin: '800px' });
  showPages.painter = painter;
  root.replaceChildren(...spreads.map((pair) => {
    const spread = document.createElement('div');
    spread.className = 'pt-spread';
    for (const p of pair) {
      const figure = document.createElement('figure');
      if (p) {
        const label = p.page.pageLabel || String(p.n + 1);
        const canvas = document.createElement('canvas');
        canvas.postext = p;
        canvas.style.aspectRatio = `${p.page.width} / ${p.page.height}`;
        canvas.setAttribute('role', 'img');
        canvas.setAttribute('aria-label', `Page ${label}`);
        const folio = document.createElement('figcaption');
        folio.textContent = label;
        figure.append(canvas, folio);
        painter.observe(canvas);
      } else figure.className = 'pt-blank';
      spread.append(figure);
    }
    return spread;
  }));
  kitStatus(`${pages.length} ${pages.length === 1 ? 'page' : 'pages'}`);
  document.documentElement.dataset.postext = 'ready';
  return pages.length;
}

/** The desk, the bar and the error reporting, created once. */
function viewer(title) {
  if (!document.getElementById('pt-kit')) {
    document.head.insertAdjacentHTML('beforeend', `<style id="pt-kit">
      :root { color-scheme: dark; }
      body { margin: 0; background: #0e1014; color: #b9bcc4; font: 13px/1.45 system-ui, sans-serif; }
      #pt-bar { position: sticky; top: 0; z-index: 1; display: flex; flex-wrap: wrap; align-items: center;
        gap: 6px 16px; padding: 10px 16px; background: rgb(14 16 20 / .92); backdrop-filter: blur(6px);
        border-bottom: 1px solid #23262d; }
      #pt-bar strong { color: #f4f1ea; font-weight: 600; }
      #pt-actions { display: flex; gap: 12px; margin-left: auto; }
      #pt-actions a, #pt-actions button { color: #d8a21a; font: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
      #pages { display: grid; justify-items: center; gap: 48px; padding: 32px 16px 72px; }
      .pt-spread { display: flex; }
      .pt-spread figure { margin: 0; width: min(460px, 44vw); }
      .pt-spread canvas { display: block; width: 100%; background: #fff;
        box-shadow: 0 1px 2px rgb(0 0 0 / .5), 0 22px 44px -16px rgb(0 0 0 / .8); }
      .pt-spread figure:first-child canvas { box-shadow: inset -14px 0 14px -14px rgb(0 0 0 / .18), 0 1px 2px rgb(0 0 0 / .5), 0 22px 44px -16px rgb(0 0 0 / .8); }
      .pt-spread figcaption { margin-top: 10px; text-align: center; font: 600 10px/1 system-ui, sans-serif;
        letter-spacing: .18em; text-transform: uppercase; color: #6c7079; }
      .pt-blank { visibility: hidden; }
      @media (max-width: 760px) {
        .pt-spread { flex-direction: column; gap: 32px; }
        .pt-spread figure { width: min(460px, 92vw); }
        .pt-blank { display: none; }
      }
    </style>`);
    document.body.insertAdjacentHTML('afterbegin',
      '<header id="pt-bar"><strong id="pt-title"></strong><span id="pt-status" role="status"></span><span id="pt-actions"></span></header>');
    document.getElementById('pt-title').textContent = document.title || 'Postext';
    addEventListener('error', (event) => kitFail(event.error ?? event.message));
    addEventListener('unhandledrejection', (event) => kitFail(event.reason));
  }
  if (title) document.getElementById('pt-title').textContent = title;
  return document.getElementById('pages')
    ?? document.body.appendChild(Object.assign(document.createElement('main'), { id: 'pages' }));
}

function kitStatus(text) {
  viewer();
  document.getElementById('pt-status').textContent = text;
}

function kitFail(error) {
  document.documentElement.dataset.postext = 'error';
  kitStatus(`Error: ${error?.message ?? error}`);
}

// ─── Kit · pdf v3 ── the same in every recipe that exports a PDF
/** The Fontsource files the screen used, as TrueType, with their range and
 *  place: the nearest weight the family ships, upright with no italic;
 *  latin, then what its letters need (kitSubsetsFor). */
async function fontsourceProvider(family, weight, style, request) {
  const id = fontsourceId(family);
  const meta = await fontsourceMeta(family);
  const weights = meta?.weights?.length ? meta.weights : [400, 700];
  const w = weights.reduce((a, b) => (Math.abs(b - weight) < Math.abs(a - weight) ? b : a));
  const s = style === 'italic' && meta && !meta.styles.includes('italic') ? 'normal' : style;
  const text = String.fromCodePoint(...(request?.codePoints ?? []));
  const files = await Promise.all(['latin', ...kitSubsetsFor(text, meta)].map(async (subset, order) => {
    const res = await fetch(`${await fontsourceAt(id)}files/${id}-${subset}-${w}-${s}.woff2`);
    if (!res.ok) throw new Error(`Fontsource has no ${family} ${w} ${s} ${subset}`);
    return Object.assign(await decompressWoff2(new Uint8Array(await res.arrayBuffer())),
      { unicodeRange: kitRanges()[subset], order });
  }));
  return files.length === 1 ? files[0] : files;
}

/** A "Build the PDF" button; then "Open the PDF" (a new tab: CodePen's frame
 *  shows no PDFs) and a download link. */
function offerPdf(makePdf, filename) {
  viewer();
  const button = Object.assign(document.createElement('button'), { type: 'button', textContent: 'Build the PDF' });
  button.dataset.postextPdf = filename;
  button.addEventListener('click', async () => {
    button.disabled = true;
    button.textContent = 'Building the PDF…';
    try {
      const bytes = await makePdf();
      const url = URL.createObjectURL(new Blob([bytes], { type: 'application/pdf' }));
      const size = `${Math.max(1, Math.round(bytes.length / 1024))} KB`;
      button.replaceWith(
        Object.assign(document.createElement('a'), { href: url, target: '_blank', rel: 'noopener', textContent: 'Open the PDF ↗' }),
        Object.assign(document.createElement('a'), { href: url, download: filename, textContent: `Download ${filename} · ${size}` }));
    } catch (error) {
      button.disabled = false;
      button.textContent = 'Build the PDF';
      kitFail(error);
    }
  });
  document.getElementById('pt-actions').append(button);
}

// ─── /Kit ───────────────────────────────────────────────────────────────────────
```

## Varianten

### Die Noten ans Ende setzen

Manche Zeitschriften sammeln die Noten nach dem Essay; die Zitate behalten ihre Voll- und Kurzformen.

```diff
-  placement: 'column', numbering: 'chapter',
+  placement: 'chapterEnd', numbering: 'chapter',
```

### Wieder Ibid. schreiben

Die 17. Auflage des Chicago-Stils druckt *Ibid.* für eine Note, die das vorige Werk wiederholt. Fügen Sie die `.csl`-Datei dieses Stils aus dem Zotero-Stilverzeichnis in einen String ein und verwenden Sie ihn als eigenen Stil.

```diff
-  style: 'chicago-notes-bibliography', // CMOS 18th edition, notes and bibliography
+  style: 'custom', customStyle: CHICAGO_17TH_CSL, // the XML of the .csl file
```

## Häufige Fehler

- Beenden Sie eine Note nach einem Zitat nicht mit einem Punkt: Der Stil schließt das Zitat bereits mit einem ab, und Postext verschmilzt die beiden nicht, sodass die Note mit zwei Punkten endete.
- In einem Notenstil hinterlässt `@howse1980` ohne Klammern nur die Notennummer im Satz, *As ¹ says*, ohne den Namen des Autors. Schreiben Sie den Namen selbst und zitieren Sie in Klammern: `As Howse says,[@howse1980]`.

## Nachweise

- Rezept: Ignacio Ferro ([@drnachio](https://github.com/drnachio))
- Schrift: Crimson Pro (OFL-1.1), IBM Plex Sans Condensed (OFL-1.1)
- Code: MIT · Beispielinhalt: CC-BY-4.0

## Verwandte Rezepte

- [Nº 099 · Ein juristisches Gutachten mit Zitaten nach OSCOLA](https://postext.dev/de/cookbook/legal-opinion-oscola.md): Eine vierseitige Urteilsanmerkung, deren Zitate [@robinson2018, para 21] zu OSCOLA-Fußnoten werden: Fälle kursiv, neutrale Zitate, ibid und Rückverweise (n 1). · Stufe 2 (Mittel) · Fachartikel und Wissenschaft
- [Nº 096 · Ein geisteswissenschaftlicher Essay mit MLA-Verzeichnis](https://postext.dev/de/cookbook/mla-humanities-essay.md): Ein literaturwissenschaftlicher Essay, dessen Zitate [@key, 48] zu Autor-Seite-Angaben nach MLA 9 werden, mit Blockzitat und Works Cited aus BibTeX-Daten. · Stufe 2 (Mittel) · Fachartikel und Wissenschaft
- [Nº 098 · Ein Sammelband mit Literaturliste pro Kapitel](https://postext.dev/de/cookbook/edited-volume-chapter-bibliographies.md): Drei Aufsätze von drei Beiträgern, jeder ein eigenes Dokument in buildBundle, jeder mit einer Liste nach Chicago-Autor-Jahr nur der Werke, die er zitiert. · Stufe 3 (Fortgeschritten) · Fachartikel und Wissenschaft, Lehrbücher
