UNPKG

shevchenko

Version:

JavaScript library for declension of Ukrainian anthroponyms

63 lines (59 loc) 2.22 kB
/** * @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} */ 'use strict'; 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;