Statische Website-Assets in die Quelle web_04/ holen

site.css, site.js, icons.svg, plotly.min.js und die 22 KaTeX-Dateien lagen in
OR_HTML_04/, obwohl kein Skript sie je geschrieben hat. Die Falle daran: Wer
eine CSS-Regel suchte, suchte sie in den Quellen und fand nichts - genau das
ist beim Einruecken des ZIP-Menuepunkts passiert. Und wer OR_HTML_04/ geloescht
und neu gebaut haette, haette eine Website ohne Stil, ohne Symbole und ohne
Formelsatz bekommen.

Jetzt liegen sie in web_04/, dessen Aufbau (assets/, katex/) das Ziel spiegelt.
spiegle_statische_assets() kopiert sie bei JEDEM Lauf.
kopiere_plotly_bibliothek() fuellt die Quelle statt des Ziels.
_lade_icon_sprite_inline() und die beiden KaTeX-Pruefungen lesen die Quelle,
haengen also nicht mehr vom eigenen Ergebnis ab.

Zwei Waechter, weil genau diese Verwechslung schon vorgekommen ist:

* Wurde die Kopie in OR_HTML_04/ von Hand geaendert (Inhalt weicht ab UND
  Zeitstempel ist neuer), bricht der Bau ab und nennt den mv-Befehl, der es
  richtigstellt - kein stilles Ueberschreiben.
* pruefe_assets() liest die href=/src=-Literale aus dem Quelltext des
  Bauskripts und verlangt fuer jedes einen Erzeuger: entweder web_04/ oder die
  Liste ERZEUGTE_ASSETS (highlight.css, search-index.js, programme.js).

Probe: rm -rf OR_HTML_04 && --html baut alle 213 Dateien wieder auf,
Dateiliste identisch zur Sicherung.

Fund dabei: Das Stichwortverzeichnis war nicht byte-reproduzierbar

ziel_links() sortierte nach (seite, kontext) - und kontext ist der
Kapiteltitel, fuer alle Marken einer Datei also derselbe. Bei zwei Fundstellen
im selben Kapitel war der Schluessel gleich, und die Reihenfolge fiel auf die
eines set() zurueck, also auf den je Prozess zufaelligen PYTHONHASHSEED. Zwei
Laeufe erzeugten unterschiedliche Bytes ohne Quellaenderung.

Derselbe Fehler war auch sichtbar: vier {idx:Branch-and-Bound} in Kapitel 6
ergaben vier optisch identische Links nebeneinander; zehn Registereintraege
waren betroffen. Behoben durch einen Link je Kapitel (erste Fundstelle in
Dokumentreihenfolge, dict statt set) - das macht die Sortierung zugleich
eindeutig.

Gegenprobe: drei Laeufe mit PYTHONHASHSEED=random liefern dieselbe Pruefsumme.
219 Fachbegriffe und 328 Indexmarken unveraendert.

Nachtrag zum vorigen Commit: highlight.css gehoert NICHT zu den Handdateien -
erzeuge_highlight_css() erzeugt sie aus pandoc --print-highlight-style. Die
Notiz in PROGRESS.md ist korrigiert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
dschlueter 2026-09-08 16:24:56 +02:00
commit 567bfa799a
30 changed files with 4686 additions and 22 deletions

View file

