calc-fst
A demo implementation of the fuzzy string match described at https://github.com/patkaiist/calc-fst and https://calc.hypotheses.org/ for the journal Computer-Assisted Language Comparison in Practice
by patkaiist
HTML
<!-- A demo implementation of the fuzzy string match described at https://github.com/patkaiist/calc-fst and https://calc.hypotheses.org/ for the journal Computer-Assisted Language Comparison in Practice -->
<html>
<style type="text/css">
* {font-size: 16px; font-family: sans-serif}
</style>
<body>
<p>
Input a spelling using ny, ni, sh, ch, or ng to get a list of variant spellings.
</p>
<p>
<input type="text" placeholder="nyou.pan" value="nyou.pan" id="input"/>
<button onclick="show_variants()">
get variants
</button>
</p>
<p>
<strong>all spelling variations:</strong> <span id="output"></span>
</p>
</body>
</html>
JavaScript
const replacements = {
"ɲ": ["ny", "ni", "nyi"],
"ŋ": ["ng", "ny"],
"ʊ": ["ou","o","u"],
"o": ["u"],
"u": ["o"],
"ʃ": ["si","sh","s"],
"ʧ": ["ch", "chh", "j"]
};
function replaceWithFirst(variant) {
for (const key in replacements) {
const firstReplacement = replacements[key][0];
variant = variant.split(key).join(firstReplacement);
}
return variant;
}
function generateVariations(input) {
if (!input || input.length === 0) {
return [""];
}
const segments = input.replace(/\./g, '.·').split('·');
let variations = [''];
for (const segment of segments) {
const segmentVariations = [];
for (const variation of variations) {
const segmentVariants = generateSegmentVariations(segment);
for (const segmentVariant of segmentVariants) {
let variant = variation + segmentVariant;
segmentVariations.push(replaceWithFirst(variant));
}
}
variations = segmentVariations;
}
return variations
}
function generateSegmentVariations(segment) {
let variations = [segment];
for (const pattern in replacements) {
let index = 0;
while ((index = segment.indexOf(pattern, index)) !== -1) {
for (const replacement of replacements[pattern]) {
let variant = segment.slice(0, index) + replacement + segment.slice(index + pattern.length)
variations.push(replaceWithFirst(variant));
}
index += 1;
}
}
return variations;
}
function show_variants() {
let term = document.getElementById("input").value
term = term.replace(/'/g, "’").replace(/[^a-zA-Z'’.%]/g, "")
let temp_term = term.replace(/ng|ny|ni|sh|si|ch|chh|j/g, function(match) {
switch(match) {
case 'chh':
case 'ch':
case 'j':
return 'ʧ';
case 'ng':
return 'ŋ';
case 'ny':
...