d11 theme
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

126 lines
4.6 KiB

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.importTrie = exports.serializeTrie = exports.DATA = void 0;
const TrieNode_1 = require("./TrieNode");
const gensequence_1 = require("gensequence");
const convertToTrieRefNodes_1 = require("./convertToTrieRefNodes");
const EOW = '*';
exports.DATA = EOW;
function toReferences(node) {
return gensequence_1.genSequence(convertToTrieRefNodes_1.convertToTrieRefNodes(node));
}
const regExpEscapeChars = /([[\]\\,:{}*])/g;
const regExTrailingComma = /,(\}|\n)/g;
function escapeChar(char) {
return char.replace(regExpEscapeChars, '\\$1'); // lgtm[js/incomplete-sanitization]
}
function trieToExportString(node, base) {
function* walk(node) {
if (node.f) {
yield EOW;
}
if (node.r) {
const refs = [...node.r].sort((a, b) => (a[0] < b[0] ? -1 : 1));
for (const n of refs) {
const [c, r] = n;
const ref = r ? r.toString(base) : '';
yield escapeChar(c) + ref + ',';
}
}
}
return gensequence_1.genSequence(walk(node));
}
function generateHeader(base, comment) {
const header = ['#!/usr/bin/env cspell-trie reader', 'TrieXv1', 'base=' + base]
.concat(comment ? comment.split('\n').map((a) => '# ' + a) : [])
.concat(['# Data:']);
return gensequence_1.genSequence(header).map((a) => a + '\n');
}
/**
* Serialize a TrieNode.
* Note: This is destructive. The node will no longer be usable.
* Even though it is possible to preserve the trie, dealing with very large tries can consume a lot of memory.
* Considering this is the last step before exporting, it was decided to let this be destructive.
*/
function serializeTrie(root, options = 16) {
options = typeof options === 'number' ? { base: options } : options;
const { base = 16, comment = '' } = options;
const radix = base > 36 ? 36 : base < 10 ? 10 : base;
const rows = toReferences(root).map((node) => {
const row = [...trieToExportString(node, radix), '\n'].join('').replace(regExTrailingComma, '$1');
return row;
});
return generateHeader(radix, comment).concat(rows);
}
exports.serializeTrie = serializeTrie;
function* toIterableIterator(iter) {
yield* iter;
}
function importTrie(linesX) {
let radix = 16;
const comment = /^\s*#/;
const iter = toIterableIterator(linesX);
function parseHeaderRows(headerRows) {
const header = headerRows.slice(0, 2).join('\n');
const headerReg = /^TrieXv1\nbase=(\d+)$/;
/* istanbul ignore if */
if (!headerReg.test(header))
throw new Error('Unknown file format');
radix = Number.parseInt(header.replace(headerReg, '$1'), 10);
}
function readHeader(iter) {
const headerRows = [];
// eslint-disable-next-line no-constant-condition
while (true) {
const next = iter.next();
if (next.done) {
break;
}
const line = next.value.trim();
if (!line || comment.test(line)) {
continue;
}
if (line === exports.DATA) {
break;
}
headerRows.push(line);
}
parseHeaderRows(headerRows);
}
const regNotEscapedCommas = /(^|[^\\]),/g;
const regUnescapeCommas = /__COMMA__/g;
const regUnescape = /[\\](.)/g;
const flagsWord = { f: TrieNode_1.FLAG_WORD };
function splitLine(line) {
const pattern = '$1__COMMA__';
return line
.replace(regNotEscapedCommas, pattern)
.split(regUnescapeCommas)
.map((a) => a.replace(regUnescape, '$1'));
}
function decodeLine(line, nodes) {
const isWord = line[0] === EOW;
line = isWord ? line.slice(1) : line;
const flags = isWord ? flagsWord : {};
const children = splitLine(line)
.filter((a) => !!a)
.map((a) => [a[0], Number.parseInt(a.slice(1) || '0', radix)])
.map(([k, i]) => [k, nodes[i]]);
const cNode = children.length ? { c: new TrieNode_1.ChildMap(children) } : {};
return { ...cNode, ...flags };
}
readHeader(iter);
const n = gensequence_1.genSequence([exports.DATA])
.concat(iter)
.map((a) => a.replace(/\r?\n/, ''))
.filter((a) => !!a)
.reduce((acc, line) => {
const { lines, nodes } = acc;
const root = decodeLine(line, nodes);
nodes[lines] = root;
return { lines: lines + 1, root, nodes };
}, { lines: 0, nodes: [], root: {} });
return n.root;
}
exports.importTrie = importTrie;
//# sourceMappingURL=importExportV1.js.map