UNPKG

templural

Version:

Template function for plural-sensitive formatting

118 lines 4.02 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ParsedTemplate = exports.parseChunk = exports.parseChunks = void 0; const lex_1 = require("./lex"); function parseChunks(chunks) { return chunks.map(parseChunk).reduce((tmpl, chunkTmpl, index) => [...tmpl, index - 1, ...chunkTmpl]); } exports.parseChunks = parseChunks; function parseChunk(chunk, chunkIndex) { return [...new Parser((0, lex_1.lex)(chunk), chunkIndex - 1)]; } exports.parseChunk = parseChunk; class Parser { constructor(tokens, defaultArgIndex) { this.pos = 0; this.tokens = tokens; this.defaultArgIndex = defaultArgIndex; } next() { if (this.token === undefined) return { done: true, value: null }; if (this.token === lex_1.Token.Type.LCurly) return { value: this.readGroup() }; return { value: this.readChunk() }; } readGroup() { const { pos } = this; this.nextPos(); const argIndex = this.readArgIndex(); const orderedResults = []; const associativeResults = {}; while (true) { const category = this.readCategory(); const result = this.readResult(); if (category == null) { orderedResults.push(result); } else { associativeResults[category] = result; } if (this.token === undefined) return this.readChunk(pos); if (this.token === lex_1.Token.Type.RCurly) break; this.nextPos(); } this.nextPos(); if (Object.keys(associativeResults).length !== 0) { if (orderedResults.length !== 0) throw SyntaxError('Ordered and associative syntaxes cannot be mixed'); return { argIndex, associativeResults }; } return { argIndex, orderedResults }; } readArgIndex() { if (!lex_1.Token.isInteger(this.token) || this.nextToken !== lex_1.Token.Type.Dollar) return this.defaultArgIndex; const argIndex = Number(this.token[1]) - 1; this.nextPos(); this.nextPos(); return argIndex; } readCategory() { if (!lex_1.Token.isString(this.token) || !isLDMLPluralRule(this.token[1]) || this.nextToken !== lex_1.Token.Type.Colon) return null; const category = this.token[1]; this.nextPos(); this.nextPos(); return category; } readResult() { const { pos } = this; while (this.token !== undefined && this.token !== lex_1.Token.Type.RCurly && this.token !== lex_1.Token.Type.SColon) { this.nextPos(); } return this.tokens .slice(pos, this.pos) .map(token => lex_1.Token.isString(token) || lex_1.Token.isInteger(token) ? token[1] : token) .join(''); } readChunk(pos = this.pos) { do { this.nextPos(); } while (this.token !== lex_1.Token.Type.LCurly && this.token != null); return this.tokens .slice(pos, this.pos) .map(token => lex_1.Token.isString(token) || lex_1.Token.isInteger(token) ? token[1] : token) .join(''); } nextPos() { this.pos++; } get token() { return this.tokens[this.pos]; } get nextToken() { return this.tokens[this.pos + 1]; } [Symbol.iterator]() { return this; } } function isLDMLPluralRule(s) { return s === 'one' || s === 'other' || s === 'zero' || s === 'two' || s === 'few' || s === 'many'; } var Template; (function (Template) { function isGroup(item) { return typeof item === 'object'; } Template.isGroup = isGroup; function isOrdredGroup(group) { return 'orderedResults' in group; } Template.isOrdredGroup = isOrdredGroup; })(Template || (Template = {})); exports.ParsedTemplate = Template; //# sourceMappingURL=parse.js.map