@ -2024,14 +2024,60 @@ Archivs — so können Link und Datei nicht auseinanderlaufen. Das Glossar ersch
dasselbe leisten, und unten in der Gruppe „Anhänge", weil es ein Anhang ist.
**Nebenbefund: `OR_HTML_04/assets/site.css` ist eine Quelle, keine erzeugte Datei.** Der
Build schreibt sie nicht (Zeitstempel vom 06.09., während `programme.js` bei jedem Lauf
neu entsteht). Dasselbe gilt für `site.js`, `icons.svg`, `highlight.css` und
`plotly.min.js`. Sie liegen im als „generiert" beschriebenen Verzeichnis, sind aber von Hand
Build schreibt sie nicht. Dasselbe gilt für `site.js`, `icons.svg`, `plotly.min.js` und
`katex/`. Sie liegen im als „generiert" beschriebenen Verzeichnis, sind aber von Hand
gepflegt bzw. mitgeliefert — wer `OR_HTML_04/` löscht und neu baut, verliert sie.
(Nachtrag: Der nächste Abschnitt räumt das auf. **Und `highlight.css` gehört nicht in diese
Liste** — die erzeugt `erzeuge_highlight_css()` aus `pandoc --print-highlight-style`; die
erste Fassung dieses Absatzes zählte sie fälschlich mit.)
Die alte `anhang-glossar-literatur.html` musste von Hand entfernt werden; der Build räumt
verwaiste Seiten nicht ab.
### ✅ `web_04/` — die statischen Assets bekommen eine Quelle
Vier Dateien und die 22 KaTeX-Dateien lagen im erzeugten Verzeichnis, obwohl kein Skript sie
je geschrieben hat. Die Falle daran: Wer eine CSS-Regel suchte, suchte sie in den Quellen und
fand nichts — genau das ist beim Einrücken des ZIP-Menüpunkts passiert. Und wer `OR_HTML_04/`
gelöscht und neu gebaut hätte, hätte eine Website ohne Stil, ohne Symbole und ohne
Formelsatz bekommen.
Jetzt liegen sie in `web_04/`, dessen Aufbau (`assets/`, `katex/`) das Ziel spiegelt.
`spiegle_statische_assets()` kopiert sie bei **jedem** Lauf; `kopiere_plotly_bibliothek()`
füllt die Quelle statt des Ziels; `_lade_icon_sprite_inline()` liest die Quelle, hängt also
nicht mehr vom eigenen Ergebnis ab.
**Zwei Wächter**, weil genau diese Verwechslung schon vorgekommen ist:
* Wurde die Kopie in `OR_HTML_04/` von Hand geändert (Inhalt weicht ab *und* Zeitstempel ist
neuer), **bricht der Bau ab** und nennt den `mv`-Befehl, der es richtigstellt. Kein
stilles Überschreiben.
* `pruefe_assets()` liest die `href=`/`src=`-Literale aus dem Quelltext des Bauskripts und
verlangt für jedes einen Erzeuger — entweder `web_04/` oder die Liste `ERZEUGTE_ASSETS`
(`highlight.css`, `search-index.js`, `programme.js`). Ein künftiger Eintrag im Seitenkopf
ohne Datei dahinter fällt sofort auf.
Die Probe aufs Exempel: `rm -rf OR_HTML_04 && --html` baut alle 213 Dateien wieder auf,
Dateiliste identisch zur Sicherung.
### 🐛 Fund: Das Stichwortverzeichnis war nicht byte-reproduzierbar
Beim Gegenprüfen der Neubau-Probe unterschied sich `stichwortverzeichnis.html` zwischen zwei
Läufen, ohne dass sich eine Quelle geändert hatte. Ursache in `ziel_links()`: sortiert wurde
nach `(seite, kontext)` — und `kontext` ist der **Kapiteltitel**, für alle Marken einer Datei
also derselbe. Bei zwei Fundstellen im selben Kapitel war der Schlüssel gleich, und die
Reihenfolge fiel auf die eines `set()` zurück, also auf den je Prozess zufälligen
`PYTHONHASHSEED`.
Derselbe Konstruktionsfehler war auch sichtbar: Vier `{idx:Branch-and-Bound}` in Kapitel 6
ergaben **vier optisch identische Links** nebeneinander — zehn Einträge im Register waren
davon betroffen. Behoben durch einen Link je Kapitel (die erste Fundstelle in
Dokumentreihenfolge, `dict` statt `set`). Damit ist die Sortierung zugleich eindeutig.
Gegenprobe: drei Läufe mit `PYTHONHASHSEED=random` liefern dieselbe Prüfsumme
`3da5b9b2…`. Keine Hauptzeile trägt mehr einen doppelten Link; die 219 Fachbegriffe und 328
Indexmarken bleiben unverändert.
---
## 8. Commit-Historie des V04-Strangs