Files
dejanandClaude Opus 5 6a0b36ddcc Geviertstriche aus Text, Kommentaren und Doku entfernen
467 Stellen. Nicht durch einen anderen Strich ersetzt, sondern durch das
Satzzeichen, das an der jeweiligen Stelle richtig ist: Doppelpunkt, wo eine
Erlaeuterung folgt; Komma, wo der Satz weiterlaeuft; Punkt, wo zwei
Hauptsaetze aneinanderstiessen. Ein Halbgeviertstrich waere nur derselbe
Griff mit kuerzerem Strich gewesen.

Regelbasiert ersetzt und danach nachgeprueft, weil eine Regel allein nicht
reicht. Gefunden und einzeln korrigiert:

- Eingeschobene Saetze mit Strichpaar. Nur der oeffnende Strich passte ins
  Muster, der schliessende blieb als "—," stehen. Drei Stellen, jetzt mit
  Klammern oder als eigener Satz.

- Doppelte Doppelpunkte, wo beide Striche eines Paars zu Doppelpunkten wurden
  ("Globale Regeln: Schrift, Groessen, Abstaende: kommen aus HiveGrid").
  Sieben Stellen in Doku und Oberflaeche, jetzt in Klammern.

- Pfade, denen ein Komma statt eines Doppelpunkts folgte.

- Ausgerichtete Kommentartabellen, in denen der Strich eine Spalte war.

Nicht angefasst: drei Geviertstriche, die keine Prosa sind, sondern
Tabellenplatzhalter fuer "kein Wert" (Trichter, Auftraege, Kunden). Dort ist
der Strich die Angabe selbst; ihn zu entfernen liesse leere Zellen zurueck.

tsc, lint, build, verify:carbon und verify:layout laufen sauber.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QPeZNwSeU7qG3RRCwaxEZX
2026-08-31 20:51:19 +02:00

138 lines
5.0 KiB
JavaScript

