regen.mde 0.2.2 → 0.7.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.
- package/README.md +409 -295
- package/bin/build-corpus-editor.js +5 -3
- package/bin/postinstall.js +259 -187
- package/bin/regen-mdeditor-install.js +1 -1
- package/bin/regen-mdeditor-uninstall.js +1 -1
- package/desktop/BuildCorpusEditor/BuildCorpusBridge.cs +493 -270
- package/desktop/BuildCorpusEditor/EditorForm.cs +853 -540
- package/desktop/BuildCorpusEditor/Program.cs +85 -81
- package/dist/release/regen-mde-0.3.0-win-x64-setup.exe +0 -0
- package/dist/release/{regen.mde-0.2.2-win-x64.zip → regen-mde-0.3.0-win-x64.zip} +0 -0
- package/dist/release/regen-mde-0.7.0-win-x64-setup.exe +0 -0
- package/dist/release/regen-mde-0.7.0-win-x64.zip +0 -0
- package/dist/windows-editor/BuildCorpusEditor.dll +0 -0
- package/dist/windows-editor/BuildCorpusEditor.exe +0 -0
- package/dist/windows-editor/BuildCorpusEditor.pdb +0 -0
- package/dist/windows-editor/wwwroot/assets/index-C_VxJk4k.js +375 -0
- package/dist/windows-editor/wwwroot/assets/index-Wt9zSjIw.css +1 -0
- package/dist/windows-editor/wwwroot/index.html +3 -3
- package/editor-web/index.html +1 -1
- package/editor-web/src/main.jsx +1044 -399
- package/editor-web/src/styles.css +846 -602
- package/installer/install-regen-mde.ps1 +49 -10
- package/installer/regen-mde.nsi +16 -16
- package/package.json +90 -86
- package/pyproject.toml +35 -33
- package/requirements.txt +6 -4
- package/scripts/package-windows-editor.ps1 +8 -8
- package/scripts/release-dual.mjs +105 -0
- package/scripts/run-editor-implementation-plane.ps1 +29 -6
- package/src/build_corpus/docx_exporter.py +1055 -798
- package/src/build_corpus/equations.py +80 -0
- package/src/build_corpus/exporter.py +1488 -1195
- package/src/build_corpus/frontmatter.py +302 -0
- package/src/build_corpus/ppt_exporter.py +543 -532
- package/dist/release/regen.mde-0.2.2-win-x64-setup.exe +0 -0
- package/dist/windows-editor/wwwroot/assets/index-DjJ6xmhy.js +0 -326
- package/dist/windows-editor/wwwroot/assets/index-_dwMNNsm.css +0 -1
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""LaTeX -> OMML (Office Math) conversion for Markdown -> Word export.
|
|
2
|
+
|
|
3
|
+
Word renders equations from OMML (`<m:oMath>`), not from raw text. The previous
|
|
4
|
+
exporter only set the font to "Cambria Math" and emitted the LaTeX source as
|
|
5
|
+
literal characters, so anything with real commands (\\sum, \\Delta, \\rightarrow,
|
|
6
|
+
\\leq) showed up as raw text. This module performs a genuine conversion:
|
|
7
|
+
|
|
8
|
+
LaTeX --(latex2mathml)--> presentation MathML --(mathml2omml)--> OMML
|
|
9
|
+
|
|
10
|
+
and returns a parsed `<m:oMath>` / `<m:oMathPara>` element ready to splice into a
|
|
11
|
+
python-docx paragraph. On any failure it returns ``None`` so callers can fall
|
|
12
|
+
back to plain text rather than crash.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
from docx.oxml import parse_xml
|
|
18
|
+
from docx.oxml.ns import nsdecls
|
|
19
|
+
|
|
20
|
+
_MATH_NS = "http://schemas.openxmlformats.org/officeDocument/2006/math"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _latex_to_omml_string(latex: str) -> str | None:
|
|
24
|
+
"""Convert a LaTeX fragment to an OMML `<m:oMath>` XML string, or None."""
|
|
25
|
+
latex = latex.strip()
|
|
26
|
+
if not latex:
|
|
27
|
+
return None
|
|
28
|
+
try:
|
|
29
|
+
# Imported lazily so a missing optional dependency degrades to plain
|
|
30
|
+
# text instead of breaking the whole export.
|
|
31
|
+
import latex2mathml.converter as _l2m
|
|
32
|
+
from mathml2omml import convert as _mml2omml
|
|
33
|
+
except Exception:
|
|
34
|
+
return None
|
|
35
|
+
try:
|
|
36
|
+
mathml = _l2m.convert(latex)
|
|
37
|
+
omml = _mml2omml(mathml)
|
|
38
|
+
except Exception:
|
|
39
|
+
return None
|
|
40
|
+
if not omml or "oMath" not in omml:
|
|
41
|
+
return None
|
|
42
|
+
return omml
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _parse_with_namespaces(omml: str):
|
|
46
|
+
"""Parse an OMML fragment, injecting the math/word namespace decls."""
|
|
47
|
+
decls = nsdecls("m", "w")
|
|
48
|
+
for tag in ("<m:oMath>", "<m:oMathPara>"):
|
|
49
|
+
if omml.startswith(tag):
|
|
50
|
+
opener = tag[:-1] + f" {decls}>"
|
|
51
|
+
omml = opener + omml[len(tag):]
|
|
52
|
+
break
|
|
53
|
+
else:
|
|
54
|
+
return None
|
|
55
|
+
try:
|
|
56
|
+
return parse_xml(omml)
|
|
57
|
+
except Exception:
|
|
58
|
+
return None
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def latex_to_omath(latex: str):
|
|
62
|
+
"""Return an inline `<m:oMath>` element for ``latex``, or None on failure."""
|
|
63
|
+
omml = _latex_to_omml_string(latex)
|
|
64
|
+
if omml is None:
|
|
65
|
+
return None
|
|
66
|
+
return _parse_with_namespaces(omml)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def latex_to_omath_para(latex: str):
|
|
70
|
+
"""Return a display `<m:oMathPara>` element for ``latex``, or None.
|
|
71
|
+
|
|
72
|
+
Wraps the inline `<m:oMath>` in `<m:oMathPara>` so Word treats it as a
|
|
73
|
+
centered display equation on its own line.
|
|
74
|
+
"""
|
|
75
|
+
omml = _latex_to_omml_string(latex)
|
|
76
|
+
if omml is None:
|
|
77
|
+
return None
|
|
78
|
+
if omml.startswith("<m:oMath>"):
|
|
79
|
+
omml = "<m:oMathPara>" + omml + "</m:oMathPara>"
|
|
80
|
+
return _parse_with_namespaces(omml)
|