Orthography Profiles with JavaScript
This fiddle illustrates how sequences can be manipulated with the help of orthography profiles implemented in JavaScript.
by LinguList
HTML
<h1>
Orthography Profiles with JavaScript
</h1>
<table>
<tr>
<td>
<label for="opin">Input String: </label>
</td>
<td>
<input id="opin" type="text" placeholder="your string here" onkeyup="activate(this.value)"/>
</td>
</tr>
<tr>
<td>
<label for="opout_grapheme">Output (Grapheme): </label>
</td>
<td>
<span id="opout_grapheme"/>
</td>
</tr>
<tr>
<td>
<label for="opout_ipa">Output (IPA): </label>
</td>
<td>
<span id="opout_ipa"/>
</td>
</tr>
</table>
CSS
.segment {
display: table-cell;
background-color: lightgray;
padding: 2px;
border: 1px solid black;
width: 30px;
}
JavaScript
/* Function segmentizes a word when a profile is given.
*/
function segmentize(word, profile) {
/* normalize according to NFD */
word = word.normalize('NFD');
if (word.length == 0) {
return [word];
}
/* define queue and output*/
var queue = [[[], word, '']];
/* define variables */
var segmented, current, rest;
/* main loop */
while (queue.length > 0) {
[segmented, current, rest] = queue.splice(0, 1)[0];
/* A: check if the current segment occurs in the profile */
if (current in profile && !(rest)) {
return segmented.concat([current]);
}
/* B: check for non-specified characters in profile */
else if (current.length == 1 && !(current in profile)) {
if (rest) {
queue.push([segmented.concat([current]), rest, '']);
}
else {
return segmented.concat([current]);
}
}
/* C: check for next smaller string */
else if (!(current in profile)) {
queue.push(
[
segmented,
current.slice(0, current.length-1),
current[current.length-1] + rest
]
);
}
/* D: if current in profile, proceed with rest */
else {
queue.push(
[
segmented.concat([current]),
rest,
''
]
);
}
}
}
/* convert a segmented sequence into another orthography */
function convert(segments, profile, column){
var output = [];
var i;
for (i=0; i<segments.length; i++) {
if (segments[i] in profile) {
output.push(profile[segments[i]][column]);
}
else {
output.push('«' + segments[i] + '»');
}
}
return output;
}
var profile = {
"th": {"grapheme": "th", "ipa": "tʰ"},
"ph": {"grapheme": "ph", "ipa": "pʰ"},
"kh": {"grapheme": "kh", "ipa": "kʰ"},
"a": {"grapheme": "a", "ipa": "a"},
"i": {"grapheme": "i", "ipa": "i"},
"u": {"grapheme": "u", "ipa": "u"},
"aa": {"grapheme": "aa", "ipa": "aː"},
"ii": {"grapheme": "ii", "ipa": "iː"},
...