Pruefung der Texte: weniger Ausnahmen, Geviertstriche, Navigation bis Post 9

ae/oe/ue gilt hinter einem Vokal nicht mehr als fehlender Umlaut, Mailadressen
und Domains sind ausgenommen, Geviertstriche werden gemeldet. Das Menue nennt
Post 8 und Post 9.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
dejanandClaude Opus 5.5 committed 2026-10-20 15:55:49 +02:00
1 parent 5a65b5444c
commit 76ac3e4cce
9 files changed
+403 -58

No files matched your search

+3 -2
View File
@@ -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 `);
+50 -7
View File
@@ -804,6 +804,8 @@ if (location.search.indexOf("nur=streifen") >= 0)
<button type="button" data-gehe="./post5.html">Post 5 · Projektmanagement</button>
<button type="button" data-gehe="./post6.html">Post 6 · Team-Chat</button>
<button type="button" data-gehe="./post7.html">Post 7 · Form Builder</button>
<button type="button" data-gehe="./post8.html">Post 8 · E-Mail-Marketing</button>
<button type="button" data-gehe="./post9.html">Post 9 · Webinar</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
<hr>
@@ -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.<br><span>Per
Drag-and-drop.</span>" -- 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(() => {})
+50 -7
View File
@@ -1107,6 +1107,8 @@ if (location.search.indexOf("nur=anim") >= 0)
<button type="button" data-gehe="./post5.html">Post 5 · Projektmanagement</button>
<button type="button" data-gehe="./post6.html">Post 6 · Team-Chat</button>
<button type="button" data-gehe="./post7.html">Post 7 · Form Builder</button>
<button type="button" data-gehe="./post8.html">Post 8 · E-Mail-Marketing</button>
<button type="button" data-gehe="./post9.html">Post 9 · Webinar</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
<hr>
@@ -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.<br><span>Per
Drag-and-drop.</span>" -- 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(() => {})
+50 -7
View File
@@ -1000,6 +1000,8 @@ if (location.search.indexOf("nur=anim") >= 0)
<button type="button" data-gehe="./post5.html">Post 5 · Projektmanagement</button>
<button type="button" data-gehe="./post6.html">Post 6 · Team-Chat</button>
<button type="button" data-gehe="./post7.html">Post 7 · Form Builder</button>
<button type="button" data-gehe="./post8.html">Post 8 · E-Mail-Marketing</button>
<button type="button" data-gehe="./post9.html">Post 9 · Webinar</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
<hr>
@@ -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.<br><span>Per
Drag-and-drop.</span>" -- 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(() => {})
+50 -7
View File
@@ -1020,6 +1020,8 @@ if (location.search.indexOf("nur=anim") >= 0)
<button type="button" data-gehe="./post5.html">Post 5 · Projektmanagement</button>
<button type="button" data-gehe="./post6.html">Post 6 · Team-Chat</button>
<button type="button" data-gehe="./post7.html">Post 7 · Form Builder</button>
<button type="button" data-gehe="./post8.html">Post 8 · E-Mail-Marketing</button>
<button type="button" data-gehe="./post9.html">Post 9 · Webinar</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
<hr>
@@ -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.<br><span>Per
Drag-and-drop.</span>" -- 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(() => {})
+50 -7
View File
@@ -1048,6 +1048,8 @@ if (location.search.indexOf("nur=anim") >= 0)
<button type="button" data-gehe="./post5.html">Post 5 · Projektmanagement</button>
<button type="button" data-gehe="./post6.html">Post 6 · Team-Chat</button>
<button type="button" data-gehe="./post7.html">Post 7 · Form Builder</button>
<button type="button" data-gehe="./post8.html">Post 8 · E-Mail-Marketing</button>
<button type="button" data-gehe="./post9.html">Post 9 · Webinar</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
<hr>
@@ -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.<br><span>Per
Drag-and-drop.</span>" -- 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(() => {})
+50 -7
View File
@@ -1048,6 +1048,8 @@ if (location.search.indexOf("nur=anim") >= 0)
<button type="button" data-gehe="./post5.html">Post 5 · Projektmanagement</button>
<button type="button" data-gehe="./post6.html">Post 6 · Team-Chat</button>
<button type="button" data-gehe="./post7.html">Post 7 · Form Builder</button>
<button type="button" data-gehe="./post8.html">Post 8 · E-Mail-Marketing</button>
<button type="button" data-gehe="./post9.html">Post 9 · Webinar</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
<hr>
@@ -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.<br><span>Per
Drag-and-drop.</span>" -- 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(() => {})
+50 -7
View File
@@ -1052,6 +1052,8 @@ if (location.search.indexOf("nur=anim") >= 0)
<button type="button" data-gehe="./post5.html">Post 5 · Projektmanagement</button>
<button type="button" data-gehe="./post6.html">Post 6 · Team-Chat</button>
<button type="button" data-gehe="./post7.html">Post 7 · Form Builder</button>
<button type="button" data-gehe="./post8.html">Post 8 · E-Mail-Marketing</button>
<button type="button" data-gehe="./post9.html">Post 9 · Webinar</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
<hr>
@@ -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.<br><span>Per
Drag-and-drop.</span>" -- 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(() => {})
+50 -7
View File
@@ -1052,6 +1052,8 @@ if (location.search.indexOf("nur=anim") >= 0)
<button type="button" data-gehe="./post5.html">Post 5 · Projektmanagement</button>
<button type="button" data-gehe="./post6.html">Post 6 · Team-Chat</button>
<button type="button" data-gehe="./post7.html">Post 7 · Form Builder</button>
<button type="button" data-gehe="./post8.html">Post 8 · E-Mail-Marketing</button>
<button type="button" data-gehe="./post9.html">Post 9 · Webinar</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
<hr>
@@ -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.<br><span>Per
Drag-and-drop.</span>" -- 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(() => {})