diff options
| -rw-r--r-- | FASSUNGEN.txt | 59 | ||||
| -rw-r--r-- | README.md | 31 | ||||
| -rw-r--r-- | src/main/java/eu/mulk/aendggner/AendGgner.java | 8 | ||||
| -rw-r--r-- | src/main/java/eu/mulk/aendggner/Pipeline.java | 25 | ||||
| -rw-r--r-- | src/main/resources/eu/mulk/aendggner/web/app.js | 34 | ||||
| -rw-r--r-- | src/main/resources/eu/mulk/aendggner/web/index.html | 17 | ||||
| -rw-r--r-- | src/main/resources/eu/mulk/aendggner/web/style.css | 24 | ||||
| -rw-r--r-- | src/main/resources/eu/mulk/aendggner/web/worker.js | 5 | ||||
| -rw-r--r-- | src/test/java/eu/mulk/aendggner/EndToEndTest.java | 28 | ||||
| -rw-r--r-- | src/wasm/java/eu/mulk/aendggner/wasm/BrowserMain.java | 18 |
10 files changed, 221 insertions, 28 deletions
diff --git a/FASSUNGEN.txt b/FASSUNGEN.txt index 73665fb..7d13d8d 100644 --- a/FASSUNGEN.txt +++ b/FASSUNGEN.txt @@ -21,6 +21,65 @@ Vorbemerkung zur Führung dieses Verzeichnisses ════════════════════════════════════════════════════════════════════════════════ + Fassung vom 24. August 2026, + zuletzt geändert durch die am 24. August 2026 vorgenommenen Änderungen +════════════════════════════════════════════════════════════════════════════════ + +Die Browserfassung ist seit ihrer Einführung als die vollwertige zweite Fassung +des Erzeugnisses ausgegeben worden; sie war es nicht. Zwei Angaben, die die +Befehlszeile seit jeher kennt, fehlten ihr: die Beschränkung auf einen einzelnen +Artikel und die Ausgabe des maschinell gelesenen Textes. Die erste war im +Vordruck nicht vorgesehen, obgleich Arbeiter und Rechenwerk den Wert längst +durchreichten — das Formular sandte an ihrer Stelle einen leeren Wert. Die zweite +war überhaupt nicht erreichbar. + +Das Fehlende wiegt ungleich: Die Artikelangabe erspart Mühe, die Textausgabe +dagegen ist der einzige Weg, einem unerklärlich unangewandten Befehl auf den +Grund zu gehen. Wer im Browser arbeitet, stand vor einem Ergebnis, das er nicht +nachprüfen konnte, und war auf die Befehlszeile verwiesen — also gerade auf das, +was die Browserfassung entbehrlich machen sollte. + + +Artikel 1 +Gemeinsame Textgewinnung + +(1) Die Gewinnung des Änderungstextes wird aus der Befehlszeilenklasse in den + gemeinsamen Kern verlegt („Pipeline.extrahiereText“). Befehlszeile und + Browser nehmen fortan denselben Weg; die Ausgabe des Schalters + „--extract-only“ bleibt unverändert. + +(2) Eine Prüfung hält die Ausgabe gegen das, was der Parser bekommt. Führte der + Notausgang einen anderen Text vor, so wiese er in die Irre. + + +Artikel 2 +Ergänzung des Vordrucks + +(1) Der Vordruck erhält das Feld „Anzuwendender Artikel“; ohne Eintragung bleibt + es beim bisherigen Verhalten, dass alle Artikel angewandt werden, deren + Einleitung das Stammgesetz nennt. + +(2) Er erhält ferner das Ankreuzfeld „Statt der Synopse nur den maschinell + gelesenen Text der Änderungsdokumente ausgeben“. Der Text wird als Verweis + zum Öffnen und Sichern bereitgestellt; er lässt sich von Hand berichtigen und + als Klartextdatei wieder einreichen. + +(3) Ein nicht gesetztes Feld kommt aus dem Fenster als „undefined“ herüber; die + Umsetzung nach Wahrheitswerten trägt dem nunmehr Rechnung, statt daran zu + scheitern. + + +Artikel 3 +Berichtigung des Handbuchs + +(1) § 14 führte die Absatznummern (6) und (7) zweimal. Die Absätze werden + fortlaufend gezählt; der Verweis in § 4 wird angepasst. + +(2) In § 14 wird ein Absatz eingefügt, der die Angaben des Vordrucks den + Schaltern des § 6 Absatz 2 gegenüberstellt. + + +════════════════════════════════════════════════════════════════════════════════ Fassung vom 23. August 2026, zuletzt geändert durch die am 23. August 2026 vorgenommenen Änderungen ════════════════════════════════════════════════════════════════════════════════ @@ -157,7 +157,7 @@ Fassungen (`FASSUNGEN.txt`) geführt. `mvnw` abweichend bestimmt wird. (3) Vorausgesetzt wird ein Java-Entwicklungsbausatz der Fassung 21 oder neuer. -Für die Herstellung der Browserfassung gilt abweichend § 14 Absatz 3. +Für die Herstellung der Browserfassung gilt abweichend § 14 Absatz 4. ## § 5 Zulässige Eingaben @@ -476,7 +476,18 @@ Pipeline (`eu.mulk.aendggner.Pipeline`, § 16 Absatz 1) über ein Upload-Formular zugänglich macht: Stammgesetz- und Änderungsgesetz-Datei(en) wählen, Synopse erhalten. -(2) Über dem Formular steht ein zugeklappter Einführungsblock, der zwei +(2) Der Vordruck stellt außer den beiden Dateifeldern dieselben Angaben zur +Verfügung wie die Befehlszeile nach § 6 Absatz 2, nämlich das Feld +„Anzuwendender Artikel“ (`--artikel`), das Ankreuzfeld „Unveränderte +Vorschriften mit in die Synopse aufnehmen“ (`--vollstaendig`) und das +Ankreuzfeld „Statt der Synopse nur den maschinell gelesenen Text der +Änderungsdokumente ausgeben“ (`--extract-only`). Das letztgenannte ist kein +Zierat: Ohne es hätte, wer im Browser arbeitet, keine Möglichkeit, einem +unerklärlich unangewandten Befehl auf den Grund zu gehen. Der ausgegebene Text +ist derselbe, den der Parser bekommt; er lässt sich sichern, von Hand +berichtigen und als Klartextdatei wieder einreichen. + +(3) Über dem Formular steht ein zugeklappter Einführungsblock, der zwei durchgerechnete Fälle mit Verweisen auf die amtlichen Fundstellen anbietet, nämlich das UWG (`gesetze-im-internet.de/uwg_2004/xml.zip`) mit dem Dritten Gesetz zu seiner Änderung (BGBl. 2026 I Nr. 43) und das AGG @@ -484,7 +495,7 @@ zu seiner Änderung (BGBl. 2026 I Nr. 43) und das AGG Mitausgeliefert wird nichts; die Seite ruft die Dateien auch nicht selbst ab, sie verweist nur darauf. -(3) Ein Server ist nicht erforderlich: Die vollständige Verarbeitung — +(4) Ein Server ist nicht erforderlich: Die vollständige Verarbeitung — PDF-Textgewinnung mit PDFBox eingeschlossen — läuft als WebAssembly-Modul im Browser, übersetzt mit GraalVM Web Image aus demselben Java-Quelltext. Ausgeliefert werden nur statische Dateien; die gewählten Dokumente verlassen den @@ -496,7 +507,7 @@ nicht in der Community Edition: JAVA_HOME=/pfad/zu/oracle-graalvm ./mvnw -Pwasm package ``` -(4) Ergebnis ist `target/web/` mit `index.html`, `app.js`, `worker.js`, +(5) Ergebnis ist `target/web/` mit `index.html`, `app.js`, `worker.js`, `style.css`, `favicon.svg`, `aendggner.js` und `aendggner.js.wasm` (rund 17 MB, komprimiert etwa 5 MB). Das Verzeichnis ist so, wie es dasteht, auslieferbar: `deploy/webpaket.sh` läuft am Ende desselben Befehls, wirft den mehrere hundert @@ -504,7 +515,7 @@ Megabyte großen Textzwischenschritt `aendggner.js.wat` fort, schickt das Modul durch `wasm-opt -Oz` und legt den Quelltext der gebauten Fassung als `aendggner-quelltext.tar.gz` samt `quelltext-fassung.txt` bei. -(5) Die Größe des Moduls beruht auf vier Vorkehrungen; wer eine davon zurücknimmt, +(6) Die Größe des Moduls beruht auf vier Vorkehrungen; wer eine davon zurücknimmt, handelt sich die Megabyte wieder ein: 1. `-Os` beim Übersetzen statt der auf Durchsatz gerichteten Voreinstellung; @@ -522,7 +533,7 @@ handelt sich die Megabyte wieder ein: nutzt Binaryen auch Vorschläge, die noch kein Browser annimmt, und das Modul scheitert erst beim Instanziieren. -(6) Im Quelltextarchiv fehlt der Beispielkorpus; `.gitattributes` nimmt +(7) Im Quelltextarchiv fehlt der Beispielkorpus; `.gitattributes` nimmt `src/test/resources/sampledata` von `git archive` aus. Es sind Gesetzes- und Drucksachentexte fremder Urheberschaft, an denen allein die Tests messen — Quelltext im Sinne der AGPLv3 sind sie nicht, gebaut wird ohne sie, und sie @@ -532,18 +543,18 @@ die Anschrift nach § 3 Absatz 2. Wächst das Archiv wieder über 8 MiB, so bric `webpaket.sh` ab; alsdann sind Massendaten ins Repository geraten, die dort nicht hingehören. -(7) Trägt der Arbeitsbaum uneingecheckte Änderungen, so bricht die Herstellung -nach Absatz 3 ab, denn der beigelegte Quelltext wäre alsdann nicht der gebaute. +(8) Trägt der Arbeitsbaum uneingecheckte Änderungen, so bricht die Herstellung +nach Absatz 4 ab, denn der beigelegte Quelltext wäre alsdann nicht der gebaute. Für einen Probelauf hilft `QUELLTEXT_UNGEPRUEFT=1`. -(6) Zur örtlichen Ansicht genügt `file://` nicht; Browser laden Wasm-Module und +(9) Zur örtlichen Ansicht genügt `file://` nicht; Browser laden Wasm-Module und Worker nur über HTTP (<http://localhost:8000/>): ```shell jwebserver -d target/web ``` -(7) Die Befehlszeilenfassung (§ 6) bleibt hiervon unberührt und ist weiterhin der +(10) Die Befehlszeilenfassung (§ 6) bleibt hiervon unberührt und ist weiterhin der Weg für Massenläufe. ## § 15 Ausrollen diff --git a/src/main/java/eu/mulk/aendggner/AendGgner.java b/src/main/java/eu/mulk/aendggner/AendGgner.java index a12515a..58b0d50 100644 --- a/src/main/java/eu/mulk/aendggner/AendGgner.java +++ b/src/main/java/eu/mulk/aendggner/AendGgner.java @@ -12,6 +12,7 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; import java.util.EnumMap; import java.util.List; import java.util.concurrent.Callable; @@ -129,12 +130,11 @@ public class AendGgner implements Callable<Integer> { } if (extractOnly) { - var gesetz = Pipeline.ladeStammgesetz(baseFile); - var extraktor = new PatchTextExtraktor(Pipeline.superskriptModus(gesetz)); + var quellen = new ArrayList<Quelle>(); for (var file : patches) { - var text = extraktor.extrahiere(file); - System.out.println(raw ? text : TextBereiniger.bereinige(text)); + quellen.add(Quelle.lies(file)); } + System.out.print(Pipeline.extrahiereText(Quelle.lies(baseFile), quellen, raw)); return 0; } diff --git a/src/main/java/eu/mulk/aendggner/Pipeline.java b/src/main/java/eu/mulk/aendggner/Pipeline.java index 76b492f..7949e7f 100644 --- a/src/main/java/eu/mulk/aendggner/Pipeline.java +++ b/src/main/java/eu/mulk/aendggner/Pipeline.java @@ -275,6 +275,31 @@ public final class Pipeline { return dokument.kopf().art().istEntwurfsfassung(); } + /** + * Der Text der Änderungsdokumente, so wie das Erzeugnis ihn liest — der Notausgang des § 6 Absatz + * 2 des Handbuchs. + * + * <p>Bleibt die PDF-Aufbereitung im Einzelfall fehlerhaft, so ist nicht das Ergebnis zu + * beargwöhnen, sondern der Text nachzusehen, von Hand zu berichtigen und als Klartextdatei wieder + * einzuspeisen. Dass dieser Weg beiden Fassungen offensteht, ist kein Zierat: Wer im Browser + * arbeitet, hat sonst keine Möglichkeit, einem unerklärlichen Rest auf den Grund zu gehen. + * + * <p>Das Stammgesetz wird auch hier gebraucht, denn seine Schreibweise bestimmt den + * Superskriptmodus der Textgewinnung ({@link #superskriptModus}). + * + * @param roh die Bereinigung übergehen; nur zur Fehlersuche an der Textgewinnung selbst. + */ + public static String extrahiereText(Quelle baseFile, List<Quelle> patches, boolean roh) + throws Exception { + var extraktor = new PatchTextExtraktor(superskriptModus(ladeStammgesetz(baseFile))); + var text = new StringBuilder(); + for (var patch : patches) { + var roher = extraktor.extrahiere(patch); + text.append(roh ? roher : TextBereiniger.bereinige(roher)).append('\n'); + } + return text.toString(); + } + /** Bequemlichkeit für Befehlszeile und Tests; im Browser gibt es keine {@link Path}e. */ static Gesetz ladeStammgesetz(Path baseFile) throws Exception { return ladeStammgesetz(Quelle.lies(baseFile)); diff --git a/src/main/resources/eu/mulk/aendggner/web/app.js b/src/main/resources/eu/mulk/aendggner/web/app.js index 3a2957c..97eca52 100644 --- a/src/main/resources/eu/mulk/aendggner/web/app.js +++ b/src/main/resources/eu/mulk/aendggner/web/app.js @@ -30,6 +30,15 @@ async function alsBase64(datei) { return { name: datei.name, base64: btoa(roh) }; } +/** Hängt der Meldung einen Verweis auf das Ergebnis an; ein Blob, kein Server. */ +function oeffne(inhalt, art, aufschrift) { + const verweis = document.createElement("a"); + verweis.href = URL.createObjectURL(new Blob([inhalt], { type: art })); + verweis.target = "_blank"; + verweis.textContent = aufschrift; + meldung.append(verweis); +} + formular.addEventListener("submit", async (ereignis) => { ereignis.preventDefault(); @@ -40,6 +49,9 @@ formular.addEventListener("submit", async (ereignis) => { return; } + const artikel = document.querySelector("#artikel").value.trim(); + const nurText = document.querySelector("#nurtext").checked; + knopf.disabled = true; zeige("Lade das Rechenwerk (einmalig einige Megabyte) und werte aus …", "arbeit"); @@ -60,7 +72,8 @@ formular.addEventListener("submit", async (ereignis) => { stamm, patches, vollstaendig: document.querySelector("#vollstaendig").checked, - artikel: null, + artikel: artikel === "" ? null : artikel, + nurText, }); }); @@ -69,22 +82,25 @@ formular.addEventListener("submit", async (ereignis) => { return; } - const blob = new Blob([ergebnis.html], { type: "text/html;charset=utf-8" }); - const adresse = URL.createObjectURL(blob); - // Kein window.open: Der Aufruf käme nach dem Warten auf den Worker und gälte dem Browser // nicht mehr als Nutzerhandlung — er würde als Popup blockiert. Stattdessen ein Link, der // sich öffnen und ebenso gut speichern lässt. + if (nurText) { + zeige( + `${ergebnis.text.length.toLocaleString("de-DE")} Zeichen gelesen; ` + + `keine Synopse erstellt. `, + "fertig", + ); + oeffne(ergebnis.text, "text/plain;charset=utf-8", "Gelesenen Text öffnen"); + return; + } + zeige( `${ergebnis.angewandt} Befehle angewandt, ${ergebnis.manuell} manuell zu prüfen, ` + `${ergebnis.normen} geänderte Normen. `, "fertig", ); - const verweis = document.createElement("a"); - verweis.href = adresse; - verweis.target = "_blank"; - verweis.textContent = "Synopse öffnen"; - meldung.append(verweis); + oeffne(ergebnis.html, "text/html;charset=utf-8", "Synopse öffnen"); } catch (e) { zeige("Verarbeitung fehlgeschlagen: " + (e && e.message ? e.message : e), "fehler"); } finally { diff --git a/src/main/resources/eu/mulk/aendggner/web/index.html b/src/main/resources/eu/mulk/aendggner/web/index.html index 680aa8c..edca09e 100644 --- a/src/main/resources/eu/mulk/aendggner/web/index.html +++ b/src/main/resources/eu/mulk/aendggner/web/index.html @@ -132,12 +132,29 @@ gewählten Reihenfolge nacheinander angewendet)</span></label> <input type="file" id="aenderung" name="aenderung" multiple required> </div> + <div class="feld"> + <label for="artikel">Anzuwendender Artikel + <span class="erl">(nur auszufüllen, wenn abweichend: ohne Angabe werden alle + Artikel angewandt, deren Einleitung das oben bezeichnete Stammgesetz + nennt)</span></label> + <input type="text" id="artikel" name="artikel" inputmode="numeric" + autocomplete="off" placeholder="z. B. 3"> + </div> <div class="feld ankreuzfeld"> <label> <input type="checkbox" id="vollstaendig" name="vollstaendig"> Unveränderte Vorschriften mit in die Synopse aufnehmen </label> </div> + <div class="feld ankreuzfeld"> + <label> + <input type="checkbox" id="nurtext" name="nurtext"> + Statt der Synopse nur den maschinell gelesenen Text der Änderungsdokumente ausgeben + </label> + <p class="erl nachsatz">Zur Nachschau, wenn ein Befehl unerklärlich unangewandt + bleibt: Der Text lässt sich sichern, von Hand berichtigen und als Klartextdatei + oben wieder einreichen.</p> + </div> </div> </div> diff --git a/src/main/resources/eu/mulk/aendggner/web/style.css b/src/main/resources/eu/mulk/aendggner/web/style.css index 36c2198..80479ff 100644 --- a/src/main/resources/eu/mulk/aendggner/web/style.css +++ b/src/main/resources/eu/mulk/aendggner/web/style.css @@ -215,6 +215,24 @@ input[type="file"] { font-size: 0.75rem; } +/* Die Eintragung von Hand steht auf einer Linie, wie im gedruckten Vordruck; sie ist kurz, + weil dort nur eine Artikelnummer hingehört. */ +input[type="text"] { + width: 8rem; + margin-top: 0.35rem; + padding: 0.1rem 0.2rem; + border: none; + border-bottom: 1px solid var(--linie); + background: transparent; + color: inherit; + font: inherit; + font-size: 0.8125rem; +} + +input[type="text"]::placeholder { + color: var(--muted); +} + /* Der Dateiwähler ist der einzige Knopf im Feld und trägt deshalb die Form der übrigen Eintragungsfelder: eckig, haarfein umrandet, weiß. */ input[type="file"]::file-selector-button { @@ -232,6 +250,12 @@ input[type="file"]::file-selector-button:hover { background: var(--grund); } +/* Der Nachsatz zu einem Ankreuzfeld steht unter dem Text, nicht neben ihm, und rückt bis + unter die Aufschrift ein. */ +.nachsatz { + margin: 0.15rem 0 0 1.6rem; +} + /* Das Ankreuzfeld steht vor dem Text und wird angekreuzt, nicht angehakt. */ .ankreuzfeld label { display: flex; diff --git a/src/main/resources/eu/mulk/aendggner/web/worker.js b/src/main/resources/eu/mulk/aendggner/web/worker.js index f20e873..827358e 100644 --- a/src/main/resources/eu/mulk/aendggner/web/worker.js +++ b/src/main/resources/eu/mulk/aendggner/web/worker.js @@ -19,7 +19,7 @@ const gestartet = GraalVM.run([], Object.assign(new GraalVM.Config(), { })); self.onmessage = async (nachricht) => { - const { stamm, patches, vollstaendig, artikel } = nachricht.data; + const { stamm, patches, vollstaendig, artikel, nurText } = nachricht.data; try { await gestartet; await bereit; @@ -28,9 +28,12 @@ self.onmessage = async (nachricht) => { patches, artikel: artikel ?? null, vollstaendig: Boolean(vollstaendig), + nurText: Boolean(nurText), }); if (ergebnis.fehler) { self.postMessage({ fehler: String(ergebnis.fehler) }); + } else if (nurText) { + self.postMessage({ text: String(ergebnis.text) }); } else { self.postMessage({ html: String(ergebnis.html), diff --git a/src/test/java/eu/mulk/aendggner/EndToEndTest.java b/src/test/java/eu/mulk/aendggner/EndToEndTest.java index 2698fa5..fe98b84 100644 --- a/src/test/java/eu/mulk/aendggner/EndToEndTest.java +++ b/src/test/java/eu/mulk/aendggner/EndToEndTest.java @@ -99,6 +99,34 @@ class EndToEndTest { * die Rechnung vollständig auf: <b>75 von 75</b>, kein Rest. Das ist zugleich der Beleg, dass die * 27 nie ein Mangel des Werkzeugs waren. */ + /** + * Der Notausgang (§ 6 Absatz 2 des Handbuchs) gibt aus, was das Erzeugnis gelesen hat, und geht + * dabei denselben Weg wie die Synopse — auf ihn verlässt sich, wer einem unerklärlichen Rest + * nachgeht, und seit Welle 21 tut das auch die Browserfassung. + */ + @Test + void notausgangLiefertDenGelesenenText() throws Exception { + assumeTrue(Files.exists(STAMMGESETZ), "IfSG-Beispieldaten fehlen"); + assumeTrue(Files.exists(AENDERUNGSGESETZ), "BGBl-Beispiel-PDF fehlt"); + + var stamm = Quelle.lies(STAMMGESETZ); + var patches = List.of(Quelle.lies(AENDERUNGSGESETZ)); + + var bereinigt = Pipeline.extrahiereText(stamm, patches, false); + var roh = Pipeline.extrahiereText(stamm, patches, true); + + // Wortgleich mit dem, was der Parser bekommt — sonst führte der Notausgang in die Irre. + assertThat(bereinigt) + .isEqualTo( + TextBereiniger.bereinige(new PatchTextExtraktor().extrahiere(AENDERUNGSGESETZ)) + "\n"); + assertThat(bereinigt).contains("Nach § 28 wird folgender § 28a eingefügt"); + // Die Bereinigung nimmt fort, was der Satz beisteuert (Kolumnentitel, Trennstriche); der + // Rohtext ist deshalb länger und trägt den Kopf des Gesetzblatts noch. + assertThat(roh).hasSizeGreaterThan(bereinigt.length()); + assertThat(roh).contains("Bundesgesetzblatt"); + assertThat(bereinigt).doesNotContain("Bundesgesetzblatt Jahrgang 2020 Teil I Nr."); + } + @Test void ifsgGegenZeitrichtigenStamm() throws Exception { var xml = SAMPLEDATA.resolve("IfSG/BJNR104510000-2020.xml"); diff --git a/src/wasm/java/eu/mulk/aendggner/wasm/BrowserMain.java b/src/wasm/java/eu/mulk/aendggner/wasm/BrowserMain.java index 7df8ecb..c318f86 100644 --- a/src/wasm/java/eu/mulk/aendggner/wasm/BrowserMain.java +++ b/src/wasm/java/eu/mulk/aendggner/wasm/BrowserMain.java @@ -22,9 +22,10 @@ import org.graalvm.webimage.api.JSValue; * damit dieselbe {@link Pipeline} auf wie Befehlszeile und Tests. * * <p>Erwartet ein JS-Objekt <code>{stamm: {name, base64}, patches: [{name, base64}], artikel, - * vollstaendig}</code> und liefert <code>{html, angewandt, manuell, normen}</code> oder <code> - * {fehler}</code> zurück. Geworfen wird nichts: Eine Ausnahme im Wasm hinterlässt auf der JS-Seite - * nur einen unlesbaren Stapel, also wird jeder Fehler als Text zurückgereicht. + * vollstaendig, nurText}</code> und liefert <code>{html, angewandt, manuell, normen}</code> — bei + * <code>nurText</code> stattdessen <code>{text}</code> — oder <code>{fehler}</code> zurück. + * Geworfen wird nichts: Eine Ausnahme im Wasm hinterlässt auf der JS-Seite nur einen unlesbaren + * Stapel, also wird jeder Fehler als Text zurückgereicht. * * <p>Der Dateiinhalt wandert als Base64-Text über die Grenze, nicht als {@code Uint8Array}: Die * Umsetzung typisierter Felder nach {@code byte[]} ist in Web Image derzeit defekt („byteArrayHub @@ -71,6 +72,14 @@ public final class BrowserMain { var artikel = text(eingabe.get("artikel")); var vollstaendig = Boolean.TRUE.equals(wahrheitswert(eingabe.get("vollstaendig"))); + if (Boolean.TRUE.equals(wahrheitswert(eingabe.get("nurText")))) { + // Der Notausgang der Befehlszeile (--extract-only) steht auch hier offen: Wer einem Rest + // nachgehen will, muss sehen können, was das Erzeugnis gelesen hat. + antwort.set( + "text", JSString.of(Pipeline.extrahiereText(stamm, List.copyOf(patches), false))); + return antwort; + } + var ergebnis = Pipeline.erzeugeSynopse( stamm, @@ -132,7 +141,8 @@ public final class BrowserMain { return b; } if (wert instanceof JSValue v) { - return v.asBoolean(); + // Ein nicht gesetztes Feld kommt als „undefined“ herüber; asBoolean() bräche daran. + return "undefined".equals(v.typeof()) ? Boolean.FALSE : v.asBoolean(); } return Boolean.FALSE; } |
