Saltar al contenido
← Volver

legal-expand: Cómo convertir AEAT, IVA, IRPF en texto que tu cliente pueda entender

8 min de lectura
TypeScriptPythonNPMPyPILegal TechNLP

Los textos legales españoles están plagados de siglas que solo entienden los abogados. AEAT, IRPF, LEC, CGPJ, BOE. Tu cliente lee una sentencia y no entiende nada. Esta librería expande automáticamente 646 siglas jurídicas verificadas por la RAE, añadiendo el significado entre paréntesis. Disponible para NPM y Python, con soporte para HTML semántico y salida estructurada.

Tu cliente recibe una notificación de Hacienda. Lee: “La AEAT, en aplicación del art. 108 de la LGT, requiere la presentación de la declaración del IRPF correspondiente al ejercicio fiscal, conforme al RD 1065/2007 y la LIRPF”. Te llama preguntando qué significa eso. Pasas diez minutos explicando que AEAT es la Agencia Tributaria, que LGT es la Ley General Tributaria, que IRPF es el impuesto de la renta, que RD es Real Decreto, y que LIRPF es la Ley del IRPF.

Este escenario se repite constantemente en despachos de abogados, gestorías, y departamentos legales. Los textos jurídicos españoles usan siglas para todo: instituciones, leyes, impuestos, tribunales, procedimientos. Un texto de dos páginas puede tener treinta siglas diferentes. Para un profesional del derecho son obvias. Para el resto del mundo son jeroglíficos.

El problema no es solo la comprensión del cliente. También afecta a sistemas automatizados. Si usas un LLM para analizar documentos legales, el modelo puede no conocer qué significa CGPJ o TSJC. Si indexas sentencias para búsqueda, las siglas sin expandir dificultan encontrar resultados relevantes. Si generas resúmenes automáticos, las siglas se copian tal cual sin contexto.

La solución: expandir siglas automáticamente

La idea es simple. Tomas un texto con siglas y lo transformas en un texto donde cada sigla tiene su significado entre paréntesis:

Entrada:

La AEAT notifica el IVA

Salida:

La AEAT (Agencia Estatal de Administración Tributaria) notifica el IVA (Impuesto sobre el Valor Añadido)

El texto sigue siendo el mismo pero ahora cualquiera puede entenderlo. El cliente lee “AEAT” y al lado tiene “(Agencia Estatal de Administración Tributaria)”. No necesita buscar en Google ni preguntarte qué significa.

legal-expand hace exactamente esto. Es una librería que contiene 646 siglas jurídicas españolas verificadas con fuentes oficiales. Le pasas un texto, te devuelve el texto con las siglas expandidas. Disponible para NPM (TypeScript/JavaScript) y PyPI (Python).

Instalación

Para proyectos Node.js:

npm install legal-expand

Para proyectos Python:

pip install legal-expand

Ambas versiones tienen la misma funcionalidad y API equivalente.

Uso básico

En TypeScript/JavaScript:

import { expandirSiglas } from 'legal-expand';

const texto = 'La AEAT notifica el IVA';
const resultado = expandirSiglas(texto);
// 'La AEAT (Agencia Estatal de Administración Tributaria) notifica el IVA (Impuesto sobre el Valor Añadido)'

En Python:

from legal_expand import expandir_siglas

texto = 'La AEAT notifica el IVA'
resultado = expandir_siglas(texto)
# 'La AEAT (Agencia Estatal de Administración Tributaria) notifica el IVA (Impuesto sobre el Valor Añadido)'

La función detecta las siglas en el texto, busca su significado en el diccionario, y añade la expansión entre paréntesis después de cada sigla.

Detección inteligente de variantes

Las siglas en textos reales aparecen escritas de formas diferentes. A veces con puntos, a veces sin ellos, a veces en mayúsculas, a veces con la primera letra en mayúscula. La librería reconoce todas las variantes:

expandirSiglas('La AEAT requiere...');    // Detecta AEAT
expandirSiglas('La A.E.A.T. requiere...'); // Detecta A.E.A.T.
expandirSiglas('La A.E.A.T requiere...');  // Detecta A.E.A.T
expandirSiglas('La Aeat requiere...');     // Detecta Aeat

Todas estas variantes se expanden correctamente al mismo significado. No tienes que normalizar el texto antes de procesarlo.

Formatos de salida

La librería soporta tres formatos de salida según el caso de uso.

Texto plano (por defecto)

Añade la expansión entre paréntesis después de cada sigla. Es el formato más simple y funciona para cualquier contexto.

expandirSiglas('El BOE publica la LEC');
// 'El BOE (Boletín Oficial del Estado) publica la LEC (Ley de Enjuiciamiento Civil)'

HTML semántico

Usa etiquetas <abbr> con el atributo title. En navegadores, el usuario puede pasar el ratón sobre la sigla y ver el significado en un tooltip nativo.

expandirSiglas('El BOE publica la LEC', { format: 'html' });
// 'El <abbr title="Boletín Oficial del Estado">BOE</abbr> (Boletín Oficial del Estado) publica la <abbr title="Ley de Enjuiciamiento Civil">LEC</abbr> (Ley de Enjuiciamiento Civil)'

