Hîsyêô Syllabary
Newest candidate for Koqatha's official writing system.
by MadcapJake
HTML
<label>
<input id="quoteTypeDoubleAngle" type="radio" name="quoteType" checked /> 《 and 》
</label>
<label>
<input id="quoteTypeSquare" type="radio" name="quoteType" /> 「 and 」
</label>
<br /><br />
<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-face {
font-family: HisyakuiSans;
src: url('https://hisyeo.github.io/HisyakuiSans.woff2');
}
* {
/* 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 {
font-family: HisyakuiSans, Helvetica, sans-serif;
margin-top: 5px;
padding: 3px;
border: 2px solid black;
width: auto;
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 quotation = ['\u25D6', '\u25D7'],
diacritic = '\u0304',
lCons = ' hkgtcsxdzbfmnwly', sCons = ' hkgtcsxdzbfmnwly',
lVowels = 'ôuûiîeê', sVowels = 'orujiqe',
lDiacritics = 'ktlnsc', sDiacritics = 'KTLNSC';
quoteTypeDoubleAngle.oninput = quoteTypeSquare.oninput = () => latinIn.oninput()
index = (loc, val) => loc.indexOf(val.toLowerCase())
latinIn.oninput = function (e) {
let quotation = quoteTypeSquare.checked ? ['「 ', ' 」'] : ['《 ', ' 》']
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, quotation[0])
.replace(/]/g, quotation[1])
.replace(/\{/g, '〈 ')
.replace(/}/g, ' 〉')
// Replace newlines with a placeholder character to later...