silegismg-interpretador-articulacao
Version:
Interpretador de Articulação
170 lines (169 loc) • 6.34 kB
JavaScript
;
/* Copyright 2019 Assembleia Legislativa de Minas Gerais
*
* This file is part of Interpretador-Articulacao.
*
* Interpretador-Articulacao is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* Interpretador-Articulacao is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Interpretador-Articulacao. If not, see <http://www.gnu.org/licenses/>.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.formatar = exports.interpretarNumero = exports.inferirFormatacao = exports.FormatacaoNumerica = exports.interpretarLetra = exports.transformarLetra = exports.interpretarNumeroRomano = exports.transformarNumeroRomano = void 0;
/**
* Escreve o número em romano.
*
* @param {Number} numero
*/
function transformarNumeroRomano(numero) {
const digitos = String(numero).split('');
const tabela = ['', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM',
'', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC',
'', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'];
let resultado = '';
let i = 3;
while (i--) {
resultado = (tabela[+digitos.pop() + (i * 10)] || '') + resultado;
}
return new Array(+digitos.join('') + 1).join('M') + resultado;
}
exports.transformarNumeroRomano = transformarNumeroRomano;
/**
* Interpreta o número romano, transformando-o em arábico.
*
* @param romano Número romano.
*/
function interpretarNumeroRomano(romano) {
romano = romano.toUpperCase().replace(/ +/g, '');
let soma = 0;
let i = 0;
const mapa = { M: 1000, D: 500, C: 100, L: 50, X: 10, V: 5, I: 1 };
if (/^[MDCLXVI]+$/.test(romano)) {
while (i < romano.length) {
let valor = mapa[romano.charAt(i++)];
const proximo = mapa[romano.charAt(i)] || 0;
if (proximo - valor > 0) {
valor *= -1;
}
soma += valor;
}
return soma;
}
return NaN;
}
exports.interpretarNumeroRomano = interpretarNumeroRomano;
/**
* Escreve o número em letra.
*
* @param {Number} numero
*/
function transformarLetra(numero, maiuscula = false) {
if (numero < 1) {
throw new Error('Número deve ser positivo.');
}
return String.fromCharCode((maiuscula ? 64 : 96) + numero);
}
exports.transformarLetra = transformarLetra;
/**
* Interpreta a letra.
*
* @param letra Letra a ser interpretada.
* @param alfabetoCompleto Por padrão, assume o alfabeto completo. Entretanto,
* é possível interpretar desconsiderando as letras "k", "w" e "y" na numeração
* sequencial.
*/
function interpretarLetra(letra, alfabetoCompleto = true) {
const codigo = letra.toLowerCase().charCodeAt(0);
if (alfabetoCompleto || codigo <= 107 /* k */) {
return codigo - 96;
}
else if (codigo <= 119 /* w */) {
return codigo - 97;
}
else if (codigo <= 121 /* y */) {
return codigo - 98;
}
else {
return codigo - 99;
}
}
exports.interpretarLetra = interpretarLetra;
var FormatacaoNumerica;
(function (FormatacaoNumerica) {
FormatacaoNumerica[FormatacaoNumerica["NENHUMA"] = 0] = "NENHUMA";
FormatacaoNumerica[FormatacaoNumerica["ARABICO"] = 1] = "ARABICO";
FormatacaoNumerica[FormatacaoNumerica["ROMANO"] = 2] = "ROMANO";
FormatacaoNumerica[FormatacaoNumerica["ALFABETO_MINUSCULO"] = 3] = "ALFABETO_MINUSCULO";
FormatacaoNumerica[FormatacaoNumerica["ALFABETO_MAIUSCULO"] = 4] = "ALFABETO_MAIUSCULO";
FormatacaoNumerica[FormatacaoNumerica["PARAGRAFO_UNICO"] = 5] = "PARAGRAFO_UNICO";
})(FormatacaoNumerica || (exports.FormatacaoNumerica = FormatacaoNumerica = {}));
function inferirFormatacao(numero) {
if (!numero) {
return FormatacaoNumerica.NENHUMA;
}
if (/^\d/.test(numero)) {
return FormatacaoNumerica.ARABICO;
}
if (numero.localeCompare('Parágrafo único', 'pt-BR', { sensitivity: 'base' }) === 0) {
return FormatacaoNumerica.PARAGRAFO_UNICO;
}
if (/^[a-z]/.test(numero)) {
return FormatacaoNumerica.ALFABETO_MINUSCULO;
}
if (/^[IVXLCDM]+(?:-[A-Za-z])?$/.test(numero)) {
return FormatacaoNumerica.ROMANO;
}
if (/^[A-Z]/.test(numero)) {
return FormatacaoNumerica.ALFABETO_MAIUSCULO;
}
throw new Error(`Não foi possível identificar a formatação numérica para ${numero}.`);
}
exports.inferirFormatacao = inferirFormatacao;
function interpretarNumero(numero, formatacao) {
if (numero === null) {
return 0;
}
[numero] = numero.split('-', 1);
switch (formatacao || inferirFormatacao(numero)) {
case FormatacaoNumerica.NENHUMA:
return 0;
case FormatacaoNumerica.ARABICO:
return parseInt(numero);
case FormatacaoNumerica.PARAGRAFO_UNICO:
return 1;
case FormatacaoNumerica.ALFABETO_MAIUSCULO:
case FormatacaoNumerica.ALFABETO_MINUSCULO:
return interpretarLetra(numero);
case FormatacaoNumerica.ROMANO:
return interpretarNumeroRomano(numero);
default:
throw new Error('Formatação desconhecida: ' + formatacao);
}
}
exports.interpretarNumero = interpretarNumero;
function formatar(numero, formatacao) {
switch (formatacao) {
case FormatacaoNumerica.NENHUMA:
return null;
case FormatacaoNumerica.ARABICO:
return numero.toString();
case FormatacaoNumerica.ROMANO:
return transformarNumeroRomano(numero);
case FormatacaoNumerica.ALFABETO_MINUSCULO:
return transformarLetra(numero, false);
case FormatacaoNumerica.ALFABETO_MAIUSCULO:
return transformarLetra(numero, true);
case FormatacaoNumerica.PARAGRAFO_UNICO:
return 'Parágrafo único';
default:
throw new Error('Formatação desconhecida: ' + formatacao);
}
}
exports.formatar = formatar;