Este formato es ideal para aplicaciones web donde quieres mantener el texto limpio visualmente pero ofrecer información adicional al usuario.

Salida estructurada

Devuelve un objeto con el texto expandido, la lista de siglas encontradas, y estadísticas del procesamiento. Útil para análisis o cuando necesitas acceso programático a las siglas detectadas.

const resultado = expandirSiglas('El BOE publica la LEC', { format: 'structured' });

// resultado.expandedText: 'El BOE (...) publica la LEC (...)'
// resultado.acronyms: [
//   { acronym: 'BOE', expansion: 'Boletín Oficial del Estado', position: 3 },
//   { acronym: 'LEC', expansion: 'Ley de Enjuiciamiento Civil', position: 20 }
// ]
// resultado.stats: { total: 2, expanded: 2, skipped: 0 }

En Python, la salida estructurada devuelve un objeto StructuredOutput con propiedades equivalentes.

Expandir solo la primera ocurrencia

En documentos largos, expandir cada aparición de una sigla genera textos repetitivos e incómodos de leer. Si un documento de veinte páginas menciona “AEAT” cincuenta veces, no quieres ver “(Agencia Estatal de Administración Tributaria)” cincuenta veces.

La opción expandOnlyFirst expande solo la primera aparición de cada sigla:

const texto = 'La AEAT notifica. La AEAT requiere. La AEAT informa.';

expandirSiglas(texto, { expandOnlyFirst: true });
// 'La AEAT (Agencia Estatal de Administración Tributaria) notifica. La AEAT requiere. La AEAT informa.'

La primera vez que aparece AEAT se expande. Las siguientes apariciones se dejan tal cual. Es el comportamiento estándar en textos técnicos y jurídicos donde las siglas se definen una vez al principio.

Excluir e incluir siglas específicas

A veces quieres controlar qué siglas se expanden. Quizás tu cliente ya sabe qué es el IVA pero no conoce el resto de siglas. O quizás estás procesando un texto donde ciertas siglas tienen significados específicos del contexto.

Para excluir siglas:

expandirSiglas('La AEAT notifica el IVA', { exclude: ['IVA'] });
// 'La AEAT (Agencia Estatal de Administración Tributaria) notifica el IVA'

Para expandir solo siglas específicas:

expandirSiglas('La AEAT notifica el IVA y el IRPF', { include: ['AEAT'] });
// 'La AEAT (Agencia Estatal de Administración Tributaria) notifica el IVA y el IRPF'

Siglas con múltiples significados

Algunas siglas tienen más de un significado. DGT puede ser “Dirección General de Tributos” o “Dirección General de Tráfico”. AN puede ser “Audiencia Nacional” o “Acuerdo de Nación”. El contexto determina cuál es correcto, pero la librería no puede inferirlo automáticamente.

Por defecto, las siglas con múltiples significados no se expanden para evitar errores:

expandirSiglas('La DGT comunica...');
// 'La DGT comunica...' (no se expande porque DGT tiene múltiples significados)

Puedes consultar qué significados tiene una sigla:

import { buscarSigla } from 'legal-expand';

const info = buscarSigla('DGT');
// {
//   found: true,
//   meanings: [
//     'Dirección General de Tributos',
//     'Dirección General de Tráfico'
//   ],
//   hasDuplicates: true
// }

Para resolver manualmente qué significado usar:

expandirSiglas('La DGT comunica...', {
  duplicateResolution: {
    'DGT': 'Dirección General de Tráfico'
  }
});
// 'La DGT (Dirección General de Tráfico) comunica...'

También puedes activar la resolución automática, que usa el significado más común según frecuencia de uso:

expandirSiglas('La DGT comunica...', { autoResolveDuplicates: true });
// Expande usando el significado más frecuente

Configuración global

Si tu aplicación siempre usa las mismas opciones, puedes configurarlas globalmente en lugar de pasarlas en cada llamada:

import { configurarGlobalmente } from 'legal-expand';

configurarGlobalmente({
  enabled: true,
  defaultOptions: {
    format: 'html',
    expandOnlyFirst: true,
    exclude: ['art.', 'núm.', 'apdo.']
  }
});

// Ahora todas las llamadas usan estas opciones por defecto
expandirSiglas('La AEAT notifica...');

Para resetear a la configuración original:

import { resetearConfiguracion } from 'legal-expand';

resetearConfiguracion();

Protección de contextos especiales

La librería detecta y protege contextos donde las siglas no deben expandirse:

URLs: Si el texto contiene https://aeat.es, no intenta expandir “aeat” como sigla.

Direcciones de correo: info@aeat.es se deja intacto.

Bloques de código: El contenido entre triple backticks no se procesa.

const texto = 'Visita https://aeat.es para más información sobre la AEAT';
expandirSiglas(texto);
// 'Visita https://aeat.es para más información sobre la AEAT (Agencia Estatal de Administración Tributaria)'

Solo se expande la AEAT del texto normal, no la que aparece en la URL.

Las 646 siglas del diccionario

