Umbruch
Zu hohe unteilbare Blöcke, Restzeilen am Seitenanfang und Seitenende, Überschriften am Seitenfuß, Fortsetzungsseiten und Trennungen über den Umbruch. Halbleere Seiten nur auf ausdrückliche Anforderung.
Wer PDFs aus HTML erzeugt, sieht Fehler erst nach der Paginierung: eine Überschrift am Seitenfuß, eine Restzeile allein auf der Folgeseite, ein Block, der auf keine Seite passt. breaklint misst jede Seite nach dem Umbruch und nennt zu jedem Befund den gemessenen Wert neben der Schwelle, an der er scheiterte.
Film · 0:39 · Instrumentalmusik, kein Sprechtext
npx breaklint --demo
Der Befehl braucht keinen Browser und keine Konfiguration. Er endet mit Exit 1, weil das mitgelieferte Beispiel absichtlich Befunde enthält — eine Demo, die mit 0 endet, zeigt nie, wie ein Befund aussieht. Der Block unten zeigt einen vollständigen Befund der mitgelieferten Demo; nur die langen Zeilen sind für das Lesemaß umbrochen. Die Regelkette darin ist die echte; die Seite, die sie beurteilt, ist ein handgeschriebenes Fixture, damit jeder Regelpfad ohne Browser erreichbar ist — der Bericht schreibt selbst in sein source-Feld, welche Art Fixture er gelesen hat.
error svg/text-overflows-viewport page 5
measured 72 px; threshold 0 px (uncalibrated)
detail This text extends 72.00 px beyond the
SVG viewport and is not drawn.
Coordinates are normalised through
getScreenCTM().
remedy Text rendered inside an SVG extends
outside the SVG viewport bounds and is
clipped. Enlarge the SVG 'viewBox' or
its width/height, or adjust the <text>
coordinates ('x', 'y', 'text-anchor').
'overflow: visible' on the container
also clears the finding, but it does not
move the text: the viewport then no
longer clips, the target becomes
non-applicable and this rule stops
measuring it. Use that only where the
overflow is intended.
untested: no trigger/remedied pair in
this package shows this advice removing
this finding
source unknown (node produced by the paginator)
render unknown (no evidence produced)
Prosa-Linter sehen keine Seite. Satzsysteme sehen die Seite, kennen aber die deutsche typografische Konvention nicht. Für Dokumente, die aus HTML zu PDF entstehen, gab es beides nicht.
Der Anlass war ein Fall, den die Prüfung am Quelltext nicht gefunden hat: eine Grafik bestand die XML-Validitätsprüfung und eine Geometrieprüfung — und kam mit kollidierenden Beschriftungen aus dem Renderer. Ob eine Seite trägt, entscheidet sich nach der Paginierung, im Renderer, mit den Schriften, die tatsächlich verfügbar waren.
Dreizehn Regeln, zwölf davon per Default aktiv. Zwei können einen Build scheitern lassen; zehn weitere sind Hinweise, bis man mit --fail-on warn ausdrücklich mehr verlangt. Die dreizehnte — layout/half-empty-page — ist experimentell, bewegt nie einen Exit-Code und läuft seit 0.6.0 nicht mehr im Default-Profil: sie feuerte auf 37 von 40 Dokumenten eines eigens dafür gebauten Korpus. Sie bleibt registriert und mit --profile strict oder --only abrufbar. Diese Trennung ist keine Vorsicht, sondern die Beweislast: nur zwei Regeln vergleichen unmittelbar gemessene Größen mit einer strukturellen Grenze.
Zu hohe unteilbare Blöcke, Restzeilen am Seitenanfang und Seitenende, Überschriften am Seitenfuß, Fortsetzungsseiten und Trennungen über den Umbruch. Halbleere Seiten nur auf ausdrückliche Anforderung.
Text, der über den Viewport hinausläuft. Clip-/Masken-Beschneidung und Pixelkollision sind noch keine ausgelieferten Regeln: der Produktionspfad besitzt dafür keinen sicheren Ink-Pass.
Bindestrich statt Gedankenstrich, gerade Anführungszeichen im Satz, zu kurze Ausgangszeilen, aufgerissene Wortabstände.
file:-Verweise und Pfade der Buildmaschine, die im ausgelieferten Dokument stehen geblieben sind.
Alle dreizehn ausgelieferten Regeln sind weiterhin als uncalibrated gekennzeichnet. Die zwei Ink-Definitionen bleiben als ausdrücklich nicht ausgelieferte M3-Forschung erhalten. Die technische Grundlage für eine spätere Kalibrierung steht inzwischen: Läufe im echten Renderer, ein auf Rechte und Datenschutz geprüfter Prozesspilot mit drei realen Dokumenten, getrennte Daten für Entwicklung, Schwellenabstimmung und die zurückgehaltene Schlussprüfung sowie verblindete Prüfpakete und Kontrollen gegen unzulässige Evidenz.
Das ist noch keine empirische Kalibrierung. Dafür fehlen ein ausreichend großer Korpus echter Dokumente, zwei voneinander unabhängige blinde menschliche Bewertungen, die dokumentierte Klärung von Uneinigkeiten, eine extern bestätigte und unverändert eingefrorene Testmenge sowie genau eine vorab festgelegte Schlussauswertung. Bis dahin bleibt bei jeder Regel calibrated: false.
Die Tests und Renderer-Nachweise zeigen, dass breaklint die Messungen der dreizehn ausgelieferten Regeln ausführt und bekannte Gegenbeispiele erkennt. Eine verpflichtende Prüfung an realen Dokumenten bindet eine unveränderte, auf Rechte und Datenschutz geprüfte Project-Gutenberg-HTML-Datei eines Dritten und zusätzlich einen eigenen Fall zur Paketierung, verlangt exakte Zahlen für Seiten und gemessene Regeln und weist Abweichungen der Infrastruktur zurück; das belegt Robustheit, nicht Kalibrierung. Wie häufig heuristische Grenzen bei realen Dokumenten richtig liegen, bleibt unbekannt.
Dafür gibt es veraPDF und pdfcpu.
Für Pixel- oder Bilddifferenzen gibt es Visual-Diff-Werkzeuge. Der konservative Dokument-Reparaturvergleich von breaklint verlangt dagegen ein vollständig verifiziertes, kompatibles Ziel.
Dafür gibt es vale und typopo.
PDF wird erzeugt und gerastert, um Belege zu produzieren — nie gelesen, um es zu prüfen.
Aktueller Release: 0.8.0; 0.7.0 ist der unmittelbare Vorgänger. Der aktuelle Stand liefert dreizehn öffentliche Regeln statt fünfzehn Definitionen; zwölf sind standardmäßig aktiv. Alle Regeln sind weiterhin unkalibriert. Ein Bildfehler wird nur dann als image-content-unavailable nicht-fatal benannt, wenn positive width- und height-Attribute exakt der gemessenen Browserbox entsprechen; Ersatztext und CSS-Abweichungen genügen nicht.
Neu in 0.8.0: Für jedes Dokument gilt standardmäßig ein Zeitbudget von 600000 ms (zehn Minuten). In breaklint.config.json setzt documentTimeoutMs den Wert; --document-timeout-ms <n> überschreibt ihn für einen Lauf. Erlaubt sind ganzzahlige Werte von 30000 bis 1800000 ms. Ungültige Werte enden mit Exit 2. Wird das Budget erreicht, endet der Lauf mit Exit 3 und nennt den wirksamen Wert. Das Budget begrenzt die Dauer; es beschleunigt die Paginierung nicht und senkt den Speicherbedarf großer Dokumente nicht.
0.8.0 weist zwei bekannte Quellen stillen Inhaltsverlusts vor der Messung zurück: einen body mit berechnetem column-count oder column-width (auch column-count: 1) und eine nichtleere Überschrift mit display: contents. Beide Fälle enden mit Exit 3 statt einem sauberen Ergebnis. Wiederholter SVG-Text im normalen Seiteninhalt wird pro Vorkommen zugeordnet. Inline-SVG-Text in laufenden Randkästen bleibt eine Ausnahme: Wiederholen sich die Kopien auf mehreren Seiten mit derselben Target-ID, endet die Prüfung mit checker-crashed (Exit 3). Eine allgemeine Vollständigkeitsprüfung des PDFs ist damit nicht belegt.
Bei sichtbarem Strich um SVG-Text kann breaklint in eng begrenzten Fällen nachweisen, dass eine konservativ berechnete Hülle vollständig innerhalb des SVG-Viewports liegt. Dafür müssen auch Strichbreite und -form sowie die Transformationen prüfbar sein. Berührt die Hülle den Viewport-Rand, bleibt das Ziel ungemessen. Da die Regel svg/text-overflows-viewport vollständige Abdeckung verlangt, endet der Lauf mit Exit 4. Der Nachweis bestimmt weder die exakte sichtbare Kontur noch meldet er einen nur teilweise außerhalb liegenden Strich als Fehler. Masken und Filter bleiben ungemessen.
0.7.0 hebt den Snapshot auf Version 5; Report 5, Agenten-Kontext 2 und Configuration 1 bleiben. Mehrere Regeln urteilen an unveränderten Dokumenten anders: Befunde können hinzukommen oder wegfallen, und wer Seitenbefunde über ihren Fingerprint verfolgt, braucht eine neue Baseline. layout/unbreakable-block-too-tall, eine der zwei Regeln, die per Default einen Build scheitern lassen, summiert die Höhe eines Blocks über seine Fragmente, sobald der Paginator ihn in drei oder mehr Stücke geteilt hat; ein zu hoher Block, der in genau zwei Stücke bricht, bleibt weiterhin ungemeldet. Einen geteilten Block, dessen Fragmente sich nicht über ihre Quelle zusammenführen lassen, misst die Regel nicht mehr am ersten Fragment, sondern lehnt ihn ab und rechnet das gegen die Abdeckung; ein solcher Lauf kann mit Exit 4 enden, wo er bisher sauber endete. Inhalte in den Seitenrändern, etwa Kopf- und Fußzeilen aus position: running(...), zählen nicht mehr als Textfluss und werden von keiner Regel beurteilt. Ob eine Seitengrenze erzwungen war, liest breaklint jetzt aus der Umbruchentscheidung des Paginators, auch in Bereichen mit benannten Seiten. Ein Bericht, der in eine Pipe geschrieben wird, kommt vollständig an; bis 0.6.0 konnte er an einem Vielfachen des Pipe-Puffers abgeschnitten werden, unter Linux meist bei 64 KiB. Lässt er sich nicht vollständig schreiben, endet der Lauf mit Exit 3. Für erzeugte Dokumente benennt breaklint eine editierbare Originalstelle nur, wenn ein hostgesteuerter Producer die Originalbytes erfasst und die Herkunft nachweist. Aus demselben kanonischen JSON entstehen die offline nutzbare Ansicht für Menschen und ein begrenzter Kontext für KI-Systeme. Ein Reparaturvergleich erklärt einen Befund nur bei verifiziertem, identischem Ziel sowie kompatibler Revision, Regeln, Konfiguration, Renderumgebung, Fonts und Ressourcen für behoben; unbekannte Herkunft und Teilabdeckung bleiben ausdrücklich sichtbar.
Die seit 0.7.0 verfügbare GitHub Action lässt sich mit uses: godarg/breaklint@v0.8.0 einbinden. Sie installiert das veröffentlichte npm-Release, prüft die angegebenen HTML-Pfade in einem Lauf, schreibt aus dem einen kanonischen JSON-Bericht zusätzlich SARIF, JUnit und eine Markdown-Zusammenfassung und lässt den Schritt mit dem Exit-Code von breaklint enden; Exit 2, 3 und 4 lassen ihn immer scheitern. Einen Workflow zum Übernehmen enthält docs/ci-recipe.md. Getestet ist die Action auf ubuntu-latest, macOS-Runner sind ungetestet. Sie braucht bash 4 oder neuer; mit dem /bin/bash 3.2 von macOS bricht sie mit Exit 3 ab.
Die öffentliche checkPage-API prüft getrennt davon eine bereits vorbereitete Playwright-Page: Sie übernimmt weder Navigation noch Anmeldung oder Netzpolitik. Im eigenen Betrieb prüft sie in der Testsuite eines internen Dashboards 45 Zustände: neun Ansichten bei fünf Breiten. Der Kommandozeilenpfad nimmt weiterhin ausschließlich .html/.htm an; eigenständige SVG-, PDF- und Markdown-Dateien enden mit Usage Exit 2. Node 22.13 oder neuer, auf macOS oder Linux. Ein Lauf über echte Dokumente braucht zusätzlich einen Chromium-basierten Browser und pagedjs@0.4.3; pdfjs-dist rastert das erzeugte PDF, um Belege an Befunde zu binden. Windows wird nicht unterstützt — die Prozessbehandlung ruht auf POSIX-Prozessgruppen. Der Messpfad ist unter Linux belegt; Prozessbeendigung und Profilbereinigung sind empirisch nur auf macOS gemessen.
npm i -D breaklint
npm i -D puppeteer-core@^25.8.0 pagedjs@0.4.3 pdfjs-dist@6.2.108
breaklint führt fremdes HTML samt Skripten aus. Der Offline-Modus fängt Seitenanfragen ab, ist aber keine Egress-Kontrolle: WebSocket-, WebTransport- und WebRTC-Verbindungen eines Dokuments sowie Browser-Verkehr über DNS over HTTPS und den Component Updater erfasst er nicht. Seit 0.8.0 verweigert breaklint den Renderer-Start, wenn PUPPETEER_DANGEROUS_NO_SANDBOX oder PUPPETEER_TEST_EXPERIMENTAL_CHROME_FEATURES gesetzt ist; CHROME_EXTRA_FLAGS wird aus der Chrome-Umgebung entfernt. Weitere Wrapper-Variablen sind nicht allgemein geprüft. Fremde Dokumente gehören in einen Container oder Netz-Namespace ohne Egress.
Noch offen: Dokumente mit Paged.js-Fußnoten enden vor der Regelprüfung mit Exit 3. Einzelne Regeln lehnen die Messung mehrspaltiger Blöcke ab. Ein zu hoher unteilbarer Block, der in genau zwei Fragmente zerfällt, bleibt ungemeldet.
breaklint verwendet zur Prüfzeit kein Sprachmodell. Es führt keine Inferenz aus und enthält keinen API-Client.
Genau diese Fälle suchen wir. Jeder kann ein öffentliches oder eigens dafür gebautes HTML-Dokument testen — ohne Bewerbung, Auswahl oder Vorkenntnisse. Der kurze Leitfaden führt in etwa zehn Minuten vom Installieren bis zum strukturierten Bericht.
Bitte nur Inhalte verwenden, die veröffentlicht werden dürfen. GitHub-Name, Bericht und Reproduktion sind öffentlich; vertrauliche Dokumente, personenbezogene Daten und Sicherheitsbefunde gehören nicht in das Formular. Die Auswertung nimmt strukturierte Angaben automatisch an, führt eingereichte Inhalte aber niemals aus.
Das Programm ist zusätzliche Qualitätssicherung. Öffentliche Tests sind keine Blindstudie und ersetzen nicht die noch ausstehende empirische Kalibrierung der Regeln.
breaklint entsteht bei Dargel Solutions und ist unter der MIT-Lizenz frei verwendbar, auch kommerziell. Teile des Repositories wurden mit Hilfe von Sprachmodellen geschrieben; der Regelsatz, die Schwellen und ihre Quellen wurden von einem Menschen gewählt. Jede Regel, die sich auf das deutsche Regelwerk der Rechtschreibung beruft, wurde gegen dessen veröffentlichten Text geprüft, nicht gegen die Zusammenfassung eines Modells.
Für die Erstellung und Pflege dieser Seite wird generative KI eingesetzt. Die fachliche und visuelle Veröffentlichungsfreigabe bleibt bei einem Menschen.
breaklint ist im Verzeichnis PeerPush eingetragen.