/** * Strip Greek tonos (accent marks) from text inside elements that have the * `uppercase` CSS class. * * In Greek typography, capital letters do not carry the tonos accent. * CSS `text-transform: uppercase` uppercases the glyph but leaves the tonos * in place, producing visually incorrect output (e.g. Ά instead of Α). * This utility rewrites the text nodes directly so the rendered result is clean. * * The diaeresis (ϊ, ϋ) is preserved — it is retained in Greek uppercase. * * Runs once on DOMContentLoaded and then watches for dynamically added nodes * via MutationObserver. */ const ACCENT_MAP = { // Lowercase with tonos → without tonos 'ά': 'α', 'έ': 'ε', 'ή': 'η', 'ί': 'ι', 'ό': 'ο', 'ύ': 'υ', 'ώ': 'ω', // Uppercase with tonos → without tonos (for already-uppercased text) 'Ά': 'Α', 'Έ': 'Ε', 'Ή': 'Η', 'Ί': 'Ι', 'Ό': 'Ο', 'Ύ': 'Υ', 'Ώ': 'Ω', // Combined tonos + diaeresis → diaeresis only (preserve the diaeresis) 'ΐ': 'ϊ', 'ΰ': 'ϋ', } const ACCENT_RE = /[άέήίόύώΆΈΉΊΌΎΏΐΰ]/g function stripAccents(str) { return str.replace(ACCENT_RE, c => ACCENT_MAP[c] ?? c) } function processElement(el) { const walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT) let node while ((node = walker.nextNode())) { const val = node.nodeValue if (val && /[άέήίόύώΆΈΉΊΌΎΏΐΰ]/.test(val)) { node.nodeValue = stripAccents(val) } } } function applyToPage() { document.querySelectorAll('.uppercase').forEach(processElement) } // ── Initial pass ────────────────────────────────────────────────────────────── document.addEventListener('DOMContentLoaded', applyToPage) // ── Observe dynamic additions ───────────────────────────────────────────────── const observer = new MutationObserver(mutations => { for (const { addedNodes } of mutations) { for (const node of addedNodes) { if (node.nodeType !== Node.ELEMENT_NODE) continue if (node.classList?.contains('uppercase')) processElement(node) node.querySelectorAll?.('.uppercase').forEach(processElement) } } }) observer.observe(document.body, { childList: true, subtree: true })