// ==UserScript==
// @name ΘΟΚΥΔΙΔΟ ΚΤΕΜΑ ΤΕ ΕΣ ΑΙΕΙ
// @namespace http://lunacy.wtf/
// @version 2.0
// @description Finds Ancient Greek text, transliterates it into an archaic majuscule style, and applies a custom font.
// @author Lunacy
// @match *://*/*
// @exclude https://lunacy.wtf/*
// @exclude https://docs.google.com/*
// @exclude https://suno.com/*
// @license Proprietary
// @grant GM_addStyle
// @run-at document-idle
// ==/UserScript==
(function() {
'use strict';
// ======================= 1. FONT AND STYLE INJECTION (From Script 2) =======================
// This part injects the custom font and the CSS class that will be used to apply it.
// The placeholder for the base64 font data must be replaced with your actual font file.
GM_addStyle(`
@font-face {
font-family: 'ArchaicGreekFont';
/* IMPORTANT: Replace the placeholder below with your actual base64 font data. */
/* To convert a font: use a tool like https://www.base64encode.org/ to encode your .woff2 file and paste the result here. */
src: url(data:font/woff2;base64,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aQNwc2kFb21lZ2EHdW5pMDM3MQdlbWFjcm9uB2FtYWNyb24HaW1hY3JvbgdvbWFjcm9uB3VtYWNyb24HdW5pMDIzMwd1bmkxRjAwCmFscGhhdG9ub3MHdW5pMUY3MAd1bmkxRjA0B3VuaTFGMDIHdW5pMUZCNgd1bmkxRjA2B3VuaTFGODAHdW5pMUYwOAd1bmkxRjBDB3VuaTFGMEEHdW5pMUYwRQd1bmkxRjEwDGVwc2lsb250b25vcwd1bmkxRjcyB3VuaTFGMTQHdW5pMUYxMgd1bmkxRjE4B3VuaTFGMUMHdW5pMUYxQQd1bmkxRjUwDHVwc2lsb250b25vcwd1bmkxRjdBB3VuaTFGNTQHdW5pMUY1Mgd1bmkxRjVEB3VuaTFGRTYHdW5pMUY1Ngd1bmkxRjIwCGV0YXRvbm9zB3VuaTFGNzQHdW5pMUZDNgd1bmkxRjI0B3VuaTFGMjIHdW5pMUYyNgd1bmkxRjIxB3VuaTFGMjgHdW5pMUYyQwd1bmkxRjJBB3VuaTFGMkUHdW5pMUYzMAlpb3RhdG9ub3MHdW5pMUY3Ngd1bmkxRkQ2B3VuaTFGMzQHdW5pMUYzNgxpb3RhZGllcmVzaXMRaW90YWRpZXJlc2lzdG9ub3MHdW5pMUYzOAd1bmkxRjNDB3VuaTFGM0EHdW5pMUYzRQd1bmkxRjQwDG9taWNyb250b25vcwd1bmkxRjc4B3VuaTFGNDQHdW5pMUY0Mgd1bmkxRjQ4B3VuaTFGNEMHdW5pMUY0QQd1bmkxRjYwCm9tZWdhdG9ub3MHdW5pMUY3Qwd1bmkxRkY2B3VuaTFGNjYHdW5pMUY2Mgd1bmkxRjY4B3VuaTFGNkMHdW5pMUY2QQd1bmkxRjZFAAAAAAAB//8AAgABAAAADAAAABwAJAACAAIAAwBYAAEAWgCLAAEABAAAAAIAAAABAAAAAQAAAAAAAQAAAADf1ssxAAAAAOS2r2YAAAAA5L1j2g==) format('woff2');
font-weight: normal;
font-style: normal;
}
.archaic-greek-text {
font-family: 'ArchaicGreekFont', sans-serif !important;
}
`);
// ======================= 2. CORE TRANSLITERATION LOGIC =======================
const archaicMajusculeMap = {
// ===================== Alpha ===========================
// Lowercase
'ἁ':'ͱα', 'ᾁ':'ͱαι', 'ἇ':'ͱα', 'ἅ':'ͱα', 'ἃ':'ͱα',
// Iota Subscript
'ᾷ':'αι', 'ᾴ':'αι', 'ᾳ':'αι',
// Uppercase
'Ἁ':'ͰA', 'Ἅ':'ͰA',
// ===================== Epsilon =========================
// Lowercase
'ἑ':'ͱε', 'ἓ':'ͱε', 'ἕ':'ͱε',
// Uppercase
'Ἑ':'ͰΕ', 'Ἕ':'ͰΕ',
// ===================== Eta =============================
// Lowercase
'ἡ':'ͱη', 'ᾗ':'ͱηι', 'ἧ':'ͱη', 'ἥ':'ͱη', 'ἣ':'ͱη', 'ᾑ':'ͱηι',
// Iota Subscript
'ῄ':'ηι', 'ᾖ':'ηι', 'ῇ':'ηι', 'ῃ':'ηι','ᾐ':'ηι',
// Uppercase
'Ἡ':'ͰΗ',
// ===================== Iota =============================
// Lowercase
'ἳ':'ͱι', 'ἱ':'ͱι', 'ἵ':'ͱι', 'ἷ':'ͱι',
// Uppercase
'Ἱ':'ͰΙ', 'Ἵ':'ͰΙ',
// ===================== Omicron ============================
// Lowercase
'ὁ':'ͱο', 'ὅ':'ͱο', 'ὃ':'ͱο',
// Uppercase
'Ὁ':'ͰΟ', 'Ὅ':'ͰΟ',
// ===================== Omega ==============================
// Lowercase
'ὡ':'ͱω', 'ὧ':'ͱω', 'ὥ':'ͱω',
// Iota Subscript
'ᾧ':'ͱωι','ῳ':'ωι', 'ῷ':'ωι', 'ᾠ':'ωι', 'ᾤ':'ωι', 'ῴ':'ωι',
// Uppercase
'Ὡ':'ͰΩ',
// ===================== Ypsilon ==============================
// Lowercase
'ὕ':'ͱυ', 'ὑ':'ͱυ', 'ὗ':'ͱυ', 'ὕ':'ͱυ',
// Uppercase
'Ὑ':'Ͱυ', 'Ὓ':'Ͱυ', 'Ὗ':'Ͱυ',
// ===================== Rho ==============================
'ῥ':'ΡͰ',
// ===================== COMPOUND CONSONANTS (Digraphs) ==============================
'ξ':'χς', 'Ξ':'ΧΣ', 'ψ':'πς', 'Ψ':'ΦΣ',
};
// ======================= STATE 2: MACRONS ON =======================
const archaicMap_MacronsOn = {
// ===================== Alpha Macron Collection ===========================
// Lowercase ā
'ᾶ':'ā', 'ἆ':'ā', 'ᾀ':'ā', 'ᾷ':'āι',
// Rough Breathing Mark, Heta
'ἇ':'ͱā', 'ἅ':'ͱα',
// Uppercase Ā
'Ἆ':'Ā',
// ===================== Eta Macron Collection ===========================
// Lowercase ē
'η':'ē', 'ἠ':'ē', 'ή':'ē', 'ὴ':'ē', 'ῆ':'ē', 'ἤ':'ē', 'ἢ':'ē', 'ἦ':'ē',
// Uppercase Ē
'Η':'Ē', 'Ἠ':'Ē', 'Ἤ':'Ē', 'Ἢ':'Ē', 'Ἦ':'Ē',
// Rough Breathing Mark, Heta
'ἡ':'ͱē', 'ᾗ':'ͱēι', 'ἧ':'ͱē', 'ἥ':'ͱē', 'ἣ':'ͱē', 'ῄ':'ēι', 'ᾖ':'ēι', 'ῇ':'ēι', 'ᾑ':'ͱēι', 'ῃ':'ēι','ᾐ':'ēι',
'Ἡ':'ͰĒ',
// ===================== Iota Macron Collection ===========================
// Lowercase ī
'ῖ':'ī', 'ἶ':'ī', 'ἷ':'ͱī',
// Uppercase Ī
'Ἶ':'Ī',
// ===================== Omega Macron Collection ===========================
// Lowercase ō
'ω':'ō', 'ὠ':'ō', 'ώ':'ō', 'ὼ':'ō', 'ῶ':'ō', 'ὦ':'ō', 'ὢ':'ō',
// Heta
'ὡ':'ͱō', 'ὧ':'ͱō', 'ὥ':'ͱō',
// Iota Subscript
'ᾧ':'ͱōι','ῳ':'ōι', 'ῷ':'ōι', 'ᾠ':'ōι', 'ᾤ':'ōι', 'ῴ':'ōι',
// Uppercase
'Ὠ':'Ō', 'Ὤ':'Ō', 'Ὢ':'Ō', 'Ὦ':'Ō', 'Ω':'Ō',
// Heta
'Ὡ':'ͰŌ',
// ===================== Ypsilon Macron Collection ===========================
// Υ (ΥPSILON) - Ῡ
'ῦ':'ȳ', 'ὖ':'ȳ', 'ὗ':'ͱȳ',
'Ὗ':'Ͱȳ',
};
// ====== 0) EDITABLE-FIELD GUARD (add near the top) ======
const EDITABLE_SELECTOR =
'input, textarea, select, option, [contenteditable]:not([contenteditable="false"]), [role="textbox"], .ProseMirror, .ql-editor, .public-DraftEditor-content';
function isEditableRoot(el) {
if (!el) return false;
if (el.isContentEditable) return true;
return !!el.closest(EDITABLE_SELECTOR);
}
// ====== MACRON TOGGLE STATE ======
let MACRONS_ON = false;
// Use macrons map when ON; otherwise fall back to your base map
function mapChar(ch) {
if (MACRONS_ON && archaicMap_MacronsOn[ch] != null) return archaicMap_MacronsOn[ch];
return (archaicMajusculeMap[ch] != null) ? archaicMajusculeMap[ch] : ch;
}
const diphthongVowelBases = new Set(['α','ε','ο','η','ω','Α','Ε','Ο','Η','Ω']);
const roughBreathingSecond = new Set([
// iota with rough breathing
'ἱ','ἵ','ἳ','ἷ','Ἱ','Ἵ','Ἳ','Ἷ',
// upsilon with rough breathing
'ὑ','ὕ','ὓ','ὗ','Ὑ','Ὕ','Ὓ','Ὗ'
]);
function convertToArchaic(text) {
const normalizedInput = text.normalize('NFC');
// Preserve ο + rough ὑ before collapsing to ω/Ω
const oRoughURegex = /ο[ὑὕὓὗ]/g;
const ORoughURegex = /Ο[ὙὝὛὟ]/g;
// Collapse remaining ο+υ digraphs (no breathing) to ω/Ω
const ouDigraphRegex = /[οΟ][υύὺῦὐὑὔὒὖὗΥΎῪὛὝὟ]/g;
const processedText = normalizedInput
.replace(oRoughURegex, 'ͱω') // οὑ/οὕ/οὓ/οὗ → ͱω (later macronizes to ͱō if ON)
.replace(ORoughURegex, 'ͰΩ') // Οὑ/Οὕ/Οὓ/Οὗ → ͰΩ (later macronizes to ͰŌ if ON)
.replace(ouDigraphRegex, m => (m.startsWith('Ο') ? 'Ω' : 'ω'));
let finalOutput = '';
for (let i = 0; i < processedText.length; i++) {
const char = processedText[i];
const prevChar = i > 0 ? processedText[i - 1] : null;
// Handle initial diphthongs with rough breathing on second char (ι/υ)
if (prevChar && diphthongVowelBases.has(prevChar) && roughBreathingSecond.has(char)) {
const isPrevUpper = (prevChar === prevChar.toUpperCase() && prevChar !== prevChar.toLowerCase());
const heta = isPrevUpper ? 'Ͱ' : 'ͱ';
// Remove what we emitted for prevChar (computed with same mapper!)
const prevOut = mapChar(prevChar);
finalOutput = finalOutput.slice(0, -prevOut.length);
// Current char without the inserted heta in its mapping (if any)
const currNoBreath = mapChar(char).replace(/[ͱͰ]/g, '');
finalOutput += heta + prevOut + currNoBreath;
continue;
}
finalOutput += mapChar(char);
}
return finalOutput;
}
// ======================= 3. GREEK TEXT FILTER (hardened) =======================
const ALL_GREEK_CHARS_REGEX = /([\u0370-\u03FF\u1F00-\u1FFF]+)/gu;
function processAndWrap(rootNode) {
if (![Node.ELEMENT_NODE, Node.DOCUMENT_NODE, Node.DOCUMENT_FRAGMENT_NODE].includes(rootNode.nodeType)) {
return;
}
const walker = document.createTreeWalker(
rootNode,
NodeFilter.SHOW_TEXT,
{
acceptNode(node) {
const p = node.parentElement;
if (!p) return NodeFilter.FILTER_REJECT;
// NEW: never process inside live/editable fields
if (isEditableRoot(p)) return NodeFilter.FILTER_REJECT;
const tag = p.tagName ? p.tagName.toUpperCase() : '';
if (tag === 'SCRIPT' || tag === 'STYLE' || tag === 'TEXTAREA') {
return NodeFilter.FILTER_REJECT;
}
if (p.closest('.archaic-greek-text')) {
return NodeFilter.FILTER_REJECT;
}
if (ALL_GREEK_CHARS_REGEX.test(node.nodeValue)) {
ALL_GREEK_CHARS_REGEX.lastIndex = 0;
return NodeFilter.FILTER_ACCEPT;
}
return NodeFilter.FILTER_SKIP;
}
}
);
const nodesToProcess = [];
let currentNode;
while ((currentNode = walker.nextNode())) {
nodesToProcess.push(currentNode);
}
for (const node of nodesToProcess) {
const text = node.nodeValue;
const fragment = document.createDocumentFragment();
let lastIndex = 0;
text.replace(ALL_GREEK_CHARS_REGEX, (match, _p1, offset) => {
if (offset > lastIndex) {
fragment.appendChild(document.createTextNode(text.substring(lastIndex, offset)));
}
// ▼ Put these lines here ▼
const converted = convertToArchaic(match);
const span = document.createElement('span');
span.className = 'archaic-greek-text';
span.setAttribute('data-original', match); // store original once
// (equivalent: span.dataset.original = match)
span.textContent = converted;
fragment.appendChild(span);
// ▲ Up to here ▲
lastIndex = offset + match.length;
});
if (lastIndex < text.length) {
fragment.appendChild(document.createTextNode(text.substring(lastIndex)));
}
if (node.parentNode) {
node.parentNode.replaceChild(fragment, node);
}
}
}
function reconvertAll(root = document) {
root.querySelectorAll('.archaic-greek-text').forEach(span => {
const original = span.getAttribute('data-original');
if (original != null) {
span.textContent = convertToArchaic(original);
}
});
}
// ======================= 4. DYNAMIC CONTENT HANDLING (reliable + throttled) =======================
// Initial pass
processAndWrap(document.body);
// Queue + throttle
const pending = new Set();
let flushTimer = null;
const FLUSH_DELAY = 50; // ms; raise if pages are very chatty
const BATCH_SIZE = 20; // nodes per tick; tune for your machine
// ====== inside enqueue(node) ======
function enqueue(node) {
let el = null;
if (node.nodeType === Node.ELEMENT_NODE) el = node;
else if (node.nodeType === Node.TEXT_NODE) el = node.parentElement;
if (!el) return;
if (!document.body.contains(el)) return;
// NEW: skip anything that is or lives inside an editable field
if (isEditableRoot(el)) return;
pending.add(el);
}
function minimizeRoots(nodes) {
// drop descendants when an ancestor is already queued
const set = new Set(nodes);
return nodes.filter(n => {
let p = n.parentElement;
while (p) {
if (set.has(p)) return false;
p = p.parentElement;
}
return true;
});
}
function scheduleFlush() {
if (flushTimer) return;
flushTimer = setTimeout(flush, FLUSH_DELAY);
}
function flush() {
flushTimer = null;
// Snapshot + clear pending
const unique = Array.from(pending);
pending.clear();
const roots = minimizeRoots(unique);
let index = 0;
function step() {
const end = Math.min(index + BATCH_SIZE, roots.length);
for (; index < end; index++) {
// Important: do NOT unwrap existing '.archaic-greek-text' here;
// processAndWrap already skips inside them, so we avoid rework/jank.
processAndWrap(roots[index]);
}
if (index < roots.length) {
// Yield to the event loop to keep the UI responsive
setTimeout(step, 16);
}
}
step();
}
(function injectMacronToggle() {
const btn = document.createElement('button');
btn.type = 'button';
btn.id = 'macronToggle';
btn.textContent = 'Macrons: OFF';
btn.style.cssText = [
'position:fixed',
'right:14px',
'bottom:14px',
'z-index:2147483647',
'padding:8px 12px',
'border-radius:10px',
'border:1px solid rgba(255,255,255,.2)',
'background:#111',
'color:#eee',
'font:600 12px system-ui,-apple-system,Segoe UI,Roboto,sans-serif',
'box-shadow:0 2px 8px rgba(0,0,0,.3)',
'cursor:pointer',
'opacity:.85'
].join(';');
btn.addEventListener('mouseenter', () => btn.style.opacity = '1');
btn.addEventListener('mouseleave', () => btn.style.opacity = '.85');
btn.addEventListener('click', () => {
MACRONS_ON = !MACRONS_ON;
btn.textContent = 'Macrons: ' + (MACRONS_ON ? 'ON' : 'OFF');
reconvertAll();
});
document.documentElement.appendChild(btn);
})();
const observer = new MutationObserver((mutations) => {
// Pull any queued-but-not-delivered records to avoid drops
const all = mutations.concat(observer.takeRecords());
for (const m of all) {
if (m.type === 'childList') {
m.addedNodes.forEach(enqueue);
// If a framework replaces text by toggling .textContent on an existing node,
// the 'childList' target often *is* the container whose text changed:
enqueue(m.target);
} else if (m.type === 'characterData') {
enqueue(m.target); // text node
enqueue(m.target.parentElement); // its container
}
}
scheduleFlush();
});
observer.observe(document.body, {
childList: true,
characterData: true,
subtree: true
});
})();