#!/usr/bin/env node
/**
* Prüft chartTheme.ts gegen docs/carbon-referenz.json.
*
* Warum das existiert: „Wir halten uns an IBM Carbon" ist eine Behauptung,
* solange sie niemand nachrechnet. Farbwerte driften beim Kopieren, und die
* Carbon-Dokumentation widerspricht stellenweise dem ausgelieferten Code.
* Dieser Prüfer macht aus der Behauptung eine Zusage.
*
* Aufruf: npm run verify:carbon
*/
import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
import { dirname, join } from "node:path";
const wurzel = join(dirname(fileURLToPath(import.meta.url)), "..");
const referenz = JSON.parse(readFileSync(join(wurzel, "docs/carbon-referenz.json"), "utf8"));
const theme = readFileSync(join(wurzel, "features/dashboard/utils/chartTheme.ts"), "utf8");
const fehler = [];
const hinweise = [];
/** Liest ein exportiertes Array von Hex-Werten aus dem Theme. */
function hexArray(name) {
const block = theme.match(new RegExp(`export const ${name}[^=]*=\\s*\\[([\\s\\S]*?)\\]`));
if (!block) return null;
return [...block[1].matchAll(/#[0-9a-fA-F]{6}/g)].map((m) => m[0].toLowerCase());
}
/** Liest einen einzelnen Hex-Wert aus einem Objektfeld im Theme. */
function hexFeld(objekt, feld) {
const block = theme.match(new RegExp(`export const ${objekt}[^=]*=\\s*\\{([\\s\\S]*?)\\}`));
if (!block) return null;
const treffer = block[1].match(new RegExp(`${feld}\\s*:\\s*"(#[0-9a-fA-F]{6})"`));
return treffer ? treffer[1].toLowerCase() : null;
}
/* -------------------------------------------------- Kategoriale Palette */
const palette = hexArray("KATEGORIE_FARBEN");
const soll = referenz.kategorialePalette.werte.map((w) => w.toLowerCase());
if (!palette) {
fehler.push("KATEGORIE_FARBEN nicht gefunden");
} else if (palette.length !== soll.length) {
fehler.push(`Palette hat ${palette.length} Farben, Carbon hat ${soll.length}`);
} else {
palette.forEach((farbe, i) => {
if (farbe !== soll[i]) {
fehler.push(`Palette Position ${i + 1}: ${farbe}: Carbon: ${soll[i]}`);
}
});
}
/* ------------------------------------------------------- Neutrale Werte */
const neutraleZuordnung = {
grid: "gitterlinie",
achse: "achsenlinie",
textSekundaer: "achsenbeschriftung",
text: "textPrimaer",
};
for (const [feld, refName] of Object.entries(neutraleZuordnung)) {
const ist = hexFeld("CHART", feld);
const sollWert = referenz.neutraleWerte[refName].wert.toLowerCase();
if (ist === null) fehler.push(`CHART.${feld} nicht gefunden`);
else if (ist !== sollWert) {
fehler.push(
`CHART.${feld} = ${ist}: Carbon ${referenz.neutraleWerte[refName].token}: ${sollWert}`
);
}
}
/* ---------------------------------------------------------------- Tooltip */
const tooltipBg = hexFeld("CHART", "tooltipBg");
const tooltipFg = hexFeld("CHART", "tooltipFg");
if (tooltipBg !== referenz.tooltip.hintergrund.wert.toLowerCase()) {
fehler.push(
`CHART.tooltipBg = ${tooltipBg}: Carbon ${referenz.tooltip.hintergrund.token}: ${referenz.tooltip.hintergrund.wert}`
);
}
if (tooltipFg !== referenz.tooltip.text.wert.toLowerCase()) {
fehler.push(`CHART.tooltipFg = ${tooltipFg}: Carbon: ${referenz.tooltip.text.wert}`);
}
/* ------------------------------------------------- Achsen-Tickanzahl */
const raster = theme.match(/nettesRaster\(\s*\n?\s*max: number,\s*\n?\s*maxIntervalle = (\d+)/);
if (raster && Number(raster[1]) !== referenz.achsen.ticksYAchse) {
fehler.push(
`nettesRaster maxIntervalle = ${raster[1]}: Carbon numberOfTicks (y): ${referenz.achsen.ticksYAchse}`
);
}
/* -------------------------------------------- Bewusste Abweichungen melden */
const balken = theme.match(/maxBreite:\s*(\d+)/);
const abwBalken = referenz.bewusstAbweichend.balkenMaxBreitePx;
if (balken) {
if (Number(balken[1]) !== abwBalken.hier) {
fehler.push(
`BALKEN.maxBreite = ${balken[1]}, dokumentiert ist ${abwBalken.hier}. ` +
`Entweder den Wert zurücksetzen oder docs/carbon-referenz.json nachziehen.`
);
} else {
hinweises(`Balkenbreite ${abwBalken.hier} px statt Carbon ${abwBalken.carbon} px`, abwBalken.grund);
}
}
function hinweises(titel, grund) {
hinweise.push({ titel, grund });
}
hinweises(
"Feste Farbe je Kategorie statt n-Serien-Palette",
referenz.bewusstAbweichend.festeKategorieFarben.grund
);
/* ------------------------------------------------------------- Ausgabe */
console.log(`Carbon-Abgleich gegen ${referenz.quelle.version} (${referenz.quelle.geprueftAm})\n`);
if (hinweise.length) {
console.log("Bewusste Abweichungen (dokumentiert, kein Fehler):");
for (const h of hinweise) console.log(` · ${h.titel}\n ${h.grund}\n`);
}
if (fehler.length) {
console.error(`${fehler.length} Abweichung(en) von Carbon:`);
for (const f of fehler) console.error(` ✗ ${f}`);
console.error("\nEntweder chartTheme.ts korrigieren oder die Abweichung in");
console.error("docs/carbon-referenz.json unter 'bewusstAbweichend' begründen.");
process.exit(1);
}
console.log("✓ Palette, neutrale Werte, Tooltip und Achsenraster stimmen mit Carbon überein.");