shevchenko
Version:
JavaScript library for declension of Ukrainian anthroponyms
63 lines (59 loc) • 2.22 kB
JavaScript
/**
* @file JavaScript library for declension of Ukrainian anthroponyms
* @module shevchenko
* @version 3.1.4
* @author Oleksandr Tolochko <shevchenko-js@tooleks.com>
* @license MIT
* @copyright 2017-2025 Oleksandr Tolochko <shevchenko-js@tooleks.com>
* @see {@link git+https://github.com/tooleks/shevchenko-js.git}
*/
;
require('../language/alphabet.js');
require('../language/word-class.js');
require('../language/grammatical-case.js');
require('../language/grammatical-gender.js');
var letterCase = require('../language/letter-case.js');
var commandRunnerFactory = require('./command-runner-factory.js');
/**
* Counts a number of groups in a given regular expression.
*/
function countGroups(src) {
const pattern = new RegExp(`${src.toString()}|`);
const matches = pattern.exec('');
if (matches == null) {
return 0;
}
return matches.length - 1;
}
class DeclensionRuleInflector {
constructor(rule) {
this.rule = rule;
this.commandRunnerFactory = new commandRunnerFactory.CommandRunnerFactory();
}
/**
* Inflects the given word in the given grammatical case using the rule.
*/
inflect(word, grammaticalCase) {
const [commands] = this.rule.grammaticalCases[grammaticalCase];
if (commands) {
const searchValue = new RegExp(this.rule.pattern.modify, 'gi');
const inflectedWord = word.replace(searchValue, (match, ...groups) => {
let replacer = '';
const groupCount = countGroups(this.rule.pattern.modify);
for (let groupIndex = 0; groupIndex < groupCount; groupIndex += 1) {
let value = groups[groupIndex];
const command = commands[groupIndex];
if (command != null) {
value = this.commandRunnerFactory.make(command).exec(value);
}
replacer += value;
}
return replacer;
});
return letterCase.copyLetterCase(word, inflectedWord);
}
return word;
}
}
exports.DeclensionRuleInflector = DeclensionRuleInflector;
exports.countGroups = countGroups;