Skip to main content

browser-local-tools

Herramientas HTML que funcionan 100% en el navegador sin instalación. Patrón para crear tools locales con drag-drop, extracción de texto (mammoth.js para Word, pdf.js para PDF), normalización y comparación. Incluye pitfalls de PDF.js Worker y normalización de documentos legales.

설치로 이동

소스 정보

저장소
Ntizar/NtizarBrainMasterMind
최근 소스 활동
2026년 7월 16일 08:02
감지된 SKILL.md 언어
스페인어
스타
2
포크
0

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

파일 탐색기
12 개 파일

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
browser-local-tools
description
Herramientas HTML que funcionan 100% en el navegador sin instalación. Patrón para crear tools locales con drag-drop, extracción de texto (mammoth.js para Word, pdf.js para PDF), normalización y comparación. Incluye pitfalls de PDF.js Worker y normalización de documentos legales.
version
1.0.0
tags
["html","javascript","browser","local-tools","zero-install","pdfjs","mammoth"]
triggers
["herramienta local","sin instalar nada","comparar documentos","procesar PDF en navegador","procesar Word en navegador","herramienta HTML","sin Python","error con Python","exe","fácil de usar"]
# Browser Local Tools — Herramientas HTML que funcionan en local ## Cuándo usar esta skill Cuando el usuario necesita una herramienta de procesamiento que funcione **sin instalación** — sin Python, sin .exe, sin servidor. Se resuelve con un archivo `.html` que se abre en el navegador y usa JavaScript para procesar archivos. **Señales clave del usuario:** - "no me deja Python" / "da error con Python" - "¿no puedes hacerlo más fácil?" - "algo que se abra con doble clic" - "sin instalar nada" - Necesita procesar documentos Word/PDF/Imágenes de forma aislada ## Arquitectura típica ``` archivo.html (SOLO para uso personal en tu PC) ├── CDN libs (mammoth.js, pdf.js, etc.) ← solo si NUNCA compartirás el archivo ├── CSS inline (estilo limpio, responsive) ├── UI: drag-drop zone + botón comparar + resultados └── JS: extracción → limpieza → normalización → comparación → reporte archivo.html (PARA COMPARTIR con otros) ← PATRÓN POR DEFECTO ├── Librerías EMBEBIDAS inline (mammoth.min.js, pdf.min.js, etc.) ├── CSS inline ├── UI └── JS ``` ## ⚠️ PITFATAL CRÍTICO: CDN vs Embedding **Cuando el HTML se va a compartir con otros usuarios, NUNCA usar CDN.** Razón: Si el otro PC no tiene internet, tiene firewall corporativo, o abre el archivo desde `file://` → la librería no se carga → el programa no funciona. ```javascript // ❌ MAL — No funciona en otros PCs <script src="https://cdnjs.cloudflare.com/ajax/libs/mammoth/1.8.0/mammoth.browser.min.js"></script> // ✅ BIEN — Funciona en cualquier PC, sin internet <script> !function(f){if("object"==typeof exports&&...){/* mammoth.js completo embebido */}}... </script> ``` **Cómo embeber:** 1. Descargar la librería: `curl -sL "CDN_URL" -o lib.min.js` 2. Reemplazar `<script src="CDN_URL"></script>` por `<script>` + contenido + `</script>` 3. El HTML crecerá (~600KB con mammoth.js) pero funcionará 100% offline **Regla:** Si David (o cualquier usuario) dice "funciona en mi PC pero no en el de otros" → el 99% de las veces es CDN. Primera acción: embeber la librería. ## Patrón: Comparación de documentos con diff por palabras **NUNCA usar diff carácter a carácter** — el resultado es ilegible (bloques de caracteres pegados sin espacios). Siempre usar diff **por palabras** con algoritmo LCS. ### Algoritmo LCS para palabras ```javascript function diffPalabras(palabrasA, palabrasB) { const m = palabrasA.length, n = palabrasB.length; const dp = Array(m+1).fill(null).map(() => Array(n+1).fill(0)); for (let i = 1; i <= m; i++) for (let j = 1; j <= n; j++) dp[i][j] = palabrasA[i-1] === palabrasB[j-1] ? dp[i-1][j-1] + 1 : Math.max(dp[i-1][j], dp[i][j-1]); // Retroceder para obtener cambios: { tipo: 'add'|'del', palabra, idx } // ... } ``` ### Filtrado de ruido antes de comparar Los documentos Word certificados/electrónicos tienen ruido que hay que eliminar: - **URLs embebidas:** `https://sede.xunta.gal/...` - **Sellos CVE:** `[As copias en papel deste documento...](url)` — formato markdown de hipervínculo - **Texto de verificación:** "As copias en papel deste documento teñen a condición de copia e serán verificables a través deste código" - **Headers de página:** "PASEO DE LA CASTELLANA, 67 Página 1 / 5" - **Líneas con solo guiones/asteriscos** (separadores de tabla) ```javascript function eliminarRuido(texto) { return texto .replace(/https?:\/\/[^\s]+/g, ' ') // URLs sueltas .replace(/\[([^\]]*)\]\(https?:\/\/[^)]+\)/g, '$1') // [texto](url) → texto .replace(/As copias en papel deste documento[^.]*\./g, '') .replace(/condici[oó]n de copia[^.]*\./g, '') .replace(/\s+/g, ' ').trim(); } ``` ### UX: Porcentaje de similitud + frases legibles Mostrar resultado como: - ✅ 100% = "CONTENIDO IDÉNTICO" - 🟡 95%+ = "CASO IDÉNTICO" (probablemente solo formato/sellos) - 🟠 80-95% = "SIMILAR" (diferencias significativas) - 🔴 <80% = "DIFERENTES" Diferencias como frases: ``` ➕ Lo que AÑADE el Doc B: "As copias en papel deste documento..." ❌ Lo que ELIMINA el Doc B: (nada) ``` **NUNCA** mostrar bloques de caracteres pegados sin espacios — el usuario se frustra ("así no se que puede ser lo que es distinto... igual es un espacio o una chorrada"). **Excepción:** Solo usar CDN si el HTML es un prototipo temporal que NUNCA se compartirá. ## Librerías CDN confiables (solo para desarrollo personal) | Librería | CDN | Uso | |---|---|---| | mammoth.js | `cdnjs.cloudflare.com/ajax/libs/mammoth/1.8.0/mammoth.browser.min.js` | Word → texto plano | | pdf.js | `cdn.jsdelivr.net/npm/pdfjs-dist@3.11.174/build/pdf.min.js` | PDF → texto | | marked | `cdnjs.cloudflare.com/ajax/libs/marked/4.0.10/marked.min.js` | Markdown → HTML | **⚠️ Preferir jsdelivr sobre cdnjs para pdf.js** — cdnjs tiene timeouts ocasionales. ## Pitfalls críticos ### PDF.js Worker (CRÍTICO) ```javascript // ❌ MAL — Worker falla desde file:// protocol pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdn.../pdf.worker.min.js'; // ✅ BIEN — Sin worker, funciona desde file:// y https:// pdfjsLib.GlobalWorkerOptions.workerSrc = ''; ``` **Motivo:** Cuando el usuario abre el HTML con doble clic (file:// protocol), el navegador bloquea la carga del Web Worker por CORS/Same-Origin Policy. El PDF se carga pero `getTextContent()` devuelve 0 items → 0 palabras → el usuario ve "0 palabras" en el PDF. ### PDF.js no extrae texto de PDFs generados por Acrobat PDFMaker (CRÍTICO) **Síntoma:** pdf.js devuelve 0 palabras aunque el PDF tiene texto visible. Confirmando con `markitdown` Python → 2588 palabras. El PDF fue creado por "Acrobat PDFMaker 26 para Word". **Causa:** Acrobat PDFMaker genera fuentes con codificación no estándar que pdf.js no puede decodificar. No es un bug del Worker — es una limitación del parser. **Solución:** No intentar extraer texto de PDFs directamente en el navegador si el usuario tiene muchos PDFs de origen corporativo. En su lugar: 1. Convertir PDFs a Word con LibreOffice (`soffice --convert-to docx`) 2. Comparar Word vs Word con mammoth.js ```bash # .bat para convertir PDFs a Word en lote for %%f in (*.pdf) do "C:\Program Files\LibreOffice\program\soffice.exe" --headless --convert-to docx "%%f" ``` **Solución:** Siempre configurar `workerSrc = ''` para herramientas que se usan desde archivos locales. Si se necesita rendimiento (PDFs grandes, 100+ páginas), usar fallback: ```javascript try { pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdn.../pdf.worker.min.js'; const pdf = await pdfjsLib.getDocument({ data: arrayBuffer }).promise; // ... } catch(e) { pdfjsLib.GlobalWorkerOptions.workerSrc = ''; const pdf = await pdfjsLib.getDocument({ data: arrayBuffer }).promise; // ... } ``` ### Extracción de texto de PDFs legales Los PDFs generados desde Word o herramientas de diseño gráfico producen artefactos: - **Tracking raro:** "A C UER DO" en vez de "ACUERDO" (espaciado entre letras) - **Años partidos:** "20 26" o "2 026" en vez de "2026" - **Cabeceras de página:** "PASEO DE LA CASTELLANA, 67 Página 1 / 5" - **Tablas vacías:** Muchas filas/columnas vacías que generan ruido ### Normalización para documentos legales ```javascript function normalizar(texto) { return texto // 1. Eliminar numeración de párrafos al inicio de línea .replace(/(?:^|\n)\s*\d{1,2}\.\s/g, '\n') .replace(/(?:^|\n)\s*\*\d{1,2}\.\s/g, '\n') // Markdown // 2. Minúsculas + quitar tildes .toLowerCase() .normalize('NFD') .replace(/[\u0300-\u036f]/g, '') // 3. Solo letras y números .replace(/[^a-z0-9]/g, ''); } ``` **Importante:** El regex de numeración DEBE ser `(?:^|\n)\s*\d{1,2}\.\s` (al inicio de línea), NO `\b\d+\.\s` (global) — porque `\b\d+\.\s` come "026" del año "2026." cuando hay un punto después. ### Metadata a eliminar de documentos legales ```javascript function limpiarMetadata(texto) { // 1. Sección de firmas (tabla diferente entre Word y PDF) const idx = texto.toLowerCase().indexOf('firman en la fecha'); if (idx > 0) texto = texto.substring(0, idx); // 2. Headers/footers de página texto = texto.split('\n') .filter(l => !/PASEO|CASTELLANA|MADRID|28071|Página\s+\d/i.test(l)) .filter(l => !/^[\s\-|*#=_]+$/.test(l)) .join('\n'); return texto; } ``` ## Preferencia del usuario (David) Cuando David dice "no me deja Python" o "algo más fácil", la respuesta **nunca** es "instala X" o "usa Y". La respuesta es: **crear un HTML que funcione en el navegador**. Cero dependencias, cero instalación, doble clic y listo. **Portabilidad:** Si el HTML se va a compartir con otros (compañeros de trabajo, clientes), SIEMPRE embeber las librerías inline. David ha tenido problemas con HTMLs que usaban CDN al compartirlos — otros PCs no cargaban las dependencias. Para el futuro: si la herramienta necesitaba Python, considerar si se puede resolver con: 1. HTML + JavaScript en navegador (preferido, con libs embebidas si es compartido) 2. Script .bat/.sh que instale dependencias automáticamente 3. .exe con PyInstaller (último recurso, requiere compilación en Windows)
GitHub에서 보기