UNPKG

brogue

Version:

A Grammar based generative text library based on Tracery.

203 lines (202 loc) 6.41 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getBuiltInModifier = void 0; /* eslint-disable no-unused-vars */ const compromise_1 = __importDefault(require("compromise")); const articles_1 = __importDefault(require("articles")); const num_words_1 = __importDefault(require("num-words")); const expand_1 = require("./expand"); function _isVowel(s) { return s === 'a' || s === 'e' || s === 'i' || s === 'o' || s === 'u' || s === 'y' || s === 'A' || s === 'E' || s === 'I' || s === 'O' || s === 'U' || s === 'Y'; } function _isConsonant(s) { return !_isVowel(s); } function _funcCapitalize(s, _) { return s.charAt(0).toUpperCase() + s.slice(1); } function _funcCapitalizeAll(s, _) { return s.replace(/(?:^|\s)\S/g, (a) => { return a.toUpperCase(); }); } function _funcQuotes(s, _) { return `"${s}"`; } function _funcTimes(s, _, n) { if (n === undefined || Number.isNaN(n) || typeof n !== 'number') { throw new Error('Expected number parameter. Ex: times(3)'); } return Array(n).fill(s).join(' '); } function _funcArtical(s, _) { return articles_1.default.articlize(s); } function _funcPluralize(s, _) { return compromise_1.default(s).tag("#Noun").nouns() .toPlural() .text(); } function _funcSingularize(s, _) { return compromise_1.default(s).tag("#Noun").nouns() .toSingular() .text(); } function _funcPossessive(s, _) { return compromise_1.default(s).tag("#Noun").nouns() .toPossessive() .text(); } function _funcPastTense(s, _) { return compromise_1.default(s).tag("#Verb").verbs() .toPastTense() .text(); } function _funcPresentTense(s, _) { return compromise_1.default(s).tag("#Verb").verbs() .toPresentTense() .text(); } function _funcFutureTense(s, _) { return compromise_1.default(s).tag("#Verb").verbs() .toFutureTense() .text(); } function _funcGerund(s, _) { return compromise_1.default(s).tag("#Verb").verbs() .toGerund() .text(); } function _funcInfinitive(s, _) { return compromise_1.default(s).tag("#Verb").verbs() .toInfinitive() .text(); } function _funcPositive(s, _) { return compromise_1.default(s).tag("#Verb").verbs() .toPositive() .text(); } function _funcNegative(s, _) { return compromise_1.default(s).tag("#Verb").verbs() .toNegative() .text(); } function _funcNounify(s, context) { const infinitive = _funcInfinitive(s, context); const lastChar = infinitive.charAt(infinitive.length - 1); if (lastChar === 'e') { return `${infinitive}r`; } let vowelCount = 0; for (let i = 0; i < s.length; ++i) { vowelCount += _isVowel(s[i]) ? 1 : 0; } // Double final consonant if: // word is 1 syllable // has 1 vowel // and has a consonant that follows the vowel if (_isConsonant(lastChar) && lastChar !== 'x' && vowelCount === 1 && _isVowel(infinitive.charAt(infinitive.length - 2)) && infinitive.length < 5) { return `${infinitive.slice(0, -1) + lastChar + lastChar}er`; } return `${infinitive}er`; } function _funcRandomNumber(_, context, minString = '0', maxString = '99') { const min = parseInt(minString, 10); const max = parseInt(maxString, 10); return context.grammar.random.intBetween(min, max).toString(); } function _funcRoll(_, context, rollString) { if (!rollString) { throw new Error(`Tried to invoke roll() without argument`); } const matches = rollString.match(/(?<num>\d+)d(?<sides>\d+)(?:(?:\s?\+\s?(?<plus>\d+))|(?:\s?-\s?(?<minus>\d+)))?/); if (!matches || !matches.groups?.num || !matches.groups?.sides) { throw new Error(`Failed to parse die roll string: ${rollString}`); } const num = parseInt(matches.groups.num, 10); const sides = parseInt(matches.groups.sides, 10); let val = 0; for (let i = 0; i < num; ++i) { val += context.grammar.random.intBetween(1, sides); } if (matches.groups.plus) { val += parseInt(matches.groups.plus, 10); } if (matches.groups.minus) { val -= parseInt(matches.groups.minus, 10); } return val.toString(); } function _funcUniques(_, context, ruleName, num, separator = " ") { const rule = context.grammar.rules.get(ruleName); if (!rule) { throw new Error(`Failed to call modifier 'uniques'. Rule {ruleName} not found in loaded grammar.`); } const picks = []; context.pushUniqueTracker(); const maxTries = 10; let tries = 0; while (picks.length < num && tries++ < maxTries) { const lexeme = expand_1.pickLexeme(rule, context); if (!lexeme) { break; } const expanded = expand_1.expandLexeme(lexeme, context, true); if (expanded === undefined) { continue; } if (!picks.includes(expanded)) { picks.push(expanded); } } context.popUniqueTracker(); return picks.join(separator); } function _funcNumberToWords(s, _) { const parsed = parseInt(s, 10); if (isNaN(parsed)) { return s; } return num_words_1.default(parsed); } function _funcChoose(_, context, ...args) { const string = args[context.grammar.random.range(args.length)].toString(); return expand_1.expand(context.grammar, string); } const builtInModifiers = new Map(Object.entries({ // Lexical capitalize: _funcCapitalize, capitalizeall: _funcCapitalizeAll, quotes: _funcQuotes, times: _funcTimes, a: _funcArtical, s: _funcPluralize, singular: _funcSingularize, past: _funcPastTense, present: _funcPresentTense, future: _funcFutureTense, ing: _funcGerund, infinitive: _funcInfinitive, nounify: _funcNounify, possessive: _funcPossessive, positive: _funcPositive, negative: _funcNegative, numberToWords: _funcNumberToWords, // Genrative randomNumber: _funcRandomNumber, roll: _funcRoll, uniques: _funcUniques, choose: _funcChoose, })); function getBuiltInModifier(name) { return builtInModifiers.get(name); } exports.getBuiltInModifier = getBuiltInModifier;