diff --git a/animation.mjs b/animation.mjs index b311b16..7b30790 100644 --- a/animation.mjs +++ b/animation.mjs @@ -161,6 +161,25 @@ try { if (kasten.x !== 0 || kasten.y !== 0) throw new Error(`${a.key} sitzt bei ${kasten.x},${kasten.y} statt 0,0`); + /* Dieselbe Umlautpruefung wie der Bildexport. Das Bewegtbild laeuft nicht + durch renderSlide und waere sonst die Luecke: auf einer Slide faellt + "Sanitaer" beim Export auf, in 180 Bildern niemandem. + + Ueber den ganzen Ablauf und nicht nur einmal: der Text einer Animation + aendert sich mit t. Beim ersten Versuch lief die Pruefung nur auf dem + Anfangsbild und fand nichts -- die fehlerhaften Optionen erscheinen + erst ab t = 0,4. Vierundzwanzig Stellen decken jeden Zustand ab und + kosten zusammen weniger als eine Sekunde. */ + const gesehen = new Set(); + for (let p = 0; p < 24; p++) { + await cdp.werte(`window.animSetzen(${a.i}, ${p / 24})`); + const f = await cdp.werte("window.TEXT_PRUEFUNG ? window.TEXT_PRUEFUNG() : []"); + (f || []).forEach(w => gesehen.add(w)); + } + if (gesehen.size) + throw new Error(`${a.key}: Umlaut fehlt bei ${[...gesehen].join(", ")}. ` + + "Wenn das Wort so richtig ist, gehoert es in UMLAUT_ERLAUBT."); + const ordner = await mkdtemp(path.join(tmpdir(), "postgrid-bilder-")); process.stdout.write(` ${a.key}: ${anzahl} Bilder `); for (let n = 0; n < anzahl; n++) { diff --git a/post1.html b/post1.html index b3fe51a..0dedc50 100644 --- a/post1.html +++ b/post1.html @@ -2263,6 +2263,52 @@ if (location.search.indexOf("nur=streifen") >= 0) return n < 20 ? 1 : dunkel / n; } + + /* ─── Umlaute im gezeichneten Text ─────────────────────────────────────── + Auf einer Slide stand einmal "Sanitaer" und "Klima / Lueftung". Beides + kam woertlich aus der Quelle -- im Klickdummy war es dort schludrig + eingetippt --, und beides las sich im fertigen Beitrag wie ein Fehler, + weil es einer ist. Gefunden hat es niemand beim Bauen, sondern erst + jemand, der auf den fertigen Post geschaut hat. + + Deshalb prueft es jetzt der Export. Ein reines Muster genuegt dafuer + nicht: Deutsch schreibt "neue", "Dauer", "Michael" voellig zu Recht mit + ae/oe/ue. Nachgezaehlt ueber den gezeichneten Text aller Projekte sind es + aber nur eine Handvoll solcher Woerter -- eine Ausnahmeliste ist also + kurz und trifft trotzdem alles andere. + + ss ist der umgekehrte Fall: fast immer richtig (dass, Schluss, Adresse, + Netzanschluss), nur ein paar Woerter brauchen ein scharfes s. Die stehen + deshalb einzeln als Liste und nicht als Muster. + + Kanalnamen sind Absicht: "# waermepumpe-mueller" ist ein Handle, und die + schreiben Chatwerkzeuge klein und ohne Umlaute. */ + const UMLAUT_ERLAUBT = new Set([ + "michael", "dauer", "neue", "steuer", "feuer", "aktuell", "museum", + "waermepumpe-mueller", "waermepumpe-abnahme", + ]); + const BRAUCHT_SCHARFES_S = new Set([ + "aufmass", "strasse", "groesse", "groesser", "fuss", "fussboden", + "mass", "masse", "weiss", "heisst", "aussen", "gross", "grosse", "spass", + ]); + + function umlautFehler(wurzel) { + const raus = []; + wurzel.querySelectorAll("text, .headline, .body, .badge").forEach(e => { + String(e.textContent || "").split(/[^A-Za-zÄÖÜäöüß0-9./#@-]+/).forEach(w => { + if (!w) return; + const k = w.toLowerCase().replace(/^[@#]+/, "").replace(/[.,;:!?)(]+$/, ""); + if (!k || UMLAUT_ERLAUBT.has(k) || raus.includes(w)) return; + if (/ae|oe|ue/.test(k) || BRAUCHT_SCHARFES_S.has(k)) raus.push(w); + }); + }); + return raus; + } + + /* Fuer animation.mjs: das Bewegtbild laeuft nicht durch renderSlide und + braucht deshalb eine eigene Tuer zu derselben Pruefung. */ + window.TEXT_PRUEFUNG = () => umlautFehler(document); + async function renderSlide(i) { // Hilfslinien sind Werkzeug: koennten sie aus einem Tastendruck noch // stehen, landeten sie im Bild. @@ -2279,6 +2325,11 @@ if (location.search.indexOf("nur=streifen") >= 0) el.dataset.editmode = "aus"; try { await document.fonts.ready; + /* Umlaute pruefen, bevor gerendert wird. Lieber ein Abbruch mit + klarer Meldung als ein fertiges PNG mit "Sanitaer" darauf. */ + const uf = umlautFehler(el); + if (uf.length) throw new Error("Slide " + (i + 1) + ": Umlaut fehlt bei " + + uf.join(", ") + ". Wenn das Wort so richtig ist, gehoert es in UMLAUT_ERLAUBT."); const imgs = [...el.querySelectorAll("img")]; await Promise.all(imgs.map(im => im.complete ? im.decode().catch(() => {}) diff --git a/post2-alt.html b/post2-alt.html index e29432b..a7d028d 100644 --- a/post2-alt.html +++ b/post2-alt.html @@ -4216,6 +4216,52 @@ if (location.search.indexOf("nur=anim") >= 0) return n < 20 ? 1 : dunkel / n; } + + /* ─── Umlaute im gezeichneten Text ─────────────────────────────────────── + Auf einer Slide stand einmal "Sanitaer" und "Klima / Lueftung". Beides + kam woertlich aus der Quelle -- im Klickdummy war es dort schludrig + eingetippt --, und beides las sich im fertigen Beitrag wie ein Fehler, + weil es einer ist. Gefunden hat es niemand beim Bauen, sondern erst + jemand, der auf den fertigen Post geschaut hat. + + Deshalb prueft es jetzt der Export. Ein reines Muster genuegt dafuer + nicht: Deutsch schreibt "neue", "Dauer", "Michael" voellig zu Recht mit + ae/oe/ue. Nachgezaehlt ueber den gezeichneten Text aller Projekte sind es + aber nur eine Handvoll solcher Woerter -- eine Ausnahmeliste ist also + kurz und trifft trotzdem alles andere. + + ss ist der umgekehrte Fall: fast immer richtig (dass, Schluss, Adresse, + Netzanschluss), nur ein paar Woerter brauchen ein scharfes s. Die stehen + deshalb einzeln als Liste und nicht als Muster. + + Kanalnamen sind Absicht: "# waermepumpe-mueller" ist ein Handle, und die + schreiben Chatwerkzeuge klein und ohne Umlaute. */ + const UMLAUT_ERLAUBT = new Set([ + "michael", "dauer", "neue", "steuer", "feuer", "aktuell", "museum", + "waermepumpe-mueller", "waermepumpe-abnahme", + ]); + const BRAUCHT_SCHARFES_S = new Set([ + "aufmass", "strasse", "groesse", "groesser", "fuss", "fussboden", + "mass", "masse", "weiss", "heisst", "aussen", "gross", "grosse", "spass", + ]); + + function umlautFehler(wurzel) { + const raus = []; + wurzel.querySelectorAll("text, .headline, .body, .badge").forEach(e => { + String(e.textContent || "").split(/[^A-Za-zÄÖÜäöüß0-9./#@-]+/).forEach(w => { + if (!w) return; + const k = w.toLowerCase().replace(/^[@#]+/, "").replace(/[.,;:!?)(]+$/, ""); + if (!k || UMLAUT_ERLAUBT.has(k) || raus.includes(w)) return; + if (/ae|oe|ue/.test(k) || BRAUCHT_SCHARFES_S.has(k)) raus.push(w); + }); + }); + return raus; + } + + /* Fuer animation.mjs: das Bewegtbild laeuft nicht durch renderSlide und + braucht deshalb eine eigene Tuer zu derselben Pruefung. */ + window.TEXT_PRUEFUNG = () => umlautFehler(document); + async function renderSlide(i) { // Hilfslinien sind Werkzeug: koennten sie aus einem Tastendruck noch // stehen, landeten sie im Bild. @@ -4232,6 +4278,11 @@ if (location.search.indexOf("nur=anim") >= 0) el.dataset.editmode = "aus"; try { await document.fonts.ready; + /* Umlaute pruefen, bevor gerendert wird. Lieber ein Abbruch mit + klarer Meldung als ein fertiges PNG mit "Sanitaer" darauf. */ + const uf = umlautFehler(el); + if (uf.length) throw new Error("Slide " + (i + 1) + ": Umlaut fehlt bei " + + uf.join(", ") + ". Wenn das Wort so richtig ist, gehoert es in UMLAUT_ERLAUBT."); const imgs = [...el.querySelectorAll("img")]; await Promise.all(imgs.map(im => im.complete ? im.decode().catch(() => {}) diff --git a/post2.html b/post2.html index 90d1f5d..6291e18 100644 --- a/post2.html +++ b/post2.html @@ -3837,6 +3837,52 @@ if (location.search.indexOf("nur=anim") >= 0) return n < 20 ? 1 : dunkel / n; } + + /* ─── Umlaute im gezeichneten Text ─────────────────────────────────────── + Auf einer Slide stand einmal "Sanitaer" und "Klima / Lueftung". Beides + kam woertlich aus der Quelle -- im Klickdummy war es dort schludrig + eingetippt --, und beides las sich im fertigen Beitrag wie ein Fehler, + weil es einer ist. Gefunden hat es niemand beim Bauen, sondern erst + jemand, der auf den fertigen Post geschaut hat. + + Deshalb prueft es jetzt der Export. Ein reines Muster genuegt dafuer + nicht: Deutsch schreibt "neue", "Dauer", "Michael" voellig zu Recht mit + ae/oe/ue. Nachgezaehlt ueber den gezeichneten Text aller Projekte sind es + aber nur eine Handvoll solcher Woerter -- eine Ausnahmeliste ist also + kurz und trifft trotzdem alles andere. + + ss ist der umgekehrte Fall: fast immer richtig (dass, Schluss, Adresse, + Netzanschluss), nur ein paar Woerter brauchen ein scharfes s. Die stehen + deshalb einzeln als Liste und nicht als Muster. + + Kanalnamen sind Absicht: "# waermepumpe-mueller" ist ein Handle, und die + schreiben Chatwerkzeuge klein und ohne Umlaute. */ + const UMLAUT_ERLAUBT = new Set([ + "michael", "dauer", "neue", "steuer", "feuer", "aktuell", "museum", + "waermepumpe-mueller", "waermepumpe-abnahme", + ]); + const BRAUCHT_SCHARFES_S = new Set([ + "aufmass", "strasse", "groesse", "groesser", "fuss", "fussboden", + "mass", "masse", "weiss", "heisst", "aussen", "gross", "grosse", "spass", + ]); + + function umlautFehler(wurzel) { + const raus = []; + wurzel.querySelectorAll("text, .headline, .body, .badge").forEach(e => { + String(e.textContent || "").split(/[^A-Za-zÄÖÜäöüß0-9./#@-]+/).forEach(w => { + if (!w) return; + const k = w.toLowerCase().replace(/^[@#]+/, "").replace(/[.,;:!?)(]+$/, ""); + if (!k || UMLAUT_ERLAUBT.has(k) || raus.includes(w)) return; + if (/ae|oe|ue/.test(k) || BRAUCHT_SCHARFES_S.has(k)) raus.push(w); + }); + }); + return raus; + } + + /* Fuer animation.mjs: das Bewegtbild laeuft nicht durch renderSlide und + braucht deshalb eine eigene Tuer zu derselben Pruefung. */ + window.TEXT_PRUEFUNG = () => umlautFehler(document); + async function renderSlide(i) { // Hilfslinien sind Werkzeug: koennten sie aus einem Tastendruck noch // stehen, landeten sie im Bild. @@ -3853,6 +3899,11 @@ if (location.search.indexOf("nur=anim") >= 0) el.dataset.editmode = "aus"; try { await document.fonts.ready; + /* Umlaute pruefen, bevor gerendert wird. Lieber ein Abbruch mit + klarer Meldung als ein fertiges PNG mit "Sanitaer" darauf. */ + const uf = umlautFehler(el); + if (uf.length) throw new Error("Slide " + (i + 1) + ": Umlaut fehlt bei " + + uf.join(", ") + ". Wenn das Wort so richtig ist, gehoert es in UMLAUT_ERLAUBT."); const imgs = [...el.querySelectorAll("img")]; await Promise.all(imgs.map(im => im.complete ? im.decode().catch(() => {}) diff --git a/post3.html b/post3.html index fd13949..d845fd7 100644 --- a/post3.html +++ b/post3.html @@ -3562,6 +3562,52 @@ if (location.search.indexOf("nur=anim") >= 0) return n < 20 ? 1 : dunkel / n; } + + /* ─── Umlaute im gezeichneten Text ─────────────────────────────────────── + Auf einer Slide stand einmal "Sanitaer" und "Klima / Lueftung". Beides + kam woertlich aus der Quelle -- im Klickdummy war es dort schludrig + eingetippt --, und beides las sich im fertigen Beitrag wie ein Fehler, + weil es einer ist. Gefunden hat es niemand beim Bauen, sondern erst + jemand, der auf den fertigen Post geschaut hat. + + Deshalb prueft es jetzt der Export. Ein reines Muster genuegt dafuer + nicht: Deutsch schreibt "neue", "Dauer", "Michael" voellig zu Recht mit + ae/oe/ue. Nachgezaehlt ueber den gezeichneten Text aller Projekte sind es + aber nur eine Handvoll solcher Woerter -- eine Ausnahmeliste ist also + kurz und trifft trotzdem alles andere. + + ss ist der umgekehrte Fall: fast immer richtig (dass, Schluss, Adresse, + Netzanschluss), nur ein paar Woerter brauchen ein scharfes s. Die stehen + deshalb einzeln als Liste und nicht als Muster. + + Kanalnamen sind Absicht: "# waermepumpe-mueller" ist ein Handle, und die + schreiben Chatwerkzeuge klein und ohne Umlaute. */ + const UMLAUT_ERLAUBT = new Set([ + "michael", "dauer", "neue", "steuer", "feuer", "aktuell", "museum", + "waermepumpe-mueller", "waermepumpe-abnahme", + ]); + const BRAUCHT_SCHARFES_S = new Set([ + "aufmass", "strasse", "groesse", "groesser", "fuss", "fussboden", + "mass", "masse", "weiss", "heisst", "aussen", "gross", "grosse", "spass", + ]); + + function umlautFehler(wurzel) { + const raus = []; + wurzel.querySelectorAll("text, .headline, .body, .badge").forEach(e => { + String(e.textContent || "").split(/[^A-Za-zÄÖÜäöüß0-9./#@-]+/).forEach(w => { + if (!w) return; + const k = w.toLowerCase().replace(/^[@#]+/, "").replace(/[.,;:!?)(]+$/, ""); + if (!k || UMLAUT_ERLAUBT.has(k) || raus.includes(w)) return; + if (/ae|oe|ue/.test(k) || BRAUCHT_SCHARFES_S.has(k)) raus.push(w); + }); + }); + return raus; + } + + /* Fuer animation.mjs: das Bewegtbild laeuft nicht durch renderSlide und + braucht deshalb eine eigene Tuer zu derselben Pruefung. */ + window.TEXT_PRUEFUNG = () => umlautFehler(document); + async function renderSlide(i) { // Hilfslinien sind Werkzeug: koennten sie aus einem Tastendruck noch // stehen, landeten sie im Bild. @@ -3578,6 +3624,11 @@ if (location.search.indexOf("nur=anim") >= 0) el.dataset.editmode = "aus"; try { await document.fonts.ready; + /* Umlaute pruefen, bevor gerendert wird. Lieber ein Abbruch mit + klarer Meldung als ein fertiges PNG mit "Sanitaer" darauf. */ + const uf = umlautFehler(el); + if (uf.length) throw new Error("Slide " + (i + 1) + ": Umlaut fehlt bei " + + uf.join(", ") + ". Wenn das Wort so richtig ist, gehoert es in UMLAUT_ERLAUBT."); const imgs = [...el.querySelectorAll("img")]; await Promise.all(imgs.map(im => im.complete ? im.decode().catch(() => {}) diff --git a/post4.html b/post4.html index 5a62710..6710e24 100644 --- a/post4.html +++ b/post4.html @@ -4350,6 +4350,52 @@ if (location.search.indexOf("nur=anim") >= 0) return n < 20 ? 1 : dunkel / n; } + + /* ─── Umlaute im gezeichneten Text ─────────────────────────────────────── + Auf einer Slide stand einmal "Sanitaer" und "Klima / Lueftung". Beides + kam woertlich aus der Quelle -- im Klickdummy war es dort schludrig + eingetippt --, und beides las sich im fertigen Beitrag wie ein Fehler, + weil es einer ist. Gefunden hat es niemand beim Bauen, sondern erst + jemand, der auf den fertigen Post geschaut hat. + + Deshalb prueft es jetzt der Export. Ein reines Muster genuegt dafuer + nicht: Deutsch schreibt "neue", "Dauer", "Michael" voellig zu Recht mit + ae/oe/ue. Nachgezaehlt ueber den gezeichneten Text aller Projekte sind es + aber nur eine Handvoll solcher Woerter -- eine Ausnahmeliste ist also + kurz und trifft trotzdem alles andere. + + ss ist der umgekehrte Fall: fast immer richtig (dass, Schluss, Adresse, + Netzanschluss), nur ein paar Woerter brauchen ein scharfes s. Die stehen + deshalb einzeln als Liste und nicht als Muster. + + Kanalnamen sind Absicht: "# waermepumpe-mueller" ist ein Handle, und die + schreiben Chatwerkzeuge klein und ohne Umlaute. */ + const UMLAUT_ERLAUBT = new Set([ + "michael", "dauer", "neue", "steuer", "feuer", "aktuell", "museum", + "waermepumpe-mueller", "waermepumpe-abnahme", + ]); + const BRAUCHT_SCHARFES_S = new Set([ + "aufmass", "strasse", "groesse", "groesser", "fuss", "fussboden", + "mass", "masse", "weiss", "heisst", "aussen", "gross", "grosse", "spass", + ]); + + function umlautFehler(wurzel) { + const raus = []; + wurzel.querySelectorAll("text, .headline, .body, .badge").forEach(e => { + String(e.textContent || "").split(/[^A-Za-zÄÖÜäöüß0-9./#@-]+/).forEach(w => { + if (!w) return; + const k = w.toLowerCase().replace(/^[@#]+/, "").replace(/[.,;:!?)(]+$/, ""); + if (!k || UMLAUT_ERLAUBT.has(k) || raus.includes(w)) return; + if (/ae|oe|ue/.test(k) || BRAUCHT_SCHARFES_S.has(k)) raus.push(w); + }); + }); + return raus; + } + + /* Fuer animation.mjs: das Bewegtbild laeuft nicht durch renderSlide und + braucht deshalb eine eigene Tuer zu derselben Pruefung. */ + window.TEXT_PRUEFUNG = () => umlautFehler(document); + async function renderSlide(i) { // Hilfslinien sind Werkzeug: koennten sie aus einem Tastendruck noch // stehen, landeten sie im Bild. @@ -4366,6 +4412,11 @@ if (location.search.indexOf("nur=anim") >= 0) el.dataset.editmode = "aus"; try { await document.fonts.ready; + /* Umlaute pruefen, bevor gerendert wird. Lieber ein Abbruch mit + klarer Meldung als ein fertiges PNG mit "Sanitaer" darauf. */ + const uf = umlautFehler(el); + if (uf.length) throw new Error("Slide " + (i + 1) + ": Umlaut fehlt bei " + + uf.join(", ") + ". Wenn das Wort so richtig ist, gehoert es in UMLAUT_ERLAUBT."); const imgs = [...el.querySelectorAll("img")]; await Promise.all(imgs.map(im => im.complete ? im.decode().catch(() => {}) diff --git a/post5.html b/post5.html index 1669db0..d7894b0 100644 --- a/post5.html +++ b/post5.html @@ -4592,6 +4592,52 @@ if (location.search.indexOf("nur=anim") >= 0) return n < 20 ? 1 : dunkel / n; } + + /* ─── Umlaute im gezeichneten Text ─────────────────────────────────────── + Auf einer Slide stand einmal "Sanitaer" und "Klima / Lueftung". Beides + kam woertlich aus der Quelle -- im Klickdummy war es dort schludrig + eingetippt --, und beides las sich im fertigen Beitrag wie ein Fehler, + weil es einer ist. Gefunden hat es niemand beim Bauen, sondern erst + jemand, der auf den fertigen Post geschaut hat. + + Deshalb prueft es jetzt der Export. Ein reines Muster genuegt dafuer + nicht: Deutsch schreibt "neue", "Dauer", "Michael" voellig zu Recht mit + ae/oe/ue. Nachgezaehlt ueber den gezeichneten Text aller Projekte sind es + aber nur eine Handvoll solcher Woerter -- eine Ausnahmeliste ist also + kurz und trifft trotzdem alles andere. + + ss ist der umgekehrte Fall: fast immer richtig (dass, Schluss, Adresse, + Netzanschluss), nur ein paar Woerter brauchen ein scharfes s. Die stehen + deshalb einzeln als Liste und nicht als Muster. + + Kanalnamen sind Absicht: "# waermepumpe-mueller" ist ein Handle, und die + schreiben Chatwerkzeuge klein und ohne Umlaute. */ + const UMLAUT_ERLAUBT = new Set([ + "michael", "dauer", "neue", "steuer", "feuer", "aktuell", "museum", + "waermepumpe-mueller", "waermepumpe-abnahme", + ]); + const BRAUCHT_SCHARFES_S = new Set([ + "aufmass", "strasse", "groesse", "groesser", "fuss", "fussboden", + "mass", "masse", "weiss", "heisst", "aussen", "gross", "grosse", "spass", + ]); + + function umlautFehler(wurzel) { + const raus = []; + wurzel.querySelectorAll("text, .headline, .body, .badge").forEach(e => { + String(e.textContent || "").split(/[^A-Za-zÄÖÜäöüß0-9./#@-]+/).forEach(w => { + if (!w) return; + const k = w.toLowerCase().replace(/^[@#]+/, "").replace(/[.,;:!?)(]+$/, ""); + if (!k || UMLAUT_ERLAUBT.has(k) || raus.includes(w)) return; + if (/ae|oe|ue/.test(k) || BRAUCHT_SCHARFES_S.has(k)) raus.push(w); + }); + }); + return raus; + } + + /* Fuer animation.mjs: das Bewegtbild laeuft nicht durch renderSlide und + braucht deshalb eine eigene Tuer zu derselben Pruefung. */ + window.TEXT_PRUEFUNG = () => umlautFehler(document); + async function renderSlide(i) { // Hilfslinien sind Werkzeug: koennten sie aus einem Tastendruck noch // stehen, landeten sie im Bild. @@ -4608,6 +4654,11 @@ if (location.search.indexOf("nur=anim") >= 0) el.dataset.editmode = "aus"; try { await document.fonts.ready; + /* Umlaute pruefen, bevor gerendert wird. Lieber ein Abbruch mit + klarer Meldung als ein fertiges PNG mit "Sanitaer" darauf. */ + const uf = umlautFehler(el); + if (uf.length) throw new Error("Slide " + (i + 1) + ": Umlaut fehlt bei " + + uf.join(", ") + ". Wenn das Wort so richtig ist, gehoert es in UMLAUT_ERLAUBT."); const imgs = [...el.querySelectorAll("img")]; await Promise.all(imgs.map(im => im.complete ? im.decode().catch(() => {}) diff --git a/post6.html b/post6.html index e1580e0..bf4c413 100644 --- a/post6.html +++ b/post6.html @@ -5529,6 +5529,52 @@ if (location.search.indexOf("nur=anim") >= 0) return n < 20 ? 1 : dunkel / n; } + + /* ─── Umlaute im gezeichneten Text ─────────────────────────────────────── + Auf einer Slide stand einmal "Sanitaer" und "Klima / Lueftung". Beides + kam woertlich aus der Quelle -- im Klickdummy war es dort schludrig + eingetippt --, und beides las sich im fertigen Beitrag wie ein Fehler, + weil es einer ist. Gefunden hat es niemand beim Bauen, sondern erst + jemand, der auf den fertigen Post geschaut hat. + + Deshalb prueft es jetzt der Export. Ein reines Muster genuegt dafuer + nicht: Deutsch schreibt "neue", "Dauer", "Michael" voellig zu Recht mit + ae/oe/ue. Nachgezaehlt ueber den gezeichneten Text aller Projekte sind es + aber nur eine Handvoll solcher Woerter -- eine Ausnahmeliste ist also + kurz und trifft trotzdem alles andere. + + ss ist der umgekehrte Fall: fast immer richtig (dass, Schluss, Adresse, + Netzanschluss), nur ein paar Woerter brauchen ein scharfes s. Die stehen + deshalb einzeln als Liste und nicht als Muster. + + Kanalnamen sind Absicht: "# waermepumpe-mueller" ist ein Handle, und die + schreiben Chatwerkzeuge klein und ohne Umlaute. */ + const UMLAUT_ERLAUBT = new Set([ + "michael", "dauer", "neue", "steuer", "feuer", "aktuell", "museum", + "waermepumpe-mueller", "waermepumpe-abnahme", + ]); + const BRAUCHT_SCHARFES_S = new Set([ + "aufmass", "strasse", "groesse", "groesser", "fuss", "fussboden", + "mass", "masse", "weiss", "heisst", "aussen", "gross", "grosse", "spass", + ]); + + function umlautFehler(wurzel) { + const raus = []; + wurzel.querySelectorAll("text, .headline, .body, .badge").forEach(e => { + String(e.textContent || "").split(/[^A-Za-zÄÖÜäöüß0-9./#@-]+/).forEach(w => { + if (!w) return; + const k = w.toLowerCase().replace(/^[@#]+/, "").replace(/[.,;:!?)(]+$/, ""); + if (!k || UMLAUT_ERLAUBT.has(k) || raus.includes(w)) return; + if (/ae|oe|ue/.test(k) || BRAUCHT_SCHARFES_S.has(k)) raus.push(w); + }); + }); + return raus; + } + + /* Fuer animation.mjs: das Bewegtbild laeuft nicht durch renderSlide und + braucht deshalb eine eigene Tuer zu derselben Pruefung. */ + window.TEXT_PRUEFUNG = () => umlautFehler(document); + async function renderSlide(i) { // Hilfslinien sind Werkzeug: koennten sie aus einem Tastendruck noch // stehen, landeten sie im Bild. @@ -5545,6 +5591,11 @@ if (location.search.indexOf("nur=anim") >= 0) el.dataset.editmode = "aus"; try { await document.fonts.ready; + /* Umlaute pruefen, bevor gerendert wird. Lieber ein Abbruch mit + klarer Meldung als ein fertiges PNG mit "Sanitaer" darauf. */ + const uf = umlautFehler(el); + if (uf.length) throw new Error("Slide " + (i + 1) + ": Umlaut fehlt bei " + + uf.join(", ") + ". Wenn das Wort so richtig ist, gehoert es in UMLAUT_ERLAUBT."); const imgs = [...el.querySelectorAll("img")]; await Promise.all(imgs.map(im => im.complete ? im.decode().catch(() => {}) diff --git a/rules.md b/rules.md index 92f052b..a9d7e91 100644 --- a/rules.md +++ b/rules.md @@ -347,6 +347,35 @@ schon zweimal zu viel. - **Keine Em-Dashes (—)** in sichtbaren Texten. Komma, Punkt oder `·` - Feature-Texte wortgleich von der Website. Headlines dürfen gekürzt und umgestellt werden, aber **keine neuen Wörter erfinden** +- **Umlaute sind Umlaute.** Kein `Sanitaer`, kein `Aufmass`. Das gilt auch + dann, wenn die Quelle es so schreibt: eine ASCII-Ersatzschreibung im + Klickdummy ist ein Tippfehler und kein Produktbegriff, den man zitiert + +#### Der Export prüft das + +Aufgefallen ist es an „Sanitaer“ und „Klima / Lueftung“ auf einer fertigen +Slide — beim Bauen hatte es niemand gesehen, weil beides wörtlich aus der +Quelle kam. Seitdem prüft es die Maschine, an zwei Stellen: + +| Weg | Wo | +|---|---| +| Bildexport | `renderSlide()` bricht ab, bevor ein PNG entsteht | +| Bewegtbild | `animation.mjs` prüft an 24 Stellen über den Ablauf | + +**Ein reines Muster genügt dafür nicht.** Deutsch schreibt „neue“, „Dauer“ und +„Michael“ völlig zu Recht mit `ae`/`oe`/`ue`. Nachgezählt über den gezeichneten +Text aller Projekte sind es aber nur eine Handvoll solcher Wörter — deshalb +Muster **plus** Ausnahmeliste `UMLAUT_ERLAUBT`. Bei `ss` ist es umgekehrt: +fast immer richtig (dass, Schluss, Netzanschluss), nur wenige Wörter brauchen +ein scharfes s. Die stehen einzeln in `BRAUCHT_SCHARFES_S`. + +Schlägt die Prüfung bei einem Wort an, das so richtig ist, gehört es in die +Ausnahmeliste — nicht die Prüfung abgeschaltet. + +> **Beim Bewegtbild reicht ein Blick auf das erste Bild nicht.** Der erste +> Anlauf prüfte nur den Anfangszustand und fand nichts: die fehlerhaften +> Wörter erscheinen dort erst ab `t = 0,4`. Der Text einer Animation ändert +> sich mit der Zeit, die Prüfung muss es auch. --- @@ -873,6 +902,7 @@ etwas ins Statusfeld schreibt. **Nicht entfernen.** | Farbe „stimmt nicht" | Deckkraft der Ebene lag darüber. Eine Farbe ist nur exakt, wenn nichts sie multipliziert | | Muster wirkt zufällig hingeworfen | Formen liefen quer durch den Text. Dekoration bleibt in den Rändern, verankert und angeschnitten | | Nichts lädt, Bühne leer | Konstante vor ihrer Deklaration benutzt (TDZ) | +| „Sanitaer“ auf dem fertigen Beitrag | Wörtlich aus der Quelle übernommen, die es selbst falsch schreibt. §4 | ---