diff --git a/animation.mjs b/animation.mjs index 7b30790..09bd219 100644 --- a/animation.mjs +++ b/animation.mjs @@ -177,8 +177,9 @@ try { (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."); + throw new Error(`${a.key}: ${[...gesehen].join(", ")}. ` + + "Fehlt ein Umlaut, schreib ihn; ist das Wort so richtig, gehoert es in " + + "UMLAUT_ERLAUBT. Einen Geviertstrich ersetzt ein Punkt oder ein Komma."); const ordner = await mkdtemp(path.join(tmpdir(), "postgrid-bilder-")); process.stdout.write(` ${a.key}: ${anzahl} Bilder `); diff --git a/post1.html b/post1.html index 514445f..ffc4f6e 100644 --- a/post1.html +++ b/post1.html @@ -804,6 +804,8 @@ if (location.search.indexOf("nur=streifen") >= 0) + +

@@ -2284,8 +2286,17 @@ if (location.search.indexOf("nur=streifen") >= 0) Kanalnamen sind Absicht: "# waermepumpe-mueller" ist ein Handle, und die schreiben Chatwerkzeuge klein und ohne Umlaute. */ + /* Woerter, in denen ae/oe/ue kein verkruepppelter Umlaut ist, sondern zwei + Laute an einer Silbengrenze. Die Eintraege wirken als Wortanfang. + + Die Liste ist kurz geworden, weil die Regel darunter den groessten Teil + der Ausnahmen von selbst erledigt: ein ersatzweise geschriebener Umlaut + steht nie hinter einem Vokal. Vorher standen hier dauer, neue, steuer, + feuer, bauer -- alle nach demselben Muster, und die Liste waere mit + jedem Beitrag weitergewachsen. Was bleibt, sind die echten Sonderfaelle: + "Michael" (ae hinter h), "aktuell" (ue hinter t). */ const UMLAUT_ERLAUBT = new Set([ - "michael", "dauer", "neue", "steuer", "feuer", "aktuell", "museum", + "michael", "aktuell", "museum", "waermepumpe-mueller", "waermepumpe-abnahme", ]); const BRAUCHT_SCHARFES_S = new Set([ @@ -2296,11 +2307,42 @@ if (location.search.indexOf("nur=streifen") >= 0) function umlautFehler(wurzel) { const raus = []; wurzel.querySelectorAll("text, .headline, .body, .badge").forEach(e => { - String(e.textContent || "").split(/[^A-Za-zÄÖÜäöüß0-9./#@-]+/).forEach(w => { + /* Nicht textContent, sondern die Textknoten mit Leerzeichen dazwischen. + Eine Ueberschrift ist "Formulare selbst bauen.
Per + Drag-and-drop." -- textContent klebt daraus "bauen.Per" + zusammen, ein Wort, das es nicht gibt. Ein Umbruch und eine + Elementgrenze sind Wortgrenzen. */ + const stuecke = []; + const lauf = document.createTreeWalker(e, NodeFilter.SHOW_TEXT); + for (let k = lauf.nextNode(); k; k = lauf.nextNode()) stuecke.push(k.nodeValue); + const ganz = stuecke.join(" "); + /* Geviertstriche gehoeren nicht in unsere Texte. Der Halbgeviertstrich + als Gedankenstrich ist richtiges Deutsch und bleibt erlaubt; der + lange Strich ist eine englische Angewohnheit und liest sich auf einer + deutschen Slide fremd. Er kam nicht aus einer Quelle, sondern beim + Schreiben mit hinein. */ + if (ganz.indexOf("\u2014") >= 0) { + const stelle = "Geviertstrich in „" + ganz.trim().slice(0, 40) + "“"; + if (!raus.includes(stelle)) raus.push(stelle); + } + ganz.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); + if (!k || raus.includes(w)) return; + /* Mailadressen und Domains sind ausgenommen. Dort ist die + umlautfreie Schreibung keine Schludrigkeit, sondern Pflicht: + "buero@muster-shk.de" kann gar kein ue ersetzen. Ohne diese + Ausnahme meldete Post 8 drei Adressen als Fehler. */ + if (/@/.test(k) || /\.(de|com|net|org|eu|at|ch|io)$/.test(k)) return; + if ([...UMLAUT_ERLAUBT].some(a => k.startsWith(a))) return; + /* ae/oe/ue nur dann als verunglueckter Umlaut, wenn kein Vokal + davorsteht. Ein ae, oe oder ue, das fuer ae, oe oder ue steht, + folgt immer einem Konsonanten oder steht am Wortanfang: "fuer", + "ueber", "gruen", "Sanitaer", "Lueftung". Hinter einem Vokal sind + es dagegen immer zwei eigene Laute: bauen, Bauer, neue, Dauer, + Steuer, Feuer, Mauer, genauer. Die Regel ersetzt sechs Eintraege + in UMLAUT_ERLAUBT und alle, die dort noch gelandet waeren. */ + if (/(^|[^aeiou])(ae|oe|ue)/.test(k) || BRAUCHT_SCHARFES_S.has(k)) raus.push(w); }); }); return raus; @@ -2326,11 +2368,12 @@ 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 + /* Den Text 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."); + if (uf.length) throw new Error("Slide " + (i + 1) + ": " + uf.join(", ") + + ". Fehlt ein Umlaut, schreib ihn; ist das Wort so richtig, gehoert es " + + "in UMLAUT_ERLAUBT. Einen Geviertstrich ersetzt ein Punkt oder ein Komma."); 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 a3d84b1..1d0a6b2 100644 --- a/post2-alt.html +++ b/post2-alt.html @@ -1107,6 +1107,8 @@ if (location.search.indexOf("nur=anim") >= 0) + +

@@ -4237,8 +4239,17 @@ if (location.search.indexOf("nur=anim") >= 0) Kanalnamen sind Absicht: "# waermepumpe-mueller" ist ein Handle, und die schreiben Chatwerkzeuge klein und ohne Umlaute. */ + /* Woerter, in denen ae/oe/ue kein verkruepppelter Umlaut ist, sondern zwei + Laute an einer Silbengrenze. Die Eintraege wirken als Wortanfang. + + Die Liste ist kurz geworden, weil die Regel darunter den groessten Teil + der Ausnahmen von selbst erledigt: ein ersatzweise geschriebener Umlaut + steht nie hinter einem Vokal. Vorher standen hier dauer, neue, steuer, + feuer, bauer -- alle nach demselben Muster, und die Liste waere mit + jedem Beitrag weitergewachsen. Was bleibt, sind die echten Sonderfaelle: + "Michael" (ae hinter h), "aktuell" (ue hinter t). */ const UMLAUT_ERLAUBT = new Set([ - "michael", "dauer", "neue", "steuer", "feuer", "aktuell", "museum", + "michael", "aktuell", "museum", "waermepumpe-mueller", "waermepumpe-abnahme", ]); const BRAUCHT_SCHARFES_S = new Set([ @@ -4249,11 +4260,42 @@ if (location.search.indexOf("nur=anim") >= 0) function umlautFehler(wurzel) { const raus = []; wurzel.querySelectorAll("text, .headline, .body, .badge").forEach(e => { - String(e.textContent || "").split(/[^A-Za-zÄÖÜäöüß0-9./#@-]+/).forEach(w => { + /* Nicht textContent, sondern die Textknoten mit Leerzeichen dazwischen. + Eine Ueberschrift ist "Formulare selbst bauen.
Per + Drag-and-drop." -- textContent klebt daraus "bauen.Per" + zusammen, ein Wort, das es nicht gibt. Ein Umbruch und eine + Elementgrenze sind Wortgrenzen. */ + const stuecke = []; + const lauf = document.createTreeWalker(e, NodeFilter.SHOW_TEXT); + for (let k = lauf.nextNode(); k; k = lauf.nextNode()) stuecke.push(k.nodeValue); + const ganz = stuecke.join(" "); + /* Geviertstriche gehoeren nicht in unsere Texte. Der Halbgeviertstrich + als Gedankenstrich ist richtiges Deutsch und bleibt erlaubt; der + lange Strich ist eine englische Angewohnheit und liest sich auf einer + deutschen Slide fremd. Er kam nicht aus einer Quelle, sondern beim + Schreiben mit hinein. */ + if (ganz.indexOf("\u2014") >= 0) { + const stelle = "Geviertstrich in „" + ganz.trim().slice(0, 40) + "“"; + if (!raus.includes(stelle)) raus.push(stelle); + } + ganz.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); + if (!k || raus.includes(w)) return; + /* Mailadressen und Domains sind ausgenommen. Dort ist die + umlautfreie Schreibung keine Schludrigkeit, sondern Pflicht: + "buero@muster-shk.de" kann gar kein ue ersetzen. Ohne diese + Ausnahme meldete Post 8 drei Adressen als Fehler. */ + if (/@/.test(k) || /\.(de|com|net|org|eu|at|ch|io)$/.test(k)) return; + if ([...UMLAUT_ERLAUBT].some(a => k.startsWith(a))) return; + /* ae/oe/ue nur dann als verunglueckter Umlaut, wenn kein Vokal + davorsteht. Ein ae, oe oder ue, das fuer ae, oe oder ue steht, + folgt immer einem Konsonanten oder steht am Wortanfang: "fuer", + "ueber", "gruen", "Sanitaer", "Lueftung". Hinter einem Vokal sind + es dagegen immer zwei eigene Laute: bauen, Bauer, neue, Dauer, + Steuer, Feuer, Mauer, genauer. Die Regel ersetzt sechs Eintraege + in UMLAUT_ERLAUBT und alle, die dort noch gelandet waeren. */ + if (/(^|[^aeiou])(ae|oe|ue)/.test(k) || BRAUCHT_SCHARFES_S.has(k)) raus.push(w); }); }); return raus; @@ -4279,11 +4321,12 @@ 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 + /* Den Text 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."); + if (uf.length) throw new Error("Slide " + (i + 1) + ": " + uf.join(", ") + + ". Fehlt ein Umlaut, schreib ihn; ist das Wort so richtig, gehoert es " + + "in UMLAUT_ERLAUBT. Einen Geviertstrich ersetzt ein Punkt oder ein Komma."); 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 7543311..9d25ae4 100644 --- a/post2.html +++ b/post2.html @@ -1000,6 +1000,8 @@ if (location.search.indexOf("nur=anim") >= 0) + +

@@ -3858,8 +3860,17 @@ if (location.search.indexOf("nur=anim") >= 0) Kanalnamen sind Absicht: "# waermepumpe-mueller" ist ein Handle, und die schreiben Chatwerkzeuge klein und ohne Umlaute. */ + /* Woerter, in denen ae/oe/ue kein verkruepppelter Umlaut ist, sondern zwei + Laute an einer Silbengrenze. Die Eintraege wirken als Wortanfang. + + Die Liste ist kurz geworden, weil die Regel darunter den groessten Teil + der Ausnahmen von selbst erledigt: ein ersatzweise geschriebener Umlaut + steht nie hinter einem Vokal. Vorher standen hier dauer, neue, steuer, + feuer, bauer -- alle nach demselben Muster, und die Liste waere mit + jedem Beitrag weitergewachsen. Was bleibt, sind die echten Sonderfaelle: + "Michael" (ae hinter h), "aktuell" (ue hinter t). */ const UMLAUT_ERLAUBT = new Set([ - "michael", "dauer", "neue", "steuer", "feuer", "aktuell", "museum", + "michael", "aktuell", "museum", "waermepumpe-mueller", "waermepumpe-abnahme", ]); const BRAUCHT_SCHARFES_S = new Set([ @@ -3870,11 +3881,42 @@ if (location.search.indexOf("nur=anim") >= 0) function umlautFehler(wurzel) { const raus = []; wurzel.querySelectorAll("text, .headline, .body, .badge").forEach(e => { - String(e.textContent || "").split(/[^A-Za-zÄÖÜäöüß0-9./#@-]+/).forEach(w => { + /* Nicht textContent, sondern die Textknoten mit Leerzeichen dazwischen. + Eine Ueberschrift ist "Formulare selbst bauen.
Per + Drag-and-drop." -- textContent klebt daraus "bauen.Per" + zusammen, ein Wort, das es nicht gibt. Ein Umbruch und eine + Elementgrenze sind Wortgrenzen. */ + const stuecke = []; + const lauf = document.createTreeWalker(e, NodeFilter.SHOW_TEXT); + for (let k = lauf.nextNode(); k; k = lauf.nextNode()) stuecke.push(k.nodeValue); + const ganz = stuecke.join(" "); + /* Geviertstriche gehoeren nicht in unsere Texte. Der Halbgeviertstrich + als Gedankenstrich ist richtiges Deutsch und bleibt erlaubt; der + lange Strich ist eine englische Angewohnheit und liest sich auf einer + deutschen Slide fremd. Er kam nicht aus einer Quelle, sondern beim + Schreiben mit hinein. */ + if (ganz.indexOf("\u2014") >= 0) { + const stelle = "Geviertstrich in „" + ganz.trim().slice(0, 40) + "“"; + if (!raus.includes(stelle)) raus.push(stelle); + } + ganz.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); + if (!k || raus.includes(w)) return; + /* Mailadressen und Domains sind ausgenommen. Dort ist die + umlautfreie Schreibung keine Schludrigkeit, sondern Pflicht: + "buero@muster-shk.de" kann gar kein ue ersetzen. Ohne diese + Ausnahme meldete Post 8 drei Adressen als Fehler. */ + if (/@/.test(k) || /\.(de|com|net|org|eu|at|ch|io)$/.test(k)) return; + if ([...UMLAUT_ERLAUBT].some(a => k.startsWith(a))) return; + /* ae/oe/ue nur dann als verunglueckter Umlaut, wenn kein Vokal + davorsteht. Ein ae, oe oder ue, das fuer ae, oe oder ue steht, + folgt immer einem Konsonanten oder steht am Wortanfang: "fuer", + "ueber", "gruen", "Sanitaer", "Lueftung". Hinter einem Vokal sind + es dagegen immer zwei eigene Laute: bauen, Bauer, neue, Dauer, + Steuer, Feuer, Mauer, genauer. Die Regel ersetzt sechs Eintraege + in UMLAUT_ERLAUBT und alle, die dort noch gelandet waeren. */ + if (/(^|[^aeiou])(ae|oe|ue)/.test(k) || BRAUCHT_SCHARFES_S.has(k)) raus.push(w); }); }); return raus; @@ -3900,11 +3942,12 @@ 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 + /* Den Text 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."); + if (uf.length) throw new Error("Slide " + (i + 1) + ": " + uf.join(", ") + + ". Fehlt ein Umlaut, schreib ihn; ist das Wort so richtig, gehoert es " + + "in UMLAUT_ERLAUBT. Einen Geviertstrich ersetzt ein Punkt oder ein Komma."); 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 d15dd7a..3a874e9 100644 --- a/post3.html +++ b/post3.html @@ -1020,6 +1020,8 @@ if (location.search.indexOf("nur=anim") >= 0) + +

@@ -3583,8 +3585,17 @@ if (location.search.indexOf("nur=anim") >= 0) Kanalnamen sind Absicht: "# waermepumpe-mueller" ist ein Handle, und die schreiben Chatwerkzeuge klein und ohne Umlaute. */ + /* Woerter, in denen ae/oe/ue kein verkruepppelter Umlaut ist, sondern zwei + Laute an einer Silbengrenze. Die Eintraege wirken als Wortanfang. + + Die Liste ist kurz geworden, weil die Regel darunter den groessten Teil + der Ausnahmen von selbst erledigt: ein ersatzweise geschriebener Umlaut + steht nie hinter einem Vokal. Vorher standen hier dauer, neue, steuer, + feuer, bauer -- alle nach demselben Muster, und die Liste waere mit + jedem Beitrag weitergewachsen. Was bleibt, sind die echten Sonderfaelle: + "Michael" (ae hinter h), "aktuell" (ue hinter t). */ const UMLAUT_ERLAUBT = new Set([ - "michael", "dauer", "neue", "steuer", "feuer", "aktuell", "museum", + "michael", "aktuell", "museum", "waermepumpe-mueller", "waermepumpe-abnahme", ]); const BRAUCHT_SCHARFES_S = new Set([ @@ -3595,11 +3606,42 @@ if (location.search.indexOf("nur=anim") >= 0) function umlautFehler(wurzel) { const raus = []; wurzel.querySelectorAll("text, .headline, .body, .badge").forEach(e => { - String(e.textContent || "").split(/[^A-Za-zÄÖÜäöüß0-9./#@-]+/).forEach(w => { + /* Nicht textContent, sondern die Textknoten mit Leerzeichen dazwischen. + Eine Ueberschrift ist "Formulare selbst bauen.
Per + Drag-and-drop." -- textContent klebt daraus "bauen.Per" + zusammen, ein Wort, das es nicht gibt. Ein Umbruch und eine + Elementgrenze sind Wortgrenzen. */ + const stuecke = []; + const lauf = document.createTreeWalker(e, NodeFilter.SHOW_TEXT); + for (let k = lauf.nextNode(); k; k = lauf.nextNode()) stuecke.push(k.nodeValue); + const ganz = stuecke.join(" "); + /* Geviertstriche gehoeren nicht in unsere Texte. Der Halbgeviertstrich + als Gedankenstrich ist richtiges Deutsch und bleibt erlaubt; der + lange Strich ist eine englische Angewohnheit und liest sich auf einer + deutschen Slide fremd. Er kam nicht aus einer Quelle, sondern beim + Schreiben mit hinein. */ + if (ganz.indexOf("\u2014") >= 0) { + const stelle = "Geviertstrich in „" + ganz.trim().slice(0, 40) + "“"; + if (!raus.includes(stelle)) raus.push(stelle); + } + ganz.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); + if (!k || raus.includes(w)) return; + /* Mailadressen und Domains sind ausgenommen. Dort ist die + umlautfreie Schreibung keine Schludrigkeit, sondern Pflicht: + "buero@muster-shk.de" kann gar kein ue ersetzen. Ohne diese + Ausnahme meldete Post 8 drei Adressen als Fehler. */ + if (/@/.test(k) || /\.(de|com|net|org|eu|at|ch|io)$/.test(k)) return; + if ([...UMLAUT_ERLAUBT].some(a => k.startsWith(a))) return; + /* ae/oe/ue nur dann als verunglueckter Umlaut, wenn kein Vokal + davorsteht. Ein ae, oe oder ue, das fuer ae, oe oder ue steht, + folgt immer einem Konsonanten oder steht am Wortanfang: "fuer", + "ueber", "gruen", "Sanitaer", "Lueftung". Hinter einem Vokal sind + es dagegen immer zwei eigene Laute: bauen, Bauer, neue, Dauer, + Steuer, Feuer, Mauer, genauer. Die Regel ersetzt sechs Eintraege + in UMLAUT_ERLAUBT und alle, die dort noch gelandet waeren. */ + if (/(^|[^aeiou])(ae|oe|ue)/.test(k) || BRAUCHT_SCHARFES_S.has(k)) raus.push(w); }); }); return raus; @@ -3625,11 +3667,12 @@ 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 + /* Den Text 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."); + if (uf.length) throw new Error("Slide " + (i + 1) + ": " + uf.join(", ") + + ". Fehlt ein Umlaut, schreib ihn; ist das Wort so richtig, gehoert es " + + "in UMLAUT_ERLAUBT. Einen Geviertstrich ersetzt ein Punkt oder ein Komma."); 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 798682e..94306bb 100644 --- a/post4.html +++ b/post4.html @@ -1048,6 +1048,8 @@ if (location.search.indexOf("nur=anim") >= 0) + +

@@ -4371,8 +4373,17 @@ if (location.search.indexOf("nur=anim") >= 0) Kanalnamen sind Absicht: "# waermepumpe-mueller" ist ein Handle, und die schreiben Chatwerkzeuge klein und ohne Umlaute. */ + /* Woerter, in denen ae/oe/ue kein verkruepppelter Umlaut ist, sondern zwei + Laute an einer Silbengrenze. Die Eintraege wirken als Wortanfang. + + Die Liste ist kurz geworden, weil die Regel darunter den groessten Teil + der Ausnahmen von selbst erledigt: ein ersatzweise geschriebener Umlaut + steht nie hinter einem Vokal. Vorher standen hier dauer, neue, steuer, + feuer, bauer -- alle nach demselben Muster, und die Liste waere mit + jedem Beitrag weitergewachsen. Was bleibt, sind die echten Sonderfaelle: + "Michael" (ae hinter h), "aktuell" (ue hinter t). */ const UMLAUT_ERLAUBT = new Set([ - "michael", "dauer", "neue", "steuer", "feuer", "aktuell", "museum", + "michael", "aktuell", "museum", "waermepumpe-mueller", "waermepumpe-abnahme", ]); const BRAUCHT_SCHARFES_S = new Set([ @@ -4383,11 +4394,42 @@ if (location.search.indexOf("nur=anim") >= 0) function umlautFehler(wurzel) { const raus = []; wurzel.querySelectorAll("text, .headline, .body, .badge").forEach(e => { - String(e.textContent || "").split(/[^A-Za-zÄÖÜäöüß0-9./#@-]+/).forEach(w => { + /* Nicht textContent, sondern die Textknoten mit Leerzeichen dazwischen. + Eine Ueberschrift ist "Formulare selbst bauen.
Per + Drag-and-drop." -- textContent klebt daraus "bauen.Per" + zusammen, ein Wort, das es nicht gibt. Ein Umbruch und eine + Elementgrenze sind Wortgrenzen. */ + const stuecke = []; + const lauf = document.createTreeWalker(e, NodeFilter.SHOW_TEXT); + for (let k = lauf.nextNode(); k; k = lauf.nextNode()) stuecke.push(k.nodeValue); + const ganz = stuecke.join(" "); + /* Geviertstriche gehoeren nicht in unsere Texte. Der Halbgeviertstrich + als Gedankenstrich ist richtiges Deutsch und bleibt erlaubt; der + lange Strich ist eine englische Angewohnheit und liest sich auf einer + deutschen Slide fremd. Er kam nicht aus einer Quelle, sondern beim + Schreiben mit hinein. */ + if (ganz.indexOf("\u2014") >= 0) { + const stelle = "Geviertstrich in „" + ganz.trim().slice(0, 40) + "“"; + if (!raus.includes(stelle)) raus.push(stelle); + } + ganz.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); + if (!k || raus.includes(w)) return; + /* Mailadressen und Domains sind ausgenommen. Dort ist die + umlautfreie Schreibung keine Schludrigkeit, sondern Pflicht: + "buero@muster-shk.de" kann gar kein ue ersetzen. Ohne diese + Ausnahme meldete Post 8 drei Adressen als Fehler. */ + if (/@/.test(k) || /\.(de|com|net|org|eu|at|ch|io)$/.test(k)) return; + if ([...UMLAUT_ERLAUBT].some(a => k.startsWith(a))) return; + /* ae/oe/ue nur dann als verunglueckter Umlaut, wenn kein Vokal + davorsteht. Ein ae, oe oder ue, das fuer ae, oe oder ue steht, + folgt immer einem Konsonanten oder steht am Wortanfang: "fuer", + "ueber", "gruen", "Sanitaer", "Lueftung". Hinter einem Vokal sind + es dagegen immer zwei eigene Laute: bauen, Bauer, neue, Dauer, + Steuer, Feuer, Mauer, genauer. Die Regel ersetzt sechs Eintraege + in UMLAUT_ERLAUBT und alle, die dort noch gelandet waeren. */ + if (/(^|[^aeiou])(ae|oe|ue)/.test(k) || BRAUCHT_SCHARFES_S.has(k)) raus.push(w); }); }); return raus; @@ -4413,11 +4455,12 @@ 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 + /* Den Text 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."); + if (uf.length) throw new Error("Slide " + (i + 1) + ": " + uf.join(", ") + + ". Fehlt ein Umlaut, schreib ihn; ist das Wort so richtig, gehoert es " + + "in UMLAUT_ERLAUBT. Einen Geviertstrich ersetzt ein Punkt oder ein Komma."); 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 d4f98a1..a31c95e 100644 --- a/post5.html +++ b/post5.html @@ -1048,6 +1048,8 @@ if (location.search.indexOf("nur=anim") >= 0) + +

@@ -4613,8 +4615,17 @@ if (location.search.indexOf("nur=anim") >= 0) Kanalnamen sind Absicht: "# waermepumpe-mueller" ist ein Handle, und die schreiben Chatwerkzeuge klein und ohne Umlaute. */ + /* Woerter, in denen ae/oe/ue kein verkruepppelter Umlaut ist, sondern zwei + Laute an einer Silbengrenze. Die Eintraege wirken als Wortanfang. + + Die Liste ist kurz geworden, weil die Regel darunter den groessten Teil + der Ausnahmen von selbst erledigt: ein ersatzweise geschriebener Umlaut + steht nie hinter einem Vokal. Vorher standen hier dauer, neue, steuer, + feuer, bauer -- alle nach demselben Muster, und die Liste waere mit + jedem Beitrag weitergewachsen. Was bleibt, sind die echten Sonderfaelle: + "Michael" (ae hinter h), "aktuell" (ue hinter t). */ const UMLAUT_ERLAUBT = new Set([ - "michael", "dauer", "neue", "steuer", "feuer", "aktuell", "museum", + "michael", "aktuell", "museum", "waermepumpe-mueller", "waermepumpe-abnahme", ]); const BRAUCHT_SCHARFES_S = new Set([ @@ -4625,11 +4636,42 @@ if (location.search.indexOf("nur=anim") >= 0) function umlautFehler(wurzel) { const raus = []; wurzel.querySelectorAll("text, .headline, .body, .badge").forEach(e => { - String(e.textContent || "").split(/[^A-Za-zÄÖÜäöüß0-9./#@-]+/).forEach(w => { + /* Nicht textContent, sondern die Textknoten mit Leerzeichen dazwischen. + Eine Ueberschrift ist "Formulare selbst bauen.
Per + Drag-and-drop." -- textContent klebt daraus "bauen.Per" + zusammen, ein Wort, das es nicht gibt. Ein Umbruch und eine + Elementgrenze sind Wortgrenzen. */ + const stuecke = []; + const lauf = document.createTreeWalker(e, NodeFilter.SHOW_TEXT); + for (let k = lauf.nextNode(); k; k = lauf.nextNode()) stuecke.push(k.nodeValue); + const ganz = stuecke.join(" "); + /* Geviertstriche gehoeren nicht in unsere Texte. Der Halbgeviertstrich + als Gedankenstrich ist richtiges Deutsch und bleibt erlaubt; der + lange Strich ist eine englische Angewohnheit und liest sich auf einer + deutschen Slide fremd. Er kam nicht aus einer Quelle, sondern beim + Schreiben mit hinein. */ + if (ganz.indexOf("\u2014") >= 0) { + const stelle = "Geviertstrich in „" + ganz.trim().slice(0, 40) + "“"; + if (!raus.includes(stelle)) raus.push(stelle); + } + ganz.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); + if (!k || raus.includes(w)) return; + /* Mailadressen und Domains sind ausgenommen. Dort ist die + umlautfreie Schreibung keine Schludrigkeit, sondern Pflicht: + "buero@muster-shk.de" kann gar kein ue ersetzen. Ohne diese + Ausnahme meldete Post 8 drei Adressen als Fehler. */ + if (/@/.test(k) || /\.(de|com|net|org|eu|at|ch|io)$/.test(k)) return; + if ([...UMLAUT_ERLAUBT].some(a => k.startsWith(a))) return; + /* ae/oe/ue nur dann als verunglueckter Umlaut, wenn kein Vokal + davorsteht. Ein ae, oe oder ue, das fuer ae, oe oder ue steht, + folgt immer einem Konsonanten oder steht am Wortanfang: "fuer", + "ueber", "gruen", "Sanitaer", "Lueftung". Hinter einem Vokal sind + es dagegen immer zwei eigene Laute: bauen, Bauer, neue, Dauer, + Steuer, Feuer, Mauer, genauer. Die Regel ersetzt sechs Eintraege + in UMLAUT_ERLAUBT und alle, die dort noch gelandet waeren. */ + if (/(^|[^aeiou])(ae|oe|ue)/.test(k) || BRAUCHT_SCHARFES_S.has(k)) raus.push(w); }); }); return raus; @@ -4655,11 +4697,12 @@ 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 + /* Den Text 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."); + if (uf.length) throw new Error("Slide " + (i + 1) + ": " + uf.join(", ") + + ". Fehlt ein Umlaut, schreib ihn; ist das Wort so richtig, gehoert es " + + "in UMLAUT_ERLAUBT. Einen Geviertstrich ersetzt ein Punkt oder ein Komma."); 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 de7b937..968a737 100644 --- a/post6.html +++ b/post6.html @@ -1052,6 +1052,8 @@ if (location.search.indexOf("nur=anim") >= 0) + +

@@ -5550,8 +5552,17 @@ if (location.search.indexOf("nur=anim") >= 0) Kanalnamen sind Absicht: "# waermepumpe-mueller" ist ein Handle, und die schreiben Chatwerkzeuge klein und ohne Umlaute. */ + /* Woerter, in denen ae/oe/ue kein verkruepppelter Umlaut ist, sondern zwei + Laute an einer Silbengrenze. Die Eintraege wirken als Wortanfang. + + Die Liste ist kurz geworden, weil die Regel darunter den groessten Teil + der Ausnahmen von selbst erledigt: ein ersatzweise geschriebener Umlaut + steht nie hinter einem Vokal. Vorher standen hier dauer, neue, steuer, + feuer, bauer -- alle nach demselben Muster, und die Liste waere mit + jedem Beitrag weitergewachsen. Was bleibt, sind die echten Sonderfaelle: + "Michael" (ae hinter h), "aktuell" (ue hinter t). */ const UMLAUT_ERLAUBT = new Set([ - "michael", "dauer", "neue", "steuer", "feuer", "aktuell", "museum", + "michael", "aktuell", "museum", "waermepumpe-mueller", "waermepumpe-abnahme", ]); const BRAUCHT_SCHARFES_S = new Set([ @@ -5562,11 +5573,42 @@ if (location.search.indexOf("nur=anim") >= 0) function umlautFehler(wurzel) { const raus = []; wurzel.querySelectorAll("text, .headline, .body, .badge").forEach(e => { - String(e.textContent || "").split(/[^A-Za-zÄÖÜäöüß0-9./#@-]+/).forEach(w => { + /* Nicht textContent, sondern die Textknoten mit Leerzeichen dazwischen. + Eine Ueberschrift ist "Formulare selbst bauen.
Per + Drag-and-drop." -- textContent klebt daraus "bauen.Per" + zusammen, ein Wort, das es nicht gibt. Ein Umbruch und eine + Elementgrenze sind Wortgrenzen. */ + const stuecke = []; + const lauf = document.createTreeWalker(e, NodeFilter.SHOW_TEXT); + for (let k = lauf.nextNode(); k; k = lauf.nextNode()) stuecke.push(k.nodeValue); + const ganz = stuecke.join(" "); + /* Geviertstriche gehoeren nicht in unsere Texte. Der Halbgeviertstrich + als Gedankenstrich ist richtiges Deutsch und bleibt erlaubt; der + lange Strich ist eine englische Angewohnheit und liest sich auf einer + deutschen Slide fremd. Er kam nicht aus einer Quelle, sondern beim + Schreiben mit hinein. */ + if (ganz.indexOf("\u2014") >= 0) { + const stelle = "Geviertstrich in „" + ganz.trim().slice(0, 40) + "“"; + if (!raus.includes(stelle)) raus.push(stelle); + } + ganz.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); + if (!k || raus.includes(w)) return; + /* Mailadressen und Domains sind ausgenommen. Dort ist die + umlautfreie Schreibung keine Schludrigkeit, sondern Pflicht: + "buero@muster-shk.de" kann gar kein ue ersetzen. Ohne diese + Ausnahme meldete Post 8 drei Adressen als Fehler. */ + if (/@/.test(k) || /\.(de|com|net|org|eu|at|ch|io)$/.test(k)) return; + if ([...UMLAUT_ERLAUBT].some(a => k.startsWith(a))) return; + /* ae/oe/ue nur dann als verunglueckter Umlaut, wenn kein Vokal + davorsteht. Ein ae, oe oder ue, das fuer ae, oe oder ue steht, + folgt immer einem Konsonanten oder steht am Wortanfang: "fuer", + "ueber", "gruen", "Sanitaer", "Lueftung". Hinter einem Vokal sind + es dagegen immer zwei eigene Laute: bauen, Bauer, neue, Dauer, + Steuer, Feuer, Mauer, genauer. Die Regel ersetzt sechs Eintraege + in UMLAUT_ERLAUBT und alle, die dort noch gelandet waeren. */ + if (/(^|[^aeiou])(ae|oe|ue)/.test(k) || BRAUCHT_SCHARFES_S.has(k)) raus.push(w); }); }); return raus; @@ -5592,11 +5634,12 @@ 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 + /* Den Text 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."); + if (uf.length) throw new Error("Slide " + (i + 1) + ": " + uf.join(", ") + + ". Fehlt ein Umlaut, schreib ihn; ist das Wort so richtig, gehoert es " + + "in UMLAUT_ERLAUBT. Einen Geviertstrich ersetzt ein Punkt oder ein Komma."); const imgs = [...el.querySelectorAll("img")]; await Promise.all(imgs.map(im => im.complete ? im.decode().catch(() => {}) diff --git a/post7.html b/post7.html index ecc926f..10c5b90 100644 --- a/post7.html +++ b/post7.html @@ -1052,6 +1052,8 @@ if (location.search.indexOf("nur=anim") >= 0) + +

@@ -5838,8 +5840,17 @@ if (location.search.indexOf("nur=anim") >= 0) Kanalnamen sind Absicht: "# waermepumpe-mueller" ist ein Handle, und die schreiben Chatwerkzeuge klein und ohne Umlaute. */ + /* Woerter, in denen ae/oe/ue kein verkruepppelter Umlaut ist, sondern zwei + Laute an einer Silbengrenze. Die Eintraege wirken als Wortanfang. + + Die Liste ist kurz geworden, weil die Regel darunter den groessten Teil + der Ausnahmen von selbst erledigt: ein ersatzweise geschriebener Umlaut + steht nie hinter einem Vokal. Vorher standen hier dauer, neue, steuer, + feuer, bauer -- alle nach demselben Muster, und die Liste waere mit + jedem Beitrag weitergewachsen. Was bleibt, sind die echten Sonderfaelle: + "Michael" (ae hinter h), "aktuell" (ue hinter t). */ const UMLAUT_ERLAUBT = new Set([ - "michael", "dauer", "neue", "steuer", "feuer", "aktuell", "museum", + "michael", "aktuell", "museum", "waermepumpe-mueller", "waermepumpe-abnahme", ]); const BRAUCHT_SCHARFES_S = new Set([ @@ -5850,11 +5861,42 @@ if (location.search.indexOf("nur=anim") >= 0) function umlautFehler(wurzel) { const raus = []; wurzel.querySelectorAll("text, .headline, .body, .badge").forEach(e => { - String(e.textContent || "").split(/[^A-Za-zÄÖÜäöüß0-9./#@-]+/).forEach(w => { + /* Nicht textContent, sondern die Textknoten mit Leerzeichen dazwischen. + Eine Ueberschrift ist "Formulare selbst bauen.
Per + Drag-and-drop." -- textContent klebt daraus "bauen.Per" + zusammen, ein Wort, das es nicht gibt. Ein Umbruch und eine + Elementgrenze sind Wortgrenzen. */ + const stuecke = []; + const lauf = document.createTreeWalker(e, NodeFilter.SHOW_TEXT); + for (let k = lauf.nextNode(); k; k = lauf.nextNode()) stuecke.push(k.nodeValue); + const ganz = stuecke.join(" "); + /* Geviertstriche gehoeren nicht in unsere Texte. Der Halbgeviertstrich + als Gedankenstrich ist richtiges Deutsch und bleibt erlaubt; der + lange Strich ist eine englische Angewohnheit und liest sich auf einer + deutschen Slide fremd. Er kam nicht aus einer Quelle, sondern beim + Schreiben mit hinein. */ + if (ganz.indexOf("\u2014") >= 0) { + const stelle = "Geviertstrich in „" + ganz.trim().slice(0, 40) + "“"; + if (!raus.includes(stelle)) raus.push(stelle); + } + ganz.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); + if (!k || raus.includes(w)) return; + /* Mailadressen und Domains sind ausgenommen. Dort ist die + umlautfreie Schreibung keine Schludrigkeit, sondern Pflicht: + "buero@muster-shk.de" kann gar kein ue ersetzen. Ohne diese + Ausnahme meldete Post 8 drei Adressen als Fehler. */ + if (/@/.test(k) || /\.(de|com|net|org|eu|at|ch|io)$/.test(k)) return; + if ([...UMLAUT_ERLAUBT].some(a => k.startsWith(a))) return; + /* ae/oe/ue nur dann als verunglueckter Umlaut, wenn kein Vokal + davorsteht. Ein ae, oe oder ue, das fuer ae, oe oder ue steht, + folgt immer einem Konsonanten oder steht am Wortanfang: "fuer", + "ueber", "gruen", "Sanitaer", "Lueftung". Hinter einem Vokal sind + es dagegen immer zwei eigene Laute: bauen, Bauer, neue, Dauer, + Steuer, Feuer, Mauer, genauer. Die Regel ersetzt sechs Eintraege + in UMLAUT_ERLAUBT und alle, die dort noch gelandet waeren. */ + if (/(^|[^aeiou])(ae|oe|ue)/.test(k) || BRAUCHT_SCHARFES_S.has(k)) raus.push(w); }); }); return raus; @@ -5880,11 +5922,12 @@ 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 + /* Den Text 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."); + if (uf.length) throw new Error("Slide " + (i + 1) + ": " + uf.join(", ") + + ". Fehlt ein Umlaut, schreib ihn; ist das Wort so richtig, gehoert es " + + "in UMLAUT_ERLAUBT. Einen Geviertstrich ersetzt ein Punkt oder ein Komma."); const imgs = [...el.querySelectorAll("img")]; await Promise.all(imgs.map(im => im.complete ? im.decode().catch(() => {})