Hîsyêô Abugida
Newest candidate for Koqatha's official writing system.
by MadcapJake
HTML
<label>
<input id="quoteTypeSquare" type="radio" name="quoteType" checked/> 「 and 」
</label>
<label>
<input id="quoteTypeButton" type="radio" name="quoteType"/> ◖ and ◗
</label>
<label>
<input id="commaToggle" type="checkbox" checked/> , = 、
</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-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 = ["'", "ꞌ", 'h', 'k', 'g', 't', 'c', 's', 'x', 'd', 'z', 'b', 'f', 'm', 'n', 'w', 'l', 'y'],
kCons = ['ɽ', 'ɽ', 'ɂ', 'ɔ', 'ꜿ', 'c', 'ꞇ', 'ɐ', 'ɋ', 'ʌ', 'ⱴ', 'ʋ', 'ɤ', 'ƶ', 'ƨ', 'ʒ', 'ʓ', 'ɀ']; // oϷʑʌxɕƨɂɞɤʁⱶ
const lVowels = ['o', 'ô', 'u', 'û', 'i', 'î', 'e', 'ê'];
const kVowels = ['', 'ı', 'ʃ', 'ʄ', 'ȷ', 'ɟ', 'ɿ', 'ʇ']; // 'ɿjɉɩᵼ'; //ꜣꞌᶫ ıȷjʝſɿɾrɍɩᵼ℩℩
const lDiacritics = ['t',/* ◌̑ */'k',/* ◌͒ */ 's',/* ◌̀ */'c',/* ◌̄ */'n',/* ◌̉ */'l',/* ◌̉ */],
kDiacritics = ['\u0306', '\u0311', '\u0301', '\u0304', '\u0303', '\u034a',];
quoteTypeSquare.oninput = quoteTypeButton.oninput = commaToggle.oninput = () => latinIn.oninput()
index = (loc, val) => loc.indexOf(val.toLowerCase())
latinIn.oninput = function (e) {
let quotation = quoteTypeSquare.checked ? ['\uFF62', '\uFF63'] : ['\u25D6', '\u25D7']
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(
/([ꞌhkgtcsxdzbfmnlwy])?([oôuûiîeê])((?:[kntscl])(?![oôuûiîeê]))?|([ꞌhkgtcsxdzbfmnlwy])(?![oôuûiîeê])/gi, // RegEx: cons?+vowel+n? | const
(p0, p1, p2, p3, p4) => {
// console.log(p0);
return p4 // If no vowel found
? kCons[index(lCons, p4)] // Null consonant
: kCons[(p1 ? index(lCons, p1) : 0)] + // Leading consonant
(p3 ? kDiacritics[index(lDiacritics, p3)] : '') +
(kVowels[index(lVowels, p2)] || '')
}
)
// Replace punctuation
.replace(/,/g,...