import fs from 'node:fs/promises'; import { fileURLToPath } from 'node:url'; const escapeText = value => value.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>'); // Populate the checked-in German fallback while retaining all runtime i18n markers. export function localizeHtml(source, translate) { const result = source.replaceAll(/(<[^>]+\bdata-i18n="([^"]+)"[^>]*>)([^<]*)(<\/)/g, (_match, opening, key, _text, closing) => opening + escapeText(translate(key)) + closing); return result.replaceAll(/<[^>]+>/g, opening => { let translated = opening; for (const attribute of ['title', 'aria-label', 'placeholder', 'alt']) { const key = new RegExp(`data-i18n-${attribute}="([^"]+)"`).exec(opening)?.[1]; if (!key) continue; const value = escapeText(translate(key)).replaceAll('"', '"'); // Match an actual attribute, never the suffix of its data-i18n marker. translated = translated.replaceAll(new RegExp(`(\\s)${attribute}="[^"]*"`, 'g'), (_match, space) => `${space}${attribute}="${value}"`); } return translated; }); } if (process.argv[1] === fileURLToPath(import.meta.url)) { await import('../public/js/texts-de.js'); await import('../public/js/i18n.js'); const file = new URL('../public/index.html', import.meta.url); const source = await fs.readFile(file, 'utf8'); const translated = localizeHtml(source, key => globalThis.Wegwichtel.I18n.t(key)); await fs.writeFile(file, translated); }