UNPKG

shevchenko

Version:

JavaScript library for declension of Ukrainian anthroponyms

60 lines (57 loc) 2.13 kB
/** * @file JavaScript library for declension of Ukrainian anthroponyms * @module shevchenko * @version 3.2.2 * @author Oleksandr Tolochko <shevchenko-js@tooleks.com> * @license MIT * @copyright 2017-2026 Oleksandr Tolochko <shevchenko-js@tooleks.com> * @see {@link git+https://github.com/tooleks/shevchenko-js.git} */ import '../language/alphabet.js'; import '../language/word-class.js'; import '../language/grammatical-case.js'; import '../language/grammatical-gender.js'; import { copyLetterCase } from '../language/letter-case.js'; import { CommandRunnerFactory } from './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(); } /** * 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 copyLetterCase(word, inflectedWord); } return word; } } export { DeclensionRuleInflector, countGroups };