templural
Version:
Template function for plural-sensitive formatting
118 lines • 4.02 kB
JavaScript
"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