UNPKG

silegismg-interpretador-articulacao

Version:
125 lines (124 loc) 6.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const EscapeInterpretacao_1 = __importDefault(require("./EscapeInterpretacao")); const EscapeSimboloEscape_1 = __importDefault(require("./impl/EscapeSimboloEscape")); /** * Processa um texto, omitindo trechos que não devem fazer parte do processamento. */ class Escapamento { /** * Prepara o processamento, escapando o texto. * * @param textoOriginal Texto a ser processado. * @param escapesExtras Escapadores a serem utilizados. */ constructor(textoOriginal, ...escapesExtras) { this.contexto = null; this.escapes = []; const escapadores = [new EscapeSimboloEscape_1.default(), ...escapesExtras]; /* * Para cada citação, isto é, texto entre aspas, substitui-se o seu conteúdo * por \0 e o conteúdo substituído é inserido na pilha de aspas, para evitar * que o conteúdo seja também interpretado. * * Desta maneira, de forma transparente, por meio do método processar, é * possível iterar por todas linhas sem o conteúdo escapado para realizar * o devido processamento textual. */ this.textoEscapado = escapadores.reduce((prev, cur) => { const escapesAnteriores = [...this.escapes]; /** * Determina o índice em que deve inserir o escape de forma ordenada * no contexto. */ let idxAdicaoVetorEscape = 0; return cur.escapar(prev, (trecho, idx) => { // Ajusta o índice à posição no texto original considerando os escapamentos anteriores. for (let i = 0; i < escapesAnteriores.length && escapesAnteriores[i].idx <= idx; i++) { idx += escapesAnteriores[i].trecho.length - EscapeInterpretacao_1.default.ESCAPE.length; } // Substitui todos os escapes contidos dentro deste novo escape pelo texto original. let idxBaseRestauracao = idx; trecho = trecho.replace(EscapeInterpretacao_1.default.ESCAPES_REGEXP, (escape, idxARestaurar) => { const idxCorrigido = idxARestaurar + idxBaseRestauracao; const aRemover = this.escapes.findIndex((item) => item.idx === idxCorrigido); if (aRemover === -1) { throw new Error('Falha durante escapamento.'); } const [escapeAnterior] = this.escapes.splice(aRemover, 1); idxBaseRestauracao += escapeAnterior.trecho.length - EscapeInterpretacao_1.default.ESCAPE.length; return escapeAnterior.trecho; }); while (idxAdicaoVetorEscape > 0 && this.escapes[idxAdicaoVetorEscape].idx > idx) { idxAdicaoVetorEscape--; } while (this.escapes.length > idxAdicaoVetorEscape && this.escapes[idxAdicaoVetorEscape].idx < idx) { idxAdicaoVetorEscape++; } this.escapes.splice(idxAdicaoVetorEscape, 0, { trecho: trecho, idx }); return EscapeInterpretacao_1.default.ESCAPE; }); }, textoOriginal); } *processar() { for (const trecho of this.textoEscapado.split('\n')) { if (this.escapes.length === 0) { this.contexto = { trechoComEscapes: trecho, escapou: false, trechoSemEscapes: trecho }; } else { const trechoSemEscapes = trecho.replace(EscapeInterpretacao_1.default.ESCAPES_REGEXP, ''); this.contexto = { trechoComEscapes: trecho, trechoSemEscapes, escapou: trechoSemEscapes.length !== trecho.length }; } yield this.contexto.trechoSemEscapes; } } desfazerEscapes(trecho) { if (!this.contexto) { throw new Error('Contexto de escapamento está nulo.'); } try { if (!this.contexto.escapou) { return trecho !== null && trecho !== void 0 ? trecho : this.contexto.trechoComEscapes; } else if (trecho === undefined) { return this.contexto.trechoComEscapes.replace(EscapeInterpretacao_1.default.ESCAPES_REGEXP, () => this.escapes.shift().trecho); } else { let idxTrecho = this.contexto.trechoSemEscapes.indexOf(trecho); let idxEscape; let nEscapesAnteriores = 0; // Ajusta o índice da descrição, para torná-la relativa à linha com escapes. for (idxEscape = this.contexto.trechoComEscapes.indexOf(EscapeInterpretacao_1.default.ESCAPE); idxEscape !== -1 && idxEscape <= idxTrecho; idxEscape = this.contexto.trechoComEscapes.indexOf(EscapeInterpretacao_1.default.ESCAPE, idxEscape + EscapeInterpretacao_1.default.ESCAPE.length)) { idxTrecho += EscapeInterpretacao_1.default.ESCAPE.length; nEscapesAnteriores++; } // Ajusta o índice da descrição para escapes imediatamente anterior a ela. while (nEscapesAnteriores > 0 && this.contexto.trechoComEscapes.lastIndexOf(EscapeInterpretacao_1.default.ESCAPE, idxTrecho - 1) + EscapeInterpretacao_1.default.ESCAPE.length === idxTrecho) { idxTrecho -= EscapeInterpretacao_1.default.ESCAPE.length; nEscapesAnteriores--; } // Remove os escapes do rótulo. while (nEscapesAnteriores-- > 0) { this.escapes.shift(); } return this.contexto.trechoComEscapes.substring(idxTrecho).replace(EscapeInterpretacao_1.default.ESCAPES_REGEXP, () => this.escapes.shift().trecho); } } finally { this.contexto = null; } } } exports.default = Escapamento;