From ed91c0efc9bf22115d8d3a76baf1e5e55492e38c Mon Sep 17 00:00:00 2001 From: Juan Mauricio Matera Date: Thu, 29 Jan 2026 10:29:58 -0300 Subject: [PATCH 1/4] improve TeXForm --- mathics/builtin/atomic/strings.py | 2 +- mathics/builtin/layout.py | 2 +- mathics/builtin/list/associations.py | 4 +- mathics/builtin/numbers/calculus.py | 4 +- mathics/doc/documentation/1-Manual.mdoc | 6 +- mathics/docpipeline.py | 2 +- mathics/format/render/latex.py | 111 ++++++++++++++++++++++-- test/doc/test_latex.py | 4 +- test/format/format_tests.yaml | 18 ++-- test/format/test_latex.py | 4 +- 10 files changed, 129 insertions(+), 28 deletions(-) diff --git a/mathics/builtin/atomic/strings.py b/mathics/builtin/atomic/strings.py index 2c2326e7a..ad4c42fc0 100644 --- a/mathics/builtin/atomic/strings.py +++ b/mathics/builtin/atomic/strings.py @@ -876,7 +876,7 @@ class ToString(Builtin): >> "U" <> ToString[2] = U2 >> ToString[Integrate[f[x],x], TeXForm] - = \\int f\\left(x\\right) \\, dx + = \\int f(x) \\, dx """ diff --git a/mathics/builtin/layout.py b/mathics/builtin/layout.py index 8ce757748..6caa1170f 100644 --- a/mathics/builtin/layout.py +++ b/mathics/builtin/layout.py @@ -74,7 +74,7 @@ class Format(Builtin): Format can be used to specify the request format: >> Format[Integrate[F[x], x], TeXForm] - = \\int F\\left(x\\right) \\, dx + = \\int F(x) \\, dx Format evaluates its first element before applying the format: >> Format[Integrate[Cos[x], x], TeXForm] diff --git a/mathics/builtin/list/associations.py b/mathics/builtin/list/associations.py index 2bd46eea3..72282cbe6 100644 --- a/mathics/builtin/list/associations.py +++ b/mathics/builtin/list/associations.py @@ -40,8 +40,8 @@ class Association(Builtin): >> <|a -> x, b -> y|> = <|a -> x, b -> y|> - >> Association[{a -> x, b -> y}] - = <|a -> x, b -> y|> + >> Association[{a -> x^2, b -> y}] + = <|a -> x ^ 2, b -> y|> Associations can be nested: >> <|a -> x, b -> y, <|a -> z, d -> t|>|> diff --git a/mathics/builtin/numbers/calculus.py b/mathics/builtin/numbers/calculus.py index b9290e6a4..74df4ecce 100644 --- a/mathics/builtin/numbers/calculus.py +++ b/mathics/builtin/numbers/calculus.py @@ -1007,8 +1007,8 @@ class Integrate(SympyFunction): = Integrate[1, {x, Infinity, 0}] Here how is an example of converting integral equation to TeX: - >> Integrate[f[x], {x, a, b}] // TeXForm - = \int_a^b f\left(x\right) \, dx + >> Integrate[f[x^2], {x, a, b}] // TeXForm + = \int_a^b f\left(x^2\right) \, dx Sometimes there is a loss of precision during integration. You can check the precision of your result with the following sequence \ diff --git a/mathics/doc/documentation/1-Manual.mdoc b/mathics/doc/documentation/1-Manual.mdoc index 433a65c38..80e6cde1f 100644 --- a/mathics/doc/documentation/1-Manual.mdoc +++ b/mathics/doc/documentation/1-Manual.mdoc @@ -942,7 +942,7 @@ For instance, you can override 'MakeBoxes' to format lists in a different way: = {1, 2, 3} >> {1, 2, 3} // TeXForm - = \left[1 2 3\right] + = [1 2 3] However, this will not be accepted as input to \Mathics anymore: >> [1 2 3] @@ -970,7 +970,7 @@ The desired effect can be achieved in the following way: = squared[1, 2] #> squared[1, 2] // TeXForm - = \text{squared}\left[1, 2\right]^2 + = \text{squared}[1, 2]^2 You can view the box structure of a formatted expression using 'ToBoxes': @@ -1115,7 +1115,7 @@ Three-dimensional plots are supported as well: Here are some examples written by Jan Pöschko that come from the very first version.
-Let\'s sketch the function +Let's sketch the function >> f[x_] := 4 x / (x ^ 2 + 3 x + 5) The derivatives are: diff --git a/mathics/docpipeline.py b/mathics/docpipeline.py index 6200150e4..403f3372f 100644 --- a/mathics/docpipeline.py +++ b/mathics/docpipeline.py @@ -274,7 +274,7 @@ def create_output(test_pipeline, tests): if output_format in ("latex", "xml"): def out_wrapper(expr): - return f"{expr} // StandardForm" + return f"StandardForm[{expr}]" else: diff --git a/mathics/format/render/latex.py b/mathics/format/render/latex.py index 797b82cef..b619f067c 100644 --- a/mathics/format/render/latex.py +++ b/mathics/format/render/latex.py @@ -50,6 +50,71 @@ # mathics_scanner does not generates this table in a way that we can load it here. # When it get fixed, we can use that table instead of this one: +BRACKET_INFO = { + ( + String("("), + String(")"), + ): { + "latex_open": "(", + "latex_closing": ")", + "latex_open_large": r"\left(", + "latex_closing_large": r"\right)", + }, + ( + String("{"), + String("}"), + ): { + "latex_open": r"\{", + "latex_closing": r"\}", + "latex_open_large": r"\left\{", + "latex_closing_large": r"\right\}", + }, + ( + String("["), + String("]"), + ): { + "latex_open": "[", + "latex_closing": "]", + "latex_open_large": r"\left[", + "latex_closing_large": r"\right]", + }, + ( + String("\u301A"), + String("\u301B"), + ): { + "latex_open": r"[[", + "latex_closing": "]]", + "latex_open_large": r"\left[\left[", + "latex_closing_large": r"\right]\right]", + }, + ( + String("\u2329"), + String("\u232A"), + ): { + "latex_open": "\\langle", + "latex_closing": "\\rangle", + "latex_open_large": r"\left\langle ", + "latex_closing_large": r"\right\rangle ", + }, + ( + String("\u2016"), + String("\u2016"), + ): { + "latex_open": r"\|", + "latex_closing": r"\|", + "latex_open_large": r"\left\|", + "latex_closing_large": r"\right\| ", + }, + ( + String("<|"), + String("|>"), + ): { + "latex_open": r"\langle\vert ", + "latex_closing": r"\vert\rangle ", + "latex_open_large": r"\left\langle\left\vert ", + "latex_closing_large": r"\right\vert\right\rangle ", + }, +} TEX_REPLACE = { "{": r"\{", @@ -347,13 +412,10 @@ def subsuperscriptbox(self, **options): add_conversion_fn(SubsuperscriptBox, subsuperscriptbox) -def rowbox(self, **options) -> str: - _options = self.box_options.copy() - _options.update(options) - options = _options +def rowbox_sequence(items, **options): parts_str = [ lookup_conversion_method(element, "latex")(element, **options) - for element in self.items + for element in items ] if len(parts_str) == 1: return parts_str[0] @@ -376,6 +438,45 @@ def rowbox(self, **options) -> str: return result +def rowbox_parenthesized(items, **options): + if len(items) < 2: + return None + key = ( + items[0], + items[-1], + ) + try: + bracket_data = BRACKET_INFO[key] + except KeyError: + return None + + contain = rowbox_sequence(items[1:-1], **options) if len(items) > 2 else "" + + if any(c in contain for c in ("\\", "^", "_")): + return f'{bracket_data["latex_open_large"]}{contain}{bracket_data["latex_closing_large"]}' + return f'{bracket_data["latex_open"]}{contain}{bracket_data["latex_closing"]}' + + +def rowbox(self, **options) -> str: + _options = self.box_options.copy() + _options.update(options) + options = _options + items = self.items + # Handle special cases + if len(items) >= 3: + head, *rest = items + rest_latex = rowbox_parenthesized(rest, **options) + if rest_latex is not None: + # Must be a function-like expression f[] + head_latex = lookup_conversion_method(head, "latex")(head, **options) + return head_latex + rest_latex + if len(items) >= 2: + parenthesized_latex = rowbox_parenthesized(items, **options) + if parenthesized_latex is not None: + return parenthesized_latex + return rowbox_sequence(items, **options) + + add_conversion_fn(RowBox, rowbox) diff --git a/test/doc/test_latex.py b/test/doc/test_latex.py index d96d9b6bb..307a5d573 100644 --- a/test/doc/test_latex.py +++ b/test/doc/test_latex.py @@ -83,8 +83,8 @@ def test_load_latex_documentation(): r"\begin{testresult}o\end{testresult}\end{testcase}" ) assert ( - doc_in_section.latex(doc_data)[:40] - ).strip() == "Let\\'s sketch the function\n\\begin{tests}" + doc_in_section.latex(doc_data)[:39] + ).strip() == "Let's sketch the function\n\\begin{tests}" assert ( first_section.latex(doc_data)[:30] ).strip() == "\\section{Curve Sketching}{}" diff --git a/test/format/format_tests.yaml b/test/format/format_tests.yaml index 3a7ad203c..66aef3f60 100644 --- a/test/format/format_tests.yaml +++ b/test/format/format_tests.yaml @@ -288,8 +288,8 @@ latex: System`InputForm: '\text{$<$$\vert$a -$>$ x, b -$>$ y, c -$>$ $<$$\vert$d -$>$ t$\vert$$>$$\vert$$>$}' System`OutputForm: '\text{$<$$\vert$a -$>$ x, b -$>$ y, c -$>$ $<$$\vert$d -$>$ t$\vert$$>$$\vert$$>$}' - System`StandardForm: '\text{$<$$\vert$}a->x, b->y, c->\text{$<$$\vert$}d->t\text{$\vert$$>$}\text{$\vert$$>$}' - System`TraditionalForm: '\text{$<$$\vert$}a->x, b->y, c->\text{$<$$\vert$}d->t\text{$\vert$$>$}\text{$\vert$$>$}' + System`StandardForm: '\left\langle\left\vert a->x, b->y, c->\langle\vert d->t\vert\rangle \right\vert\right\rangle' + System`TraditionalForm: '\left\langle\left\vert a->x, b->y, c->\langle\vert d->t\vert\rangle \right\vert\right\rangle' mathml: System`InputForm: <|a -> x, b -> y, c -> <|d -> t|>|> System`OutputForm: '<|a -> x, b -> y, c -> <|d -> t|>|>' @@ -313,8 +313,8 @@ Association[a -> x, b -> y, c -> Association[d -> t, Association[e -> u]]]: latex: System`InputForm: '\text{$<$$\vert$a -$>$ x, b -$>$ y, c -$>$ $<$$\vert$d -$>$ t, e -$>$ u$\vert$$>$$\vert$$>$}' System`OutputForm: '\text{$<$$\vert$a -$>$ x, b -$>$ y, c -$>$ $<$$\vert$d -$>$ t, e -$>$ u$\vert$$>$$\vert$$>$}' - System`StandardForm: '\text{$<$$\vert$}a->x, b->y, c->\text{$<$$\vert$}d->t, e->u\text{$\vert$$>$}\text{$\vert$$>$}' - System`TraditionalForm: '\text{$<$$\vert$}a->x, b->y, c->\text{$<$$\vert$}d->t, e->u\text{$\vert$$>$}\text{$\vert$$>$}' + System`StandardForm: '\left\langle\left\vert a->x, b->y, c->\langle\vert d->t, e->u\vert\rangle \right\vert\right\rangle' + System`TraditionalForm: '\left\langle\left\vert a->x, b->y, c->\langle\vert d->t, e->u\vert\rangle \right\vert\right\rangle' mathml: System`InputForm: <|a -> x, b -> y, c -> <|d -> t, e -> u|>|> System`OutputForm: '<|a -> x, b -> y, c -> <|d -> t, e -> u|>|>' @@ -556,8 +556,8 @@ Integrate[F[x], {x, a, g[b]}]: latex: System`InputForm: \text{Integrate[F[x], \{x, a, g[b]\}]} System`OutputForm: '\text{Integrate[F[x], \{x, a, g[b]\}]}' - System`StandardForm: \int_a^{g\left[b\right]} F\left[x\right] \, dx - System`TraditionalForm: \int_a^{g\left(b\right)} F\left(x\right) \, dx + System`StandardForm: \int_a^{g[b]} F[x] \, dx + System`TraditionalForm: \int_a^{g(b)} F(x) \, dx mathml: System`InputForm: Integrate[F[x], {x, a, g[b]}] System`OutputForm: 'Integrate[F[x], {x, a, g[b]}]' @@ -840,8 +840,8 @@ a^(g[b]/c): latex: System`InputForm: \text{a${}^{\wedge}$(g[b]/c)} System`OutputForm: '\text{a ${}^{\wedge}$ (g[b] / c)}' - System`StandardForm: a^{\frac{g\left[b\right]}{c}} - System`TraditionalForm: a^{\frac{g\left(b\right)}{c}} + System`StandardForm: a^{\frac{g[b]}{c}} + System`TraditionalForm: a^{\frac{g(b)}{c}} mathml: System`InputForm: a^(g[b]/c) System`OutputForm: 'a ^ (g[b] / c)' @@ -905,7 +905,7 @@ a+PrecedenceForm[b+c,10]: msg: "PrecedenceForm" latex: System`OutputForm: '\text{a + (b + c)}' - System`StandardForm: 'a+\left(b+c\right)' + System`StandardForm: 'a+(b+c)' mathml: System`OutputForm: 'a + (b + c)' System`StandardForm: 'a + ( b + c )' diff --git a/test/format/test_latex.py b/test/format/test_latex.py index 374fad126..c50fb1c29 100644 --- a/test/format/test_latex.py +++ b/test/format/test_latex.py @@ -26,9 +26,9 @@ def get_latex(wl_expression): ('"_"', r"\text{\_}"), ('"["', r"\text{[}"), ('"]"', r"\text{]}"), - ("HoldForm[A[[1,2]]]", r"A\left[\left[1, 2\right]\right]"), + ("HoldForm[A[[1,2]]]", r"A[[1, 2]]"), ('"wrong ]"', r"\text{wrong ]}"), - ("Integrate[F[x],x]", r"\int F\left[x\right] \, dx"), + ("Integrate[F[x],x]", r"\int F[x] \, dx"), ("Cap[c,b]", r"c \cap b"), ("CupCap[c,b]", r"c \stackrel{\smile}{\frown} b"), ("Congruent[c,b]", r"c \equiv b"), From bb2f70d728b1ac9ce5a86ec09e7a05e846ff6226 Mon Sep 17 00:00:00 2001 From: Juan Mauricio Matera Date: Fri, 30 Jan 2026 13:51:56 -0300 Subject: [PATCH 2/4] handle empty RowBox.items. Use instead of checking for characters. --- mathics/format/render/latex.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mathics/format/render/latex.py b/mathics/format/render/latex.py index b619f067c..d92585b03 100644 --- a/mathics/format/render/latex.py +++ b/mathics/format/render/latex.py @@ -417,6 +417,8 @@ def rowbox_sequence(items, **options): lookup_conversion_method(element, "latex")(element, **options) for element in items ] + if len(parts_str) == 0: + return "" if len(parts_str) == 1: return parts_str[0] # This loop integrate all the row adding spaces after a ",", followed @@ -445,14 +447,15 @@ def rowbox_parenthesized(items, **options): items[0], items[-1], ) + items = items[1:-1] try: bracket_data = BRACKET_INFO[key] except KeyError: return None - contain = rowbox_sequence(items[1:-1], **options) if len(items) > 2 else "" + contain = rowbox_sequence(items, **options) if len(items) > 0 else "" - if any(c in contain for c in ("\\", "^", "_")): + if any(item.is_multiline for item in items): return f'{bracket_data["latex_open_large"]}{contain}{bracket_data["latex_closing_large"]}' return f'{bracket_data["latex_open"]}{contain}{bracket_data["latex_closing"]}' From 430c074439be83f52523e598933049ff8f130314 Mon Sep 17 00:00:00 2001 From: Juan Mauricio Matera Date: Fri, 30 Jan 2026 14:55:48 -0300 Subject: [PATCH 3/4] adjust format tests --- test/format/format_tests.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/format/format_tests.yaml b/test/format/format_tests.yaml index 66aef3f60..14d511606 100644 --- a/test/format/format_tests.yaml +++ b/test/format/format_tests.yaml @@ -288,8 +288,8 @@ latex: System`InputForm: '\text{$<$$\vert$a -$>$ x, b -$>$ y, c -$>$ $<$$\vert$d -$>$ t$\vert$$>$$\vert$$>$}' System`OutputForm: '\text{$<$$\vert$a -$>$ x, b -$>$ y, c -$>$ $<$$\vert$d -$>$ t$\vert$$>$$\vert$$>$}' - System`StandardForm: '\left\langle\left\vert a->x, b->y, c->\langle\vert d->t\vert\rangle \right\vert\right\rangle' - System`TraditionalForm: '\left\langle\left\vert a->x, b->y, c->\langle\vert d->t\vert\rangle \right\vert\right\rangle' + System`StandardForm: '\langle\vert a->x, b->y, c->\langle\vert d->t\vert\rangle \vert\rangle' + System`TraditionalForm: '\langle\vert a->x, b->y, c->\langle\vert d->t\vert\rangle \vert\rangle' mathml: System`InputForm: <|a -> x, b -> y, c -> <|d -> t|>|> System`OutputForm: '<|a -> x, b -> y, c -> <|d -> t|>|>' @@ -313,8 +313,8 @@ Association[a -> x, b -> y, c -> Association[d -> t, Association[e -> u]]]: latex: System`InputForm: '\text{$<$$\vert$a -$>$ x, b -$>$ y, c -$>$ $<$$\vert$d -$>$ t, e -$>$ u$\vert$$>$$\vert$$>$}' System`OutputForm: '\text{$<$$\vert$a -$>$ x, b -$>$ y, c -$>$ $<$$\vert$d -$>$ t, e -$>$ u$\vert$$>$$\vert$$>$}' - System`StandardForm: '\left\langle\left\vert a->x, b->y, c->\langle\vert d->t, e->u\vert\rangle \right\vert\right\rangle' - System`TraditionalForm: '\left\langle\left\vert a->x, b->y, c->\langle\vert d->t, e->u\vert\rangle \right\vert\right\rangle' + System`StandardForm: '\langle\vert a->x, b->y, c->\langle\vert d->t, e->u\vert\rangle \vert\rangle' + System`TraditionalForm: '\langle\vert a->x, b->y, c->\langle\vert d->t, e->u\vert\rangle \vert\rangle' mathml: System`InputForm: <|a -> x, b -> y, c -> <|d -> t, e -> u|>|> System`OutputForm: '<|a -> x, b -> y, c -> <|d -> t, e -> u|>|>' From 7d33b83a3401a4e85cd9928bd04207390deb9222 Mon Sep 17 00:00:00 2001 From: "R. Bernstein" Date: Tue, 3 Feb 2026 05:53:58 -0500 Subject: [PATCH 4/4] Don't hardcode unicode-symbols (#1673) Don't hardcode Unicode symbols. Also, `op-tables.json` is renamed `character-tables.json`, since that's what it is. --- .github/workflows/pyodide.yml | 2 +- Makefile | 10 +++++----- admin-tools/make-JSON-tables.sh | 11 +---------- mathics/core/convert/op.py | 3 ++- mathics/data/.gitignore | 2 +- mathics/format/render/latex.py | 19 ++++++++++--------- setup.py | 12 +++--------- 7 files changed, 23 insertions(+), 36 deletions(-) diff --git a/.github/workflows/pyodide.yml b/.github/workflows/pyodide.yml index dfea4b728..52b0eba21 100644 --- a/.github/workflows/pyodide.yml +++ b/.github/workflows/pyodide.yml @@ -58,5 +58,5 @@ jobs: python -m pip install --no-build-isolation -e git+https://github.com/Mathics3/mathics-scanner#egg=Mathics-Scanner pip install --no-build-isolation -e . - make mathics/data/op-tables.json mathics/data/operator-tables.json + make mathics/data/character-tables.json mathics/data/operator-tables.json make -j3 check diff --git a/Makefile b/Makefile index 95fa2df8a..1bd9e3e6a 100644 --- a/Makefile +++ b/Makefile @@ -69,17 +69,17 @@ build: # because pip install doesn't handle # INSTALL_REQUIRES properly #: Set up to run from the source tree -develop: mathics/data/op-tables.json mathics/data/operator-tables.json +develop: mathics/data/character-tables.json mathics/data/operator-tables.json $(PIP) install -e .[dev] # See note above on ./setup.py #: Set up to run from the source tree with full dependencies -develop-full: mathics/data/op-tables.json mathics/data/operators.json +develop-full: mathics/data/character-tables.json mathics/data/operators.json $(PIP) install -e .[dev,full] # See note above on ./setup.py #: Set up to run from the source tree with full dependencies and Cython -develop-full-cython: mathics/data/op-tables.json mathics/data/operators.json +develop-full-cython: mathics/data/character-tables.json mathics/data/operators.json $(PIP) install -e .[dev,full,cython] @@ -126,7 +126,7 @@ clean: clean-cython clean-cache ($(MAKE) -C "$$dir" clean); \ done; \ rm -f factorials || true; \ - rm -f mathics/data/op-tables || true; \ + rm -f mathics/data/character-tables.json || true; \ rm -rf build || true mypy: @@ -166,7 +166,7 @@ latexdoc texdoc doc: (cd mathics/doc/latex && $(MAKE) doc) #: Build JSON ASCII to unicode opcode table and operator table -mathics/data/operator-tables.json mathics/data/op-tables.json mathics/data/operators.json: +mathics/data/operator-tables.json mathics/data/character-tables.json mathics/data/operators.json: $(BASH) ./admin-tools/make-JSON-tables.sh #: Remove ChangeLog diff --git a/admin-tools/make-JSON-tables.sh b/admin-tools/make-JSON-tables.sh index 5172988e8..a9d802a8d 100755 --- a/admin-tools/make-JSON-tables.sh +++ b/admin-tools/make-JSON-tables.sh @@ -5,16 +5,7 @@ mydir=$(dirname $bs) PYTHON=${PYTHON:-python} cd $mydir/../mathics/data -mathics3-generate-json-table \ - --field=latex-named-characters \ - --field=unicode-to-latex \ - --field=ascii-operator-to-symbol \ - --field=ascii-operator-to-unicode \ - --field=ascii-operator-to-wl-unicode \ - --field=operator-to-ascii \ - --field=operator-to-amslatex \ - --field=operator-to-unicode \ - -o op-tables.json +mathics3-generate-json-table -o character-tables.json mathics3-generate-operator-json-table -o operator-tables.json # tokenizer looks for the table in the default place... mathics3-generate-operator-json-table diff --git a/mathics/core/convert/op.py b/mathics/core/convert/op.py index 8ec8e1e8e..0ba25c99f 100644 --- a/mathics/core/convert/op.py +++ b/mathics/core/convert/op.py @@ -15,7 +15,7 @@ # Load the conversion tables from disk -characters_path = osp.join(ROOT_DIR, "data", "op-tables.json") +characters_path = osp.join(ROOT_DIR, "data", "character-tables.json") assert osp.exists( characters_path ), f"ASCII operator to Unicode tables are missing from {characters_path}" @@ -24,6 +24,7 @@ ascii_operator_to_symbol = OPERATOR_CONVERSION_TABLES["ascii-operator-to-symbol"] builtin_constants = OPERATOR_CONVERSION_TABLES["builtin-constants"] +named_characters = OPERATOR_CONVERSION_TABLES["named-characters"] operator_to_unicode = OPERATOR_CONVERSION_TABLES["operator-to-unicode"] operator_to_ascii = OPERATOR_CONVERSION_TABLES["operator-to-ascii"] unicode_operator_to_ascii = { diff --git a/mathics/data/.gitignore b/mathics/data/.gitignore index ba1ae5260..9c07e628a 100644 --- a/mathics/data/.gitignore +++ b/mathics/data/.gitignore @@ -1,5 +1,5 @@ /.python-version /doc_latex_data.pcl /doctest_latex_data.pcl -/op-tables.json +/character-tables.json /operator-tables.json diff --git a/mathics/format/render/latex.py b/mathics/format/render/latex.py index d92585b03..b6dd78f98 100644 --- a/mathics/format/render/latex.py +++ b/mathics/format/render/latex.py @@ -7,7 +7,7 @@ LaTeX formatting is usually initiated in Mathics via TeXForm[]. TeXForm in WMA is slightly vague or misleading since the output is -typically LaTeX rather than Plain TeX. In Mathics, we also assume AMS +typically LaTeX rather than Plain TeX. In Mathics3, we also assume AMS LaTeX or more specifically that we the additional AMS Mathematical Symbols exist. """ @@ -37,6 +37,7 @@ UNICODE_TO_AMSLATEX, UNICODE_TO_LATEX, get_latex_operator, + named_characters, ) from mathics.core.exceptions import BoxConstructError from mathics.core.formatter import ( @@ -79,8 +80,8 @@ "latex_closing_large": r"\right]", }, ( - String("\u301A"), - String("\u301B"), + String(named_characters["LeftDoubleBracket"]), + String(named_characters["RightDoubleBracket"]), ): { "latex_open": r"[[", "latex_closing": "]]", @@ -88,8 +89,8 @@ "latex_closing_large": r"\right]\right]", }, ( - String("\u2329"), - String("\u232A"), + String(named_characters["LeftAngleBracket"]), + String(named_characters["RightAngleBracket"]), ): { "latex_open": "\\langle", "latex_closing": "\\rangle", @@ -97,8 +98,8 @@ "latex_closing_large": r"\right\rangle ", }, ( - String("\u2016"), - String("\u2016"), + String(named_characters["LeftDoubleBracketingBar"]), + String(named_characters["RightDoubleBracketingBar"]), ): { "latex_open": r"\|", "latex_closing": r"\|", @@ -358,9 +359,9 @@ def superscriptbox(self, **options): sup_string = self.superindex.get_string_value() # Handle derivatives - if sup_string == "\u2032": + if sup_string == named_characters["Prime"]: return "%s'" % tex1 - if sup_string == "\u2032\u2032": + if sup_string == named_characters["Prime"] * 2: return "%s''" % tex1 base = self.tex_block(tex1, True) superidx_to_tex = lookup_conversion_method(self.superindex, "latex") diff --git a/setup.py b/setup.py index 0998ddeeb..1bba72e84 100644 --- a/setup.py +++ b/setup.py @@ -109,21 +109,15 @@ def get_srcdir(): class build_py(setuptools_build_py): def run(self): - if not os.path.exists("mathics/data/op-tables.json"): + if not os.path.exists("mathics/data/character-tables.json"): os.system( - "mathics3-generate-json-table" - " --field=ascii-operator-to-symbol" - " --field=ascii-operator-to-unicode" - " --field=ascii-operator-to-wl-unicode" - " --field=operator-to-ascii" - " --field=operator-to-unicode" - " -o mathics/data/op-tables.json" + "mathics3-generate-json-table" " -o mathics/data/character-tables.json" ) if not os.path.exists("mathics/data/operator-tables.json"): os.system( "mathics3-generate-operator-json-table" " -o operator-tables.json" ) - self.distribution.package_data["mathics"].append("data/op-tables.json") + self.distribution.package_data["mathics"].append("data/character-tables.json") setuptools_build_py.run(self)