hisyëö syllabary
Newest candidate for Koqatha's official writing system.
by MadcapJake
HTML
<div class="inWrapper">
<label>Latin:</label>
<textarea id="latinIn" cols="80" rows="3" spellcheck="false">
zowo hônyo cûtî bûlo fîkî ulyô socok xe kôs zoston mût boxô dîzel yê zowo legêfû onô.
</textarea>
<button id="copyHisyeo" type="button">Copy 👇</button>
</div>
<div class="hidden" id="hisyeoOutText"></div>
<div id="hisyeoOut"></div>
CSS
@import url('https://fonts.cdnfonts.com/css/charis-sil');
@import url('https://fonts.cdnfonts.com/css/doulos-sil');
@import url('https://fonts.cdnfonts.com/css/gentium-plus');
@import url('https://fonts.cdnfonts.com/css/noto-sans');
* {
/* font-family: 'Charis SIL', sans-serif; */
/* font-family: 'Gentium Plus', sans-serif; */
font-family: "Noto Sans", sans-serif;
/* font-family: "Arial", sans-serif; */
}
.inWrapper {
display: flex;
align-items: center;
justify-content: space-between;
}
#hisyeoOut, #latinOut {
margin-top: 5px;
padding: 3px;
border: 2px solid black;
min-width: 400px;
min-height: 20px;
border-radius: 5px;
font-size: 2em;
background-color: white;
}
.hidden {
display: none;
}
label {
padding-right: 20px;
}
button {
margin: 3px;
color: black;
}
button.flash {
animation: flash 1s linear forwards;
}
@keyframes flash {
0% { color: red; }
100% { color: black; }
}
JavaScript
const lCons = ' hkgtcsxdzbfmnwly', sCons = ' hkgtcsxdzbfmnwly',
lVowels = 'ôuûiîeê', sVowels = 'orujiqe',
lDiacritics = 'ktlnsc', sDiacritics = 'KTLNSC'
index = (loc, val) => loc.indexOf(val.toLowerCase());
latinIn.oninput = function (e) {
hisyeoOutText.innerText = latinIn.value
// Pre-process quotation marks, replacing with [ and ] as placeholder quotation marks
.split('"')
.reduce((acc, v, i) => acc + (i % 2 ? '[' : ']') + v)
// Pre-process proper nouns, adding { and } as placeholder transliteration marks
.replace(/\b[A-ZÔÊÎÛ][A-ZÔÊÎÛa-zôêîûꞌ']*(?: [A-ZÔÊÎÛ][A-ZÔÊÎÛa-zôêîûꞌ']*)*/g, '{$&}')
// Replace abugida characters
.replace(
/([hkgtcsxdzbfmnwly])o(?=[oôuûiîeê])|([hkgtcsxdzbfmnwly])?([oôuûiîeê])([ktlnsc](?![oôuûiîeê]))?|([hkgtcsxdzbfmnwly])(?![oôuûiîeê])/gi, // RegEx: cons?+vowel+n? | const
(_, p0, p1, p2, p3, p4) => {
// console.log(`p0: ${p0}\tp1: ${p1}\tp2: ${p2}\tp3: ${p3}\tp4: ${p4}`)
return p0 ? sCons[index(lCons, p0)] + 'A' : // default vowel saver
p4 ? sCons[index(lCons, p4)] : // null onset
(sCons[(p1 ? index(lCons, p1) : -1)] ?? '') + // onset
(sVowels[index(lVowels, p2)] ?? (!p1 ? 'a' : '')) + // vowel
(p3 ? sDiacritics[index(lDiacritics, p3)] : '') // coda
}
)
// Replace punctuation
.replace(/\[/g, '«')
.replace(/]/g, '»')
// Replace newlines with a placeholder character to later update as <br />
// because this initial step uses innerText for safer DOM modification
.replace(/\r?\n/g, '\uFFFE');
// Update actual output through innerHTML and only now update line breaks
hisyeoOut.innerHTML = hisyeoOutText.innerHTML.replace(/\uFFFE/g,...