UNPKG

silegismg-interpretador-articulacao

Version:
170 lines (169 loc) 6.34 kB
"use strict"; /* 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;