El diccionario contiene siglas verificadas de fuentes oficiales:

Impuestos y tributos (45 siglas): AEAT, IVA, IRPF, IS, ISD, ITP, AJD, IAE, IBI, IIVTNU, ICIO, IGIC, IPSI…

Leyes y normativa (80+ siglas): CC (Código Civil), CCom (Código de Comercio), CE (Constitución Española), CP (Código Penal), LEC (Ley de Enjuiciamiento Civil), LECrim (Ley de Enjuiciamiento Criminal), LGT (Ley General Tributaria), LIRPF, LIVA, LIS, LOPJ, LOPD, LOPDGDD…

Instituciones (60+ siglas): AN (Audiencia Nacional), BOE, CGPJ (Consejo General del Poder Judicial), CNMV, DGT, DGRN, INEM, INSS, SEPE, TGSS, TS (Tribunal Supremo), TC (Tribunal Constitucional), TSJ, TSJC, TSJM…

Abreviaturas comunes (30+ siglas): art. (artículo), apdo. (apartado), cfr. (confróntese), núm. (número), pág. (página), ss. (siguientes), vid. (véase)…

Tipos societarios (15+ siglas): S.A., S.L., S.L.U., S.Coop., S.Com., UTE, AIE, SICAV…

Otras (30+ siglas): pyme, I+D, ERE, ERTE, LAU, LAR, LPH, RAE, DPEJ…

Las fuentes incluyen el Libro de Estilo de la Justicia de la RAE, el Diccionario Panhispánico del Español Jurídico (DPEJ), el BOE, y legislación vigente. Todas las siglas están normalizadas según criterios de la RAE, ordenadas por frecuencia de uso, y verificadas para evitar duplicados incorrectos.

Funciones auxiliares

Para listar todas las siglas disponibles:

import { listarSiglas } from 'legal-expand';

const siglas = listarSiglas();
// ['AEAT', 'IVA', 'IRPF', 'BOE', 'LEC', ...]

Para obtener estadísticas del diccionario:

import { obtenerEstadisticas } from 'legal-expand';

const stats = obtenerEstadisticas();
// {
//   totalAcronyms: 646,
//   withDuplicates: 23,
//   categories: { taxes: 45, laws: 80, institutions: 60, ... }
// }

Integración con frameworks

React

function LegalText({ texto }: { texto: string }) {
  const expandido = expandirSiglas(texto, { format: 'html' });
  return <div dangerouslySetInnerHTML={{ __html: expandido }} />;
}

Next.js (Server Components)

export default async function SentenciaPage({ params }) {
  const sentencia = await getSentencia(params.id);
  const textoExpandido = expandirSiglas(sentencia.texto);

  return <article>{textoExpandido}</article>;
}

FastAPI (Python)

from fastapi import FastAPI
from legal_expand import expandir_siglas, ExpansionOptions

app = FastAPI()

@app.post("/expandir")
async def expand(texto: str, formato: str = "plain"):
    resultado = expandir_siglas(texto, ExpansionOptions(format=formato))
    return {"resultado": resultado}

Django (Python)

from django.http import JsonResponse
from legal_expand import expandir_siglas

def expandir_view(request):
    texto = request.POST.get('texto', '')
    resultado = expandir_siglas(texto)
    return JsonResponse({'resultado': resultado})

Integración con LLMs

Cuando usas modelos de lenguaje para analizar textos legales, expandir las siglas antes de enviar el texto mejora los resultados. El modelo tiene más contexto y no tiene que inferir qué significa cada sigla.

import { expandirSiglas } from 'legal-expand';
import OpenAI from 'openai';

const openai = new OpenAI();

async function analizarSentencia(texto: string) {
  // Expandir siglas antes de enviar al LLM
  const textoExpandido = expandirSiglas(texto, { expandOnlyFirst: true });

  const response = await openai.chat.completions.create({
    model: 'gpt-4',
    messages: [
      { role: 'system', content: 'Eres un asistente legal especializado en derecho español.' },
      { role: 'user', content: `Analiza esta sentencia:\n\n${textoExpandido}` }
    ]
  });

  return response.choices[0].message.content;
}

El LLM recibe “AEAT (Agencia Estatal de Administración Tributaria)” en lugar de solo “AEAT”, lo que mejora la precisión del análisis.

Rendimiento

La librería está optimizada para procesar textos largos:

Las optimizaciones incluyen expresiones regulares precompiladas, diccionario indexado con búsqueda O(1), y cero dependencias externas que añadan overhead.

El tamaño del paquete NPM es de aproximadamente 4KB comprimido con gzip.

Compatibilidad

NPM (legal-expand):

PyPI (legal-expand):

El código está en GitHub

El paquete NPM está publicado como legal-expand. El código fuente está en github.com/686f6c61/legal-expand.

El paquete Python está publicado como legal-expand. El código fuente está en github.com/686f6c61/pypi-legal-expand.

Ambos proyectos tienen licencia MIT. Si encuentras siglas que faltan o tienen significados incorrectos, abre un issue o envía un pull request. El diccionario se mantiene actualizado con nuevas siglas según aparecen en legislación y práctica jurídica.