// Phonagen-web // Browser-based gerenator for phonagen outputs // Main object var phonagen = {} // Discrete distribution // The distribution object defines a discrete distribution phonagen.Distribution = function () { this.total = 0 // Total number of elements in the distribution this.items = new Map() // Map of item -> number of elements } // Add 'occur' number of 'elem' elements into the distribution phonagen.Distribution.prototype.addTo = function (elem, occur) { this.total += occur if (this.items.has(elem)) { this.items.set(elem, occur + this.items.get(elem)) } else { this.items.set(elem, occur) } } // Pick a random element from the distribution phonagen.Distribution.prototype.pickFrom = function () { var idx = Math.floor(Math.random() * this.total) var acc = 0 var pick = undefined for (var [elem, occur] of this.items) { acc += occur pick = elem if (acc > idx) { break } } return pick } // Chain generator // This generator makes an array of elements from a table of current chain -> next element phonagen.ChainGenerator = function (order) { this.order = order this.nextItems = new Map() } // Populate the table of next elements from a description phonagen.ChainGenerator.prototype.initializeFromDescription = function (description) { for (var elem of description) { var dist = new phonagen.Distribution() for (var next of elem['possible-outputs']) { dist.addTo(next.value, next.occurences) } this.nextItems.set(elem.input.toString(), dist) // note: toString() when setting and getting to be able to compare the arrays } } // Generate an array of elements phonagen.ChainGenerator.prototype.generate = function () { var next = function (cg, current, output) { var nextElem = cg.nextItems.get(current.toString()).pickFrom() if (nextElem === "") { return output } else { current.shift() current.push(nextElem) output.push(nextElem) return next(cg, current, output) } } var current = new Array() for (var i = 0; i < this.order; ++i) { current.push("") } return next(this, current, new Array()) } // Rule generator // This generator makes an array of elements from rules describing how to generate the array // Each rule is associated to a distribution of patterns indicating how to replace a rule identifier phonagen.RuleGenerator = function () { this.rules = new Map() } // Populate the rules table from a description phonagen.RuleGenerator.prototype.initializeFromDescription = function (description) { for (var rule of description) { var dist = new phonagen.Distribution() for (var pat of rule.distribution) { dist.addTo(pat.pattern, pat.occurences) } this.rules.set(rule.id, dist) } } // Generate an array of elements phonagen.RuleGenerator.prototype.generate = function () { var replacePattern = function (rules, input) { var output = new Array() for (var i of input) { if (rules.has(i)) { output = output.concat(replacePattern(rules, rules.get(i).pickFrom())) } else { output.push(i) } } return output } return replacePattern(this.rules, this.rules.get('word').pickFrom()) } // Model of the phonagen generator phonagen.model = {} // Generate a word from the generator id phonagen.generateWord = function () { var selector = document.getElementById('generator-selector') var generatorId = selector.options[selector.selectedIndex].value var generator = phonagen.model.generators.get(generatorId) document.getElementById('phonagen-output').innerHTML = generator.generate() } // Transform a list of phoneme ids to a formatted strings phonagen.formatWord = function (phonemes, phonology) { // Construct the different transcriptions var wordTranscriptions = new Map() for (var writing of phonology.transcriptions) { var word = "" for (var id of phonemes) { if (phonology.entries.has(id)) { word += phonology.entries.get(id)[writing] } } wordTranscriptions.set(writing, word) } // Construct what should be displayed var text = "
"
text += "" + wordTranscriptions.get(phonology.mainTranscription) + "
"
text += "Pronounciation: /" + wordTranscriptions.get("phoneme") +"/
"
for (var [writing, value] of wordTranscriptions) {
if ( (writing !== "phoneme")
&& (writing !== phonology.mainTranscription) ) {
text += "Translitteration (" + writing + "): " + value + "
"
}
}
text += "