execonvert 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/README.md +194 -0
  3. package/THIRD_PARTY_NOTICES.md +42 -0
  4. package/bin/execonvert.js +21 -0
  5. package/dist/cli/app/public/THIRD_PARTY_NOTICES.md +32 -0
  6. package/dist/cli/app/public/base.elpx +0 -0
  7. package/dist/cli/app/public/exe_math_assets.zip +0 -0
  8. package/dist/cli/app/public/exelearning/app/common/common_i18n.js +79 -0
  9. package/dist/cli/app/public/exelearning/app/common/exe_powered_logo/exe_powered_logo.png +0 -0
  10. package/dist/cli/app/public/exelearning/app/common/i18n/common_i18n.ca.js +79 -0
  11. package/dist/cli/app/public/exelearning/app/common/i18n/common_i18n.de.js +79 -0
  12. package/dist/cli/app/public/exelearning/app/common/i18n/common_i18n.en.js +79 -0
  13. package/dist/cli/app/public/exelearning/app/common/i18n/common_i18n.eo.js +79 -0
  14. package/dist/cli/app/public/exelearning/app/common/i18n/common_i18n.es.js +79 -0
  15. package/dist/cli/app/public/exelearning/app/common/i18n/common_i18n.eu.js +79 -0
  16. package/dist/cli/app/public/exelearning/app/common/i18n/common_i18n.gl.js +79 -0
  17. package/dist/cli/app/public/exelearning/app/common/i18n/common_i18n.it.js +79 -0
  18. package/dist/cli/app/public/exelearning/app/common/i18n/common_i18n.pt.js +79 -0
  19. package/dist/cli/app/public/exelearning/app/common/i18n/common_i18n.ro.js +79 -0
  20. package/dist/cli/app/public/exelearning/app/common/i18n/common_i18n.va.js +79 -0
  21. package/dist/cli/app/public/exelearning/bundles/common.zip +0 -0
  22. package/dist/cli/app/public/exelearning/bundles/content-css.zip +0 -0
  23. package/dist/cli/app/public/exelearning/bundles/idevices.zip +0 -0
  24. package/dist/cli/app/public/exelearning/bundles/libs.zip +0 -0
  25. package/dist/cli/app/public/exelearning/bundles/manifest.json +110 -0
  26. package/dist/cli/app/public/exelearning/bundles/themes/base.zip +0 -0
  27. package/dist/cli/app/public/exelearning/bundles/themes/flux.zip +0 -0
  28. package/dist/cli/app/public/exelearning/bundles/themes/neo.zip +0 -0
  29. package/dist/cli/app/public/exelearning/bundles/themes/nova.zip +0 -0
  30. package/dist/cli/app/public/exelearning/bundles/themes/universal.zip +0 -0
  31. package/dist/cli/app/public/exelearning/bundles/themes/zen.zip +0 -0
  32. package/dist/cli/app/public/exelearning/exporters.bundle.js +12638 -0
  33. package/dist/cli/app/public/exelearning/importers.bundle.js +14061 -0
  34. package/dist/cli/app/public/exelearning/runtime-source.json +10 -0
  35. package/dist/cli/app/public/favicon.svg +11 -0
  36. package/dist/cli/app/public/idevices/text/text.css +16 -0
  37. package/dist/cli/app/public/idevices/text/text.html +3 -0
  38. package/dist/cli/app/public/idevices/text/text.js +291 -0
  39. package/dist/cli/app/public/info/cli.html +955 -0
  40. package/dist/cli/app/public/info/docx.svg +7 -0
  41. package/dist/cli/app/public/info/elpx-icon.png +0 -0
  42. package/dist/cli/app/public/info/exe-old.png +0 -0
  43. package/dist/cli/app/public/info/execonvert-cli-icon.svg +16 -0
  44. package/dist/cli/app/public/info/execonvert-icon.svg +11 -0
  45. package/dist/cli/app/public/info/index.html +723 -0
  46. package/dist/cli/app/public/info/markdown.svg +1 -0
  47. package/dist/cli/app/public/info/pdf.svg +14 -0
  48. package/dist/cli/app/public/libs/exe_math/LICENSE +202 -0
  49. package/dist/cli/app/public/libs/exe_math/a11y/assistive-mml.js +1 -0
  50. package/dist/cli/app/public/libs/exe_math/a11y/complexity.js +1 -0
  51. package/dist/cli/app/public/libs/exe_math/a11y/explorer.js +1 -0
  52. package/dist/cli/app/public/libs/exe_math/a11y/semantic-enrich.js +1 -0
  53. package/dist/cli/app/public/libs/exe_math/a11y/speech.js +1 -0
  54. package/dist/cli/app/public/libs/exe_math/a11y/sre.js +1 -0
  55. package/dist/cli/app/public/libs/exe_math/adaptors/jsdom.js +1 -0
  56. package/dist/cli/app/public/libs/exe_math/adaptors/linkedom.js +1 -0
  57. package/dist/cli/app/public/libs/exe_math/adaptors/liteDOM.js +1 -0
  58. package/dist/cli/app/public/libs/exe_math/core.js +1 -0
  59. package/dist/cli/app/public/libs/exe_math/input/asciimath.js +1 -0
  60. package/dist/cli/app/public/libs/exe_math/input/mml/entities.js +1 -0
  61. package/dist/cli/app/public/libs/exe_math/input/mml/extensions/mml3.js +1 -0
  62. package/dist/cli/app/public/libs/exe_math/input/mml/extensions/mml3.sef.json +1 -0
  63. package/dist/cli/app/public/libs/exe_math/input/mml.js +1 -0
  64. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/action.js +1 -0
  65. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/ams.js +1 -0
  66. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/amscd.js +1 -0
  67. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/autoload.js +1 -0
  68. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/bbm.js +1 -0
  69. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/bboldx.js +1 -0
  70. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/bbox.js +1 -0
  71. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/begingroup.js +1 -0
  72. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/boldsymbol.js +1 -0
  73. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/braket.js +1 -0
  74. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/bussproofs.js +1 -0
  75. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/cancel.js +1 -0
  76. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/cases.js +1 -0
  77. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/centernot.js +1 -0
  78. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/color.js +1 -0
  79. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/colortbl.js +1 -0
  80. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/colorv2.js +1 -0
  81. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/configmacros.js +1 -0
  82. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/dsfont.js +1 -0
  83. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/empheq.js +1 -0
  84. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/enclose.js +1 -0
  85. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/extpfeil.js +1 -0
  86. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/gensymb.js +1 -0
  87. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/html.js +1 -0
  88. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/mathtools.js +1 -0
  89. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/mhchem.js +34 -0
  90. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/newcommand.js +1 -0
  91. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/noerrors.js +1 -0
  92. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/noundefined.js +1 -0
  93. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/physics.js +1 -0
  94. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/require.js +1 -0
  95. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/setoptions.js +1 -0
  96. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/tagformat.js +1 -0
  97. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/texhtml.js +1 -0
  98. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/textcomp.js +1 -0
  99. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/textmacros.js +1 -0
  100. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/unicode.js +1 -0
  101. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/units.js +1 -0
  102. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/upgreek.js +1 -0
  103. package/dist/cli/app/public/libs/exe_math/input/tex/extensions/verb.js +1 -0
  104. package/dist/cli/app/public/libs/exe_math/input/tex-base.js +1 -0
  105. package/dist/cli/app/public/libs/exe_math/input/tex.js +1 -0
  106. package/dist/cli/app/public/libs/exe_math/loader.js +1 -0
  107. package/dist/cli/app/public/libs/exe_math/output/chtml.js +1 -0
  108. package/dist/cli/app/public/libs/exe_math/output/svg.js +1 -0
  109. package/dist/cli/app/public/libs/exe_math/sre/mathmaps/af.json +146 -0
  110. package/dist/cli/app/public/libs/exe_math/sre/mathmaps/base.json +137 -0
  111. package/dist/cli/app/public/libs/exe_math/sre/mathmaps/ca.json +140 -0
  112. package/dist/cli/app/public/libs/exe_math/sre/mathmaps/da.json +140 -0
  113. package/dist/cli/app/public/libs/exe_math/sre/mathmaps/de.json +146 -0
  114. package/dist/cli/app/public/libs/exe_math/sre/mathmaps/en.json +158 -0
  115. package/dist/cli/app/public/libs/exe_math/sre/mathmaps/es.json +140 -0
  116. package/dist/cli/app/public/libs/exe_math/sre/mathmaps/euro.json +32 -0
  117. package/dist/cli/app/public/libs/exe_math/sre/mathmaps/fr.json +146 -0
  118. package/dist/cli/app/public/libs/exe_math/sre/mathmaps/hi.json +146 -0
  119. package/dist/cli/app/public/libs/exe_math/sre/mathmaps/it.json +146 -0
  120. package/dist/cli/app/public/libs/exe_math/sre/mathmaps/ko.json +146 -0
  121. package/dist/cli/app/public/libs/exe_math/sre/mathmaps/nb.json +146 -0
  122. package/dist/cli/app/public/libs/exe_math/sre/mathmaps/nemeth.json +125 -0
  123. package/dist/cli/app/public/libs/exe_math/sre/mathmaps/nn.json +146 -0
  124. package/dist/cli/app/public/libs/exe_math/sre/mathmaps/sv.json +146 -0
  125. package/dist/cli/app/public/libs/exe_math/sre/require.d.mts +1 -0
  126. package/dist/cli/app/public/libs/exe_math/sre/require.mjs +2 -0
  127. package/dist/cli/app/public/libs/exe_math/sre/speech-worker.js +1 -0
  128. package/dist/cli/app/public/libs/exe_math/startup.js +1 -0
  129. package/dist/cli/app/public/libs/exe_math/tex-mml-svg.js +1 -0
  130. package/dist/cli/app/public/libs/exe_math/ui/lazy.js +1 -0
  131. package/dist/cli/app/public/libs/exe_math/ui/menu.js +1 -0
  132. package/dist/cli/app/public/libs/exe_math/ui/safe.js +1 -0
  133. package/dist/cli/cli/execonvert.js +807 -0
  134. package/dist/cli/cli/runtime.js +237 -0
  135. package/dist/cli/package.json +3 -0
  136. package/dist/cli/src/converter.js +5078 -0
  137. package/dist/cli/src/docx-import.js +1121 -0
  138. package/dist/cli/src/elpx-markdown.js +201 -0
  139. package/dist/cli/src/i18n.js +485 -0
  140. package/dist/cli/src/index.js +1 -0
  141. package/dist/cli/src/legacy-elp.js +846 -0
  142. package/dist/cli/src/markdown-import.js +26 -0
  143. package/package.json +68 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,79 @@
1
+ # Changelog
2
+
3
+ Todos los cambios relevantes de este proyecto se documentan aquí.
4
+
5
+ El formato se basa en [Keep a Changelog](https://keepachangelog.com/es-ES/1.0.0/)
6
+ y el proyecto sigue [Versionado Semántico](https://semver.org/lang/es/).
7
+
8
+ Categorías usadas: **Añadido**, **Cambiado**, **Corregido**, **Eliminado**.
9
+
10
+ ## [Unreleased]
11
+
12
+ ## [0.4.0] - 2026-06-25
13
+
14
+ ### Añadido
15
+ - Script `scripts/sync-exe-bundles.sh` y comando `npm run sync:exe` para
16
+ actualizar el runtime embebido de eXeLearning (`app/public/exelearning/`)
17
+ desde la última release estable, registrando versión, tag y commit en
18
+ `app/public/exelearning/runtime-source.json`. Una sola fuente cubre web y
19
+ escritorio, porque el build de la CLI copia `app/public/` tal cual.
20
+ - Este `CHANGELOG.md`, incluido también en el paquete npm distribuible.
21
+ - Soporte de traducciones (i18n) en la conversión legacy `.elp → .elpx`: el
22
+ fetcher implementa `fetchI18nFile` y `fetchI18nTranslations` (que el exporter
23
+ 4.0.1 exige) y el sync trae los archivos i18n de eXeLearning (plantilla + 11
24
+ idiomas). Las etiquetas de navegación y el `common_i18n.js` del proyecto salen
25
+ en el idioma del contenido.
26
+
27
+ ### Cambiado
28
+ - Runtime embebido de eXeLearning actualizado a **v4.0.1**. El paquete de temas
29
+ pasa de incluir solo `base` a incluir los 6 oficiales (`base`, `flux`, `neo`,
30
+ `nova`, `universal`, `zen`), lo que habilita la conversión de proyectos con
31
+ cualquiera de esos temas.
32
+
33
+ ### Corregido
34
+ - La conversión `.elp → .elpx` dejaba de funcionar con el runtime 4.0.1
35
+ (`this.fetcher.fetchI18nTranslations is not a function`); ahora el fetcher
36
+ implementa los métodos i18n requeridos.
37
+
38
+ ## [0.3.1] - 2026-05-12
39
+
40
+ ### Corregido
41
+ - La CLI expande patrones glob internamente para compatibilidad con Windows.
42
+
43
+ ### Cambiado
44
+ - Documentación de la página CLI: explicación de los formatos soportados.
45
+
46
+ ## [0.3.0] - 2026-05-12
47
+
48
+ ### Añadido
49
+ - Conversión por lotes en la CLI con `--to` y `--out-dir`.
50
+
51
+ ## [0.2.2] - 2026-04-02
52
+
53
+ ### Añadido
54
+ - Analítica de visitas dedicada para la CLI.
55
+
56
+ ## [0.2.1] - 2026-04-02
57
+
58
+ ### Cambiado
59
+ - Ajustes en la cabecera y los enlaces de la página de la CLI.
60
+
61
+ ## [0.2.0] - 2026-04-02
62
+
63
+ ### Añadido
64
+ - Línea de comandos (`execonvert`) para automatizar conversiones, con paquetes
65
+ nativos (`.deb`, AppImage, `.exe`, `.pkg`) generados por GitHub Actions.
66
+
67
+ ## [0.1.0] - 2026-04-01
68
+
69
+ ### Añadido
70
+ - Primera versión estable. Conversor estático en navegador y CLI entre `.elp`,
71
+ `.elpx`, `.docx`, `.md` y `.pdf`, usando los bundles de importación y
72
+ exportación de eXeLearning. Exportación PDF con MathJax en SVG.
73
+ - Contador de visitas propio para la versión web.
74
+
75
+ ---
76
+
77
+ Las versiones beta previas (`v0.1.0-beta.*`) y el detalle fino de cada cambio
78
+ están en el historial de git. Las entradas anteriores a *Unreleased* se
79
+ reconstruyeron a partir de los tags y mensajes de commit existentes.
package/README.md ADDED
@@ -0,0 +1,194 @@
1
+ # eXeConvert
2
+
3
+ Conversor estático en navegador para transformar proyectos de eXeLearning y convertir entre `.elp`, `.elpx`, `.docx`, `.md` y `.pdf` sin salir del navegador.
4
+
5
+ ## Qué hace ahora
6
+
7
+ - Lee directamente en el navegador archivos `.elp`, `.elpx`, `.docx` y `.md`.
8
+ - Convierte proyectos legacy `.elp` a `.elpx` usando el pipeline de importación/exportación de eXeLearning.
9
+ - Analiza `content.xml` de proyectos `.elpx` modernos y permite seleccionar páginas antes de exportar.
10
+ - Reconstruye una versión HTML estable del contenido para previsualización y exportación.
11
+ - Exporta `.elpx` a `.docx`, `.md` o `.pdf`.
12
+ - En CLI y paquetes nativos, la exportación `.pdf` usa Puppeteer con navegador embebido y MathJax en SVG para mantener fórmulas vectoriales.
13
+ - Importa `.docx` y `.md` a `.elpx`.
14
+
15
+ ## Qué no hace todavía
16
+
17
+ - No intenta reproducir toda la lógica visual de `singlepage`; genera una versión estable orientada a exportación y previsualización.
18
+ - La exportación a `.docx` genera un documento nativo simplificado, priorizando compatibilidad con LibreOffice y Word frente a la fidelidad visual absoluta.
19
+ - La conversión depende de la estructura semántica disponible en el proyecto o documento de origen; algunos iDevices, estilos complejos o comportamientos interactivos pueden degradarse a una representación más simple.
20
+
21
+ ## Desarrollo
22
+
23
+ ```bash
24
+ npm install
25
+ npm run dev
26
+ ```
27
+
28
+ La aplicación queda disponible en `http://localhost:3007`.
29
+
30
+ ## CLI
31
+
32
+ También hay una interfaz de línea de comandos para automatizar conversiones desde terminal o desde otros programas.
33
+
34
+ En desarrollo:
35
+
36
+ ```bash
37
+ npm run cli -- archivo-entrada archivo-salida
38
+ npm run cli -- inspect archivo.elpx
39
+ ```
40
+
41
+ Para generar la CLI distribuible:
42
+
43
+ ```bash
44
+ npm run build:cli
45
+ ```
46
+
47
+ Instalación para usuarios técnicos:
48
+
49
+ ```bash
50
+ npm install -g execonvert
51
+ ```
52
+
53
+ o sin instalar globalmente:
54
+
55
+ ```bash
56
+ npx execonvert archivo-entrada archivo-salida
57
+ ```
58
+
59
+ El comando instalado siempre es `execonvert`.
60
+
61
+ Distribución para usuarios normales:
62
+
63
+ - Linux Debian/Ubuntu/MX: paquete `.deb`
64
+ - Linux genérico: `AppImage`
65
+ - Windows: instalador `.exe`
66
+ - macOS: instalador `.pkg`
67
+
68
+ Esos paquetes se generan en GitHub Actions y se adjuntan a cada release de GitHub.
69
+
70
+ Ejemplos:
71
+
72
+ ```bash
73
+ npm run cli -- apuntes.md apuntes.elpx --h1 resource-title --h2 subpage --h3 idevice
74
+ npm run cli -- proyecto.elpx proyecto.docx
75
+ npm run cli -- legacy.elp legacy.elpx
76
+ npm run cli -- legacy.elp legacy.pdf
77
+ npm run cli -- proyecto.elpx resumen.md --pages 1,2.1
78
+ npm run cli -- inspect proyecto.elpx --json
79
+ ```
80
+
81
+ Opciones principales:
82
+
83
+ - `inspect <archivo.elpx>`: muestra la estructura de páginas.
84
+ - `--json`: salida pensada para scripts.
85
+ - `--pages 1,2.1`: exporta solo esas páginas de un `.elpx`.
86
+ - `--page-id <id>` / `--page-ids a,b,c`: selección por IDs internos.
87
+ - `--h1`, `--h2`, `--h3`, `--h4`: controlan cómo se interpreta la estructura al importar `.docx` o `.md` a `.elpx`.
88
+
89
+ Valores admitidos para la estructura de importación:
90
+
91
+ - `--h1`: `page` | `resource-title`
92
+ - `--h2`, `--h3`, `--h4`: `idevice` | `subpage`
93
+
94
+ Estado actual de la CLI:
95
+
96
+ - soportado: `.md/.txt -> .elpx`
97
+ - soportado: `.docx -> .elpx`
98
+ - soportado: `.elpx -> .md`
99
+ - soportado: `.elpx -> .docx`
100
+ - soportado: `.elpx -> .pdf`
101
+ - soportado: `.elp -> .elpx`
102
+ - soportado: `.elp -> .md`
103
+ - soportado: `.elp -> .docx`
104
+ - soportado: `.elp -> .pdf`
105
+
106
+ ## Organización del código
107
+
108
+ La web y la CLI están separadas como dos frontends distintos sobre el mismo núcleo de conversión:
109
+
110
+ - `app/`: entrada y configuración de la aplicación web.
111
+ - `src/`: lógica compartida de conversión.
112
+ - `cli/`: entrada y runtime específico de la CLI.
113
+ - `bin/`: lanzador ejecutable de la CLI.
114
+
115
+ Comprobaciones:
116
+
117
+ ```bash
118
+ npm run check:web
119
+ npm run check:cli
120
+ npm run build
121
+ npm run build:cli
122
+ ```
123
+
124
+ La separación no exige cambios en GitHub Pages. El despliegue web sigue dependiendo de `vite.config.ts` y del contenido generado en `docs/`.
125
+
126
+ ## Publicación en GitHub Pages
127
+
128
+ - La app compilada se genera en `docs/`.
129
+ - El despliegue en `https://execonvert.github.io/` se hace con GitHub Actions.
130
+ - Cada `push` a `main` recompila la app y publica el contenido de `docs/` como sitio de GitHub Pages.
131
+ - En local puedes seguir usando `npm run build` para comprobar el resultado antes de subir cambios.
132
+
133
+ ## Publicación de la CLI
134
+
135
+ - La CLI distribuible se compila en `dist/cli/`.
136
+ - El ejecutable expuesto al usuario es siempre `execonvert`.
137
+ - `npm pack` genera un paquete instalable que conserva ese comando.
138
+ - El workflow de releases puede adjuntar ese `.tgz` a una release de GitHub para que otros usuarios lo descarguen e instalen con:
139
+
140
+ ```bash
141
+ npm install -g ./execonvert-<version>.tgz
142
+ ```
143
+
144
+ ## Paquetes nativos
145
+
146
+ Además del paquete npm, el repositorio incluye workflows para generar instaladores autocontenidos:
147
+
148
+ - `.deb` para Debian/Ubuntu/MX Linux
149
+ - `AppImage` para Linux
150
+ - `.exe` instalador para Windows
151
+ - `.pkg` instalador para macOS
152
+
153
+ La base de esos paquetes está en:
154
+
155
+ - `scripts/package-cli/prepare-bundle.mjs`
156
+ - `scripts/package-cli/build-deb.sh`
157
+ - `scripts/package-cli/build-appimage.sh`
158
+ - `scripts/package-cli/build-windows-installer.ps1`
159
+ - `scripts/package-cli/build-macos-pkg.sh`
160
+ - `.github/workflows/build-native-packages.yml`
161
+
162
+ La idea es siempre la misma:
163
+
164
+ - construir la CLI
165
+ - empaquetarla con un runtime de Node incluido
166
+ - descargar Chrome for Testing dentro de `runtime/puppeteer`
167
+ - instalar un comando final llamado `execonvert`
168
+
169
+ ## Estadísticas de visitas
170
+
171
+ La app puede integrarse con un contador propio en IONOS:
172
+
173
+ - resumen mínimo en el pie
174
+ - carga asíncrona para no bloquear la UI
175
+ - panel privado por aplicación
176
+ - series temporales y referrers
177
+
178
+ Backend base de esta app:
179
+
180
+ - `analytics/execonvert/track.php`
181
+ - `analytics/execonvert/admin-stats.php`
182
+ - `analytics/execonvert/lib.php`
183
+ - `analytics/execonvert/config.sample.php`
184
+
185
+ ## Arquitectura
186
+
187
+ - `src/converter.ts`: parser del `.elpx`, selección de páginas, normalización HTML y exportación a `.docx` y `.pdf`.
188
+ La ruta PDF principal en Node/CLI usa HTML imprimible + MathJax SVG + Puppeteer; `pdfmake` queda como fallback del navegador web.
189
+ - `src/legacy-elp.ts`: conversión de `.elp` legacy a `.elpx` mediante bundles de eXeLearning.
190
+ - `src/docx-import.ts`: importación de `.docx` a `.elpx`.
191
+ - `src/markdown-import.ts` y `src/elpx-markdown.ts`: conversiones entre `.md` y `.elpx`.
192
+ - `src/main.ts`: interfaz web estática.
193
+
194
+ La siguiente iteración razonable es sustituir el parser simplificado por una integración más directa con la lógica de exportación de eXeLearning.
@@ -0,0 +1,42 @@
1
+ # Third-Party Notices
2
+
3
+ This project includes or repackages assets derived from eXeLearning in order to interoperate with `.elpx` projects, preserve compatible previews, and support in-browser conversion from legacy `.elp` projects to `.elpx`.
4
+
5
+ ## Reused assets from eXeLearning
6
+
7
+ - Source project: https://github.com/exelearning/exelearning
8
+ - Project license: AGPL-3.0-or-later
9
+
10
+ Included resources in this repository:
11
+
12
+ - `app/public/base.elpx`
13
+ - Base template package used to generate compatible `.elpx` files.
14
+ - `app/public/idevices/text/text.js`
15
+ - `app/public/idevices/text/text.css`
16
+ - `app/public/idevices/text/text.html`
17
+ - Text iDevice assets reused for preview and packaging compatibility.
18
+ - `app/public/exe_math_assets.zip`
19
+ - Packaged `exe_math` runtime copied from the local eXeLearning source tree for MathJax-compatible formula rendering in generated previews.
20
+ - `app/public/exelearning/importers.bundle.js`
21
+ - `app/public/exelearning/exporters.bundle.js`
22
+ - Browser bundles reused from eXeLearning to run the real import/export pipeline for legacy `.elp` to `.elpx` conversion.
23
+ - `app/public/exelearning/bundles/common.zip`
24
+ - `app/public/exelearning/bundles/libs.zip`
25
+ - `app/public/exelearning/bundles/idevices.zip`
26
+ - `app/public/exelearning/bundles/content-css.zip`
27
+ - `app/public/exelearning/bundles/manifest.json`
28
+ - Supporting resource bundles required by the reused eXeLearning browser import/export runtime.
29
+
30
+ ## Additional license notes
31
+
32
+ - `app/public/idevices/text/text.js` contains a header pointing to:
33
+ - Creative Commons Attribution-ShareAlike 4.0
34
+ - http://creativecommons.org/licenses/by-sa/4.0/
35
+ - The bundled `exe_math` distribution includes an Apache License 2.0 license file in the original eXeLearning source tree:
36
+ - `https://github.com/exelearning/exelearning/blob/main/public/app/common/exe_math/LICENSE`
37
+ - The reused browser bundles and packaged resources listed under `app/public/exelearning/` are derived from the AGPL-3.0-or-later eXeLearning project and are redistributed here for compatibility and conversion support.
38
+
39
+ ## Notes
40
+
41
+ - This file is provided as a practical attribution summary for reused third-party assets.
42
+ - It does not replace the original licenses distributed by their respective authors.
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+ import { spawnSync } from 'node:child_process';
3
+ import { existsSync } from 'node:fs';
4
+ import { fileURLToPath } from 'node:url';
5
+
6
+ const distCliPath = fileURLToPath(new URL('../dist/cli/cli/execonvert.js', import.meta.url));
7
+ const cliPath = fileURLToPath(new URL('../cli/execonvert.ts', import.meta.url));
8
+ const tsxCliPath = fileURLToPath(new URL('../node_modules/tsx/dist/cli.mjs', import.meta.url));
9
+
10
+ const args = existsSync(distCliPath)
11
+ ? [distCliPath, ...process.argv.slice(2)]
12
+ : [tsxCliPath, cliPath, ...process.argv.slice(2)];
13
+
14
+ const result = spawnSync(process.execPath, args, { stdio: 'inherit' });
15
+
16
+ if (result.error) {
17
+ console.error(result.error.message);
18
+ process.exit(1);
19
+ }
20
+
21
+ process.exit(result.status ?? 1);
@@ -0,0 +1,32 @@
1
+ # Third-Party Notices
2
+
3
+ This project includes or repackages assets derived from eXeLearning in order to interoperate with `.elpx` projects and preserve compatible previews.
4
+
5
+ ## Reused assets from eXeLearning
6
+
7
+ - Source project: https://github.com/exelearning/exelearning
8
+ - Project license: AGPL-3.0-or-later
9
+
10
+ Included resources in this repository:
11
+
12
+ - `app/public/base.elpx`
13
+ - Base template package used to generate compatible `.elpx` files.
14
+ - `app/public/idevices/text/text.js`
15
+ - `app/public/idevices/text/text.css`
16
+ - `app/public/idevices/text/text.html`
17
+ - Text iDevice assets reused for preview and packaging compatibility.
18
+ - `app/public/exe_math_assets.zip`
19
+ - Packaged `exe_math` runtime copied from the local eXeLearning source tree for MathJax-compatible formula rendering in generated previews.
20
+
21
+ ## Additional license notes
22
+
23
+ - `app/public/idevices/text/text.js` contains a header pointing to:
24
+ - Creative Commons Attribution-ShareAlike 4.0
25
+ - http://creativecommons.org/licenses/by-sa/4.0/
26
+ - The bundled `exe_math` distribution includes an Apache License 2.0 license file in the original eXeLearning source tree:
27
+ - `https://github.com/exelearning/exelearning/blob/main/public/app/common/exe_math/LICENSE`
28
+
29
+ ## Notes
30
+
31
+ - This file is provided as a practical attribution summary for reused third-party assets.
32
+ - It does not replace the original licenses distributed by their respective authors.
Binary file
@@ -0,0 +1,79 @@
1
+ // The content of this file should be generated dynamically in the .elpx's language.
2
+ $exe_i18n = {
3
+ "previous": c_("Previous"),
4
+ "next": c_("Next"),
5
+ "menu": c_("Menu"),
6
+ "show": c_("Show"),
7
+ "hide": c_("Hide"),
8
+ "toggleContent": c_("Toggle content"),
9
+ "showFeedback": c_("Show feedback"),
10
+ "hideFeedback": c_("Hide feedback"),
11
+ "correct": c_("Correct"),
12
+ "incorrect": c_("Incorrect"),
13
+ "yourScoreIs": c_("Your score"),
14
+ "solution": c_("Solution"),
15
+ "download": c_("Download"),
16
+ "print": c_("Print"),
17
+ "search": c_("Search"),
18
+ "dataError": c_("Data error"),
19
+ "epubJSerror": c_("This might not work in this ePub reader"),
20
+ "epubDisabled": c_("This activity does not work in ePub format"),
21
+ "fullSearch": c_("Full search"),
22
+ "noSearchResults": c_("No search results"),
23
+ "searchResults": c_("Search results for"),
24
+ "hideResults": c_("Hide results"),
25
+ "block": c_("block"),
26
+ "more": c_("More"),
27
+ "newWindow": c_("New window"),
28
+ "fullSize": c_("Full size"),
29
+ "accessibility_tools": c_("Accessibility tools"),
30
+ "close_toolbar": c_("Close"),
31
+ "default_font": c_("Default font"),
32
+ "increase_text_size": c_("Increase text size"),
33
+ "decrease_text_size": c_("Decrease text size"),
34
+ "uppercase_text": c_("Uppercase"),
35
+ "read": c_("Read"),
36
+ "stop_reading": c_("Stop reading"),
37
+ "translate": c_("Translate"),
38
+ "drag_and_drop": c_("Drag and drop"),
39
+ "reset": c_("Reset"),
40
+ "mode_toggler": c_("Light/Dark mode"),
41
+ "teacher_mode": c_("Teacher mode"),
42
+ "elpxGenerating": c_("Generating..."),
43
+ "elpxProcessing": c_("Processing..."),
44
+ "elpxFolderPickerTimeout": c_("The folder picker did not respond. This may happen when opening exported files directly from the filesystem (file:// protocol). Try opening the file through a local web server instead."),
45
+ "elpxFolderPickerEmpty": c_("No files were returned by the folder picker. This is a known limitation when opening exported files with the file:// protocol in some browsers. Try using a different browser or opening the file through a local web server."),
46
+ "elpxFileProtocolWarning": c_("Local mode: Due to browser security policy, you will need to select the folder from which you opened this file. On a web server this will not be necessary."),
47
+ "proprietaryLicense": c_("Proprietary license"),
48
+ "notAppropriate": c_("Not appropriate"),
49
+ "publicDomain": c_("Public domain")
50
+ };
51
+ // The following line should only be used if the ELP contains a hangman game:
52
+ $exe_i18n.exeGames = {
53
+ "hangManGame": c_("Hangman game"),
54
+ "accept": c_("Accept"),
55
+ "yes": c_("Yes"),
56
+ "no": c_("No"),
57
+ "right": c_("Right"),
58
+ "wrong": c_("Wrong"),
59
+ "rightAnswer": c_("Right answer"),
60
+ "stat": c_("Status"),
61
+ "selectedLetters": c_("Selected letters"),
62
+ "word": c_("Word"),
63
+ "words": c_("Words"),
64
+ "play": c_("Play"),
65
+ "playAgain": c_("Restart"),
66
+ "results": c_("Results"),
67
+ "total": c_("Total"),
68
+ "otherWord": c_("Other word"),
69
+ "gameOver": c_("Game over"),
70
+ "confirmReload": c_("Reload game?"),
71
+ "clickOnPlay": c_("Click Play to start"),
72
+ "clickOnOtherWord": c_("Click Other word to continue"),
73
+ "az": c_("abcdefghijklmnopqrstuvwxyz")
74
+ };
75
+
76
+ // Export for Node.js/CommonJS (tests)
77
+ if (typeof module !== 'undefined' && module.exports) {
78
+ module.exports = $exe_i18n;
79
+ }
@@ -0,0 +1,79 @@
1
+ // The content of this file should be generated dynamically in the .elpx's language.
2
+ $exe_i18n = {
3
+ "previous": "Anterior",
4
+ "next": "Següent",
5
+ "menu": "Menú",
6
+ "show": "Mostra",
7
+ "hide": "Amaga",
8
+ "toggleContent": "Commuta el contingut",
9
+ "showFeedback": "Mostra la retroalimentació",
10
+ "hideFeedback": "Amaga la retroalimentació",
11
+ "correct": "Correcte",
12
+ "incorrect": "Incorrecte",
13
+ "yourScoreIs": "La seva puntuació",
14
+ "solution": "Solució",
15
+ "download": "Descarrega",
16
+ "print": "Imprimeix",
17
+ "search": "Cerca",
18
+ "dataError": "Error de dades",
19
+ "epubJSerror": "Això podria no funcionar en aquest lector d'ePub",
20
+ "epubDisabled": "Aquesta activitat no funciona en format ePub",
21
+ "fullSearch": " Cerca complet",
22
+ "noSearchResults": " Sense resultats",
23
+ "searchResults": "Resultats de cerca per",
24
+ "hideResults": "Amaga resultats",
25
+ "block": "bloc",
26
+ "more": "Més",
27
+ "newWindow": "Nova finestra",
28
+ "fullSize": "Mida completa",
29
+ "accessibility_tools": "Eines d'accessibilitat",
30
+ "close_toolbar": "Tanca",
31
+ "default_font": "Tipografia predeterminada",
32
+ "increase_text_size": "Augmenta la mida del text",
33
+ "decrease_text_size": "Redueix la mida del text",
34
+ "uppercase_text": "Majúscules",
35
+ "read": "Llegeix",
36
+ "stop_reading": "Atura la lectura",
37
+ "translate": "Tradueix",
38
+ "drag_and_drop": "Arrossega i deixa anar",
39
+ "reset": "Reinicia",
40
+ "mode_toggler": "Mode clar/fosc",
41
+ "teacher_mode": "Mode professor",
42
+ "elpxGenerating": " S'està generant...",
43
+ "elpxProcessing": "Processant...",
44
+ "elpxFolderPickerTimeout": "El selector de carpetes no ha respost. Això pot passar en obrir arxius exportats directament des del teu equip (protocol file://). Intenta obrir l'arxiu a través d'un servidor.",
45
+ "elpxFolderPickerEmpty": "El selector de carpetes no ha trobat arxius. Aquesta és una limitació coneguda en obrir arxius exportats amb el protocol file:// en alguns navegadors. Intenta utilitzar un altre navegador o obrir l'arxiu a través d'un servidor web.",
46
+ "elpxFileProtocolWarning": "Mode local: a causa de la política de seguretat del navegador, hauràs de seleccionar la carpeta des de la qual vas obrir aquest fitxer. En un servidor web això no serà necessari.",
47
+ "proprietaryLicense": "Llicència propietària",
48
+ "notAppropriate": "No apropiada",
49
+ "publicDomain": "Domini públic"
50
+ };
51
+ // The following line should only be used if the ELP contains a hangman game:
52
+ $exe_i18n.exeGames = {
53
+ "hangManGame": "Joc de l'endevinalla",
54
+ "accept": "Accepta",
55
+ "yes": "Sí",
56
+ "no": "No",
57
+ "right": "Dreta",
58
+ "wrong": "Incorrecte",
59
+ "rightAnswer": "Resposta correcta",
60
+ "stat": "Estat",
61
+ "selectedLetters": "Lletres seleccionades",
62
+ "word": "Mot",
63
+ "words": "Mots",
64
+ "play": "Reprodueix",
65
+ "playAgain": "Reinicia",
66
+ "results": "Resultats",
67
+ "total": "Total",
68
+ "otherWord": "Una altra paraula",
69
+ "gameOver": "Fi del joc",
70
+ "confirmReload": "¿Reiniciar el joc?",
71
+ "clickOnPlay": "Fes clic a \"Jugar\" per començar",
72
+ "clickOnOtherWord": "Fes clic a \"Una altra paraula\" per continuar",
73
+ "az": "abcçdefghijklmnopqrstuvwxyz"
74
+ };
75
+
76
+ // Export for Node.js/CommonJS (tests)
77
+ if (typeof module !== 'undefined' && module.exports) {
78
+ module.exports = $exe_i18n;
79
+ }
@@ -0,0 +1,79 @@
1
+ // The content of this file should be generated dynamically in the .elpx's language.
2
+ $exe_i18n = {
3
+ "previous": "Zurück",
4
+ "next": "Weiter",
5
+ "menu": "Menü",
6
+ "show": "Anzeigen",
7
+ "hide": "Verbergen",
8
+ "toggleContent": "Inhalt umschalten",
9
+ "showFeedback": "Feedback anzeigen",
10
+ "hideFeedback": "Feedback ausblenden",
11
+ "correct": "Richtig",
12
+ "incorrect": "Falsch",
13
+ "yourScoreIs": "Ihre Punktzahl",
14
+ "solution": "Lösung",
15
+ "download": "Herunterladen",
16
+ "print": "Drucken",
17
+ "search": "Suche",
18
+ "dataError": "Datenfehler",
19
+ "epubJSerror": "Dies könnte in diesem ePub-Reader nicht funktionieren",
20
+ "epubDisabled": "Diese Aktivität funktioniert im ePub-Format nicht",
21
+ "fullSearch": "Vollständige Suche",
22
+ "noSearchResults": "Keine Ergebnisse",
23
+ "searchResults": "Suchergebnisse für",
24
+ "hideResults": "Ergebnisse ausblenden",
25
+ "block": "block",
26
+ "more": "Mehr",
27
+ "newWindow": "Neues Fenster",
28
+ "fullSize": "Vollgröße",
29
+ "accessibility_tools": "Barrierefreiheitstools",
30
+ "close_toolbar": "Schließen",
31
+ "default_font": "Standard-Schriftart",
32
+ "increase_text_size": "Textgröße erhöhen",
33
+ "decrease_text_size": "Textgröße verringern",
34
+ "uppercase_text": "Großbuchstaben",
35
+ "read": "Lesen",
36
+ "stop_reading": "Lesen stoppen",
37
+ "translate": "Übersetzen",
38
+ "drag_and_drop": "Ziehen und Ablegen",
39
+ "reset": "Zurücksetzen",
40
+ "mode_toggler": "Hell/Dunkel-Modus",
41
+ "teacher_mode": "Lehrer-Modus",
42
+ "elpxGenerating": "Wird generiert...",
43
+ "elpxProcessing": "Verarbeite...",
44
+ "elpxFolderPickerTimeout": "Der Ordner-Auswahldialog hat nicht reagiert. Dies kann passieren, wenn du exportierte Dateien direkt von deinem Gerät öffnest (file://-Protokoll). Versuche, die Datei über einen Server zu öffnen.",
45
+ "elpxFolderPickerEmpty": "Der Ordnerauswahldialog hat keine Dateien gefunden. Dies ist eine bekannte Einschränkung beim Öffnen von exportierten Dateien mit dem file://-Protokoll in einigen Browsern. Versuchen Sie, einen anderen Browser zu verwenden oder öffnen Sie die Datei über einen Webserver.",
46
+ "elpxFileProtocolWarning": "Lokaler Modus: Aufgrund der Sicherheitsrichtlinien des Browsers müssen Sie den Ordner auswählen, aus dem Sie diese Datei geöffnet haben. Bei einem Webserver ist dies nicht erforderlich.",
47
+ "proprietaryLicense": "Proprietäre Lizenz",
48
+ "notAppropriate": "Nicht zutreffend",
49
+ "publicDomain": "Gemeinfrei"
50
+ };
51
+ // The following line should only be used if the ELP contains a hangman game:
52
+ $exe_i18n.exeGames = {
53
+ "hangManGame": "Galgenmännchen-Spiel",
54
+ "accept": "Akzeptieren",
55
+ "yes": "Ja",
56
+ "no": "Nein",
57
+ "right": "Rechts",
58
+ "wrong": "Falsch",
59
+ "rightAnswer": "Richtige Antwort",
60
+ "stat": "Status",
61
+ "selectedLetters": "Ausgewählte Buchstaben",
62
+ "word": "Wort",
63
+ "words": "Wörter",
64
+ "play": "Abspielen",
65
+ "playAgain": "Neu starten",
66
+ "results": "Ergebnisse",
67
+ "total": "Insgesamt",
68
+ "otherWord": "Anderes Wort",
69
+ "gameOver": "Spiel beendet",
70
+ "confirmReload": "Möchten Sie das Spiel neu starten?",
71
+ "clickOnPlay": "Klicken Sie auf \"Spielen\" um zu beginnen",
72
+ "clickOnOtherWord": "Klicken Sie auf \"Ein anderes Wort\" um fortzufahren",
73
+ "az": "abcdefghijklmnopqrstuvwxyz"
74
+ };
75
+
76
+ // Export for Node.js/CommonJS (tests)
77
+ if (typeof module !== 'undefined' && module.exports) {
78
+ module.exports = $exe_i18n;
79
+ }