silegismg-interpretador-articulacao
Version:
Interpretador de Articulação
103 lines (102 loc) • 5.55 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.validarArticulacao = exports.Validacao = void 0;
const agrupadores_1 = require("./dispositivos/agrupadores");
const Dispositivo_1 = require("./dispositivos/Dispositivo");
const transformarNumeros_1 = require("./util/transformarNumeros");
class Validacao {
constructor(dispositivo, formatacaoNumerica, sequenciaNumerica, derivacoesValidas, conteudo) {
this.dispositivo = dispositivo;
this.formatacaoNumerica = formatacaoNumerica;
this.sequenciaNumerica = sequenciaNumerica;
this.derivacoesValidas = derivacoesValidas;
this.conteudo = conteudo;
}
get valido() {
return this.formatacaoNumerica && this.sequenciaNumerica && this.derivacoesValidas
&& this.conteudo;
}
}
exports.Validacao = Validacao;
function validarArticulacao(dispositivosOriginais, opcoes = {}) {
let ultimoArtigo;
function _validarArticulacao(dispositivos) {
const ultimos = {
get artigo() { return ultimoArtigo; },
set artigo(artigo) { ultimoArtigo = artigo; }
};
if (!opcoes.formatacaoEsperada) {
opcoes.formatacaoEsperada = {};
}
const dispositivosInvalidos = [];
dispositivos.forEach((dispositivo, idx) => {
const tipo = dispositivo.tipo;
const formatacao = (0, transformarNumeros_1.inferirFormatacao)(dispositivo.numero);
const validacaoSequencia = verificarNumeracao(dispositivo, ultimos[tipo], formatacao);
ultimos[tipo] = dispositivo;
const subvalidacao = _validarArticulacao(dispositivo.subitens);
const validacaoFormatacaoNumerica = !opcoes.formatacaoEsperada[tipo]
|| opcoes.formatacaoEsperada[tipo] === formatacao
|| formatacao === transformarNumeros_1.FormatacaoNumerica.PARAGRAFO_UNICO;
const validacao = new Validacao(dispositivo, validacaoFormatacaoNumerica, validacaoSequencia.sequenciaNumericaValida, subvalidacao.length === 0, validarConteudo(dispositivo, dispositivos[idx + 1] || obterProximoDispositivo(dispositivo), opcoes.escapes || []));
// Parágrafo único não é considerado como formatação esperada
if (formatacao !== transformarNumeros_1.FormatacaoNumerica.PARAGRAFO_UNICO) {
opcoes.formatacaoEsperada[tipo] = formatacao;
}
dispositivosInvalidos.push(...subvalidacao);
if (!validacao.valido) {
dispositivosInvalidos.push(validacao);
}
});
return dispositivosInvalidos;
}
return _validarArticulacao(dispositivosOriginais);
}
exports.validarArticulacao = validarArticulacao;
function verificarNumeracao(dispositivo, anterior, formatacao) {
const mEmenda = /^(.+?)-([a-z])$/i.exec(dispositivo.numero || '');
let sequenciaNumericaValida;
if (mEmenda) {
const mEmendaAnterior = anterior ? /^(.+?)(?:-([a-z]))?$/i.exec(anterior.numero || '') : null;
sequenciaNumericaValida = !!mEmendaAnterior && mEmenda[1] === mEmendaAnterior[1] &&
(!mEmendaAnterior[2] && mEmenda[2].toUpperCase() === 'A' ||
!!mEmendaAnterior[2] && mEmenda[2].charCodeAt(0) === mEmendaAnterior[2].charCodeAt(0) + 1);
}
else {
const proximoNumero = anterior ? (0, transformarNumeros_1.interpretarNumero)(anterior.numero, formatacao) + 1 : 1;
sequenciaNumericaValida = dispositivo.numero === (0, transformarNumeros_1.formatar)(proximoNumero, formatacao) ||
!!anterior && !!anterior.numero && !!dispositivo.numero &&
(formatacao === transformarNumeros_1.FormatacaoNumerica.ALFABETO_MINUSCULO ||
formatacao === transformarNumeros_1.FormatacaoNumerica.ALFABETO_MAIUSCULO) && ((0, transformarNumeros_1.interpretarLetra)(dispositivo.numero) !== (0, transformarNumeros_1.interpretarLetra)(anterior.numero) + 1 &&
(0, transformarNumeros_1.interpretarLetra)(dispositivo.numero, false) === (0, transformarNumeros_1.interpretarLetra)(anterior.numero, false) + 1);
}
return {
sequenciaNumericaValida,
emendado: !!mEmenda
};
}
function validarConteudo(dispositivo, proximo, escapes) {
const conteudoParaValidacao = escapes.reduce((prev, cur) => cur.escapar(prev, () => ''), dispositivo.descricao)
.replace(/\(.+?\)|\n+|\r+/g, '').trim();
if (dispositivo instanceof agrupadores_1.Divisao) {
return /^[^.:!?]+$/.test(conteudoParaValidacao);
}
if (dispositivo.subitens.length > 0 && (dispositivo.tipo !== Dispositivo_1.TipoDispositivo.ARTIGO ||
dispositivo.subitens[0].tipo === Dispositivo_1.TipoDispositivo.INCISO)) {
return conteudoParaValidacao.length > 1 && conteudoParaValidacao.endsWith(':');
}
return conteudoParaValidacao.length > 1 && (conteudoParaValidacao.endsWith('.') ||
(!!proximo && conteudoParaValidacao.endsWith(';')
&& proximo.tipo !== Dispositivo_1.TipoDispositivo.ARTIGO) ||
/".+"$|“.+”$/.test(conteudoParaValidacao)) ||
/^\(?(?:VETAD[OA]|REVOGAD[OA])\)?\.?/i.test(conteudoParaValidacao);
}
function obterProximoDispositivo(dispositivo) {
for (let pai = dispositivo.$parent; pai; dispositivo = pai, pai = pai.$parent) {
const idx = pai.subitens.findIndex((item) => item === dispositivo) + 1;
if (pai.subitens.length > idx) {
return pai.subitens[idx];
}
}
return null;
}