diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index fa02854d3..7aaed5a8c 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -28,10 +28,9 @@ jobs: python -m pip install --upgrade pip - name: Install Mathics3 with full Python dependencies run: | - python -m pip install -e git+https://github.com/Mathics3/mathics-scanner#egg=Mathics-Scanner[full] # We can comment out after next Mathics-Scanner release # python -m pip install Mathics-Scanner[full] - # python -m pip install -e git+https://github.com/Mathics3/mathics-scanner#egg=Mathics-Scanner[full] + python -m pip install -e git+https://github.com/Mathics3/mathics-scanner#egg=Mathics-Scanner[full] pip install -e . remake -x develop-full - name: Test Mathics3 diff --git a/.github/workflows/plot-tests.yml b/.github/workflows/plot-tests.yml index a7afa1da5..2dad1867e 100644 --- a/.github/workflows/plot-tests.yml +++ b/.github/workflows/plot-tests.yml @@ -25,9 +25,8 @@ jobs: run: | python -m pip install --upgrade pip # We can comment out after next Mathics-Scanner release - # python -m pip install -e git+https://github.com/Mathics3/mathics-scanner#egg=Mathics-Scanner[full] + python -m pip install -e git+https://github.com/Mathics3/mathics-scanner#egg=Mathics-Scanner[full] git clone --depth 1 https://github.com/Mathics3/mathics-scanner.git - # git clone --single-branch --branch operator-refactor-part1.5 https://github.com/Mathics3/mathics-scanner.git cd mathics-scanner/ pip install -e . cd .. diff --git a/.github/workflows/pyodide.yml b/.github/workflows/pyodide.yml index baa7834d1..dfea4b728 100644 --- a/.github/workflows/pyodide.yml +++ b/.github/workflows/pyodide.yml @@ -55,9 +55,7 @@ jobs: pip install "setuptools>=70.0.0" PyYAML click packaging pytest # We can comment out after next Mathics-Scanner release - # python -m pip install --no-build-isolation -e git+https://github.com/Mathics3/mathics-scanner#egg=Mathics-Scanner - # pip install --no-build-isolation -e . - # cd .. + 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 diff --git a/.github/workflows/ubuntu-bench.yml b/.github/workflows/ubuntu-bench.yml index 501629714..a958f7a02 100644 --- a/.github/workflows/ubuntu-bench.yml +++ b/.github/workflows/ubuntu-bench.yml @@ -26,8 +26,8 @@ jobs: python -m pip install --upgrade pip python -m pip install pytest-benchmark # We can comment out after next Mathics-Scanner release + python -m pip install -e git+https://github.com/Mathics3/mathics-scanner#egg=Mathics-Scanner[full] # python -m pip install Mathics-Scanner[full] - # python -m pip install -e git+https://github.com/Mathics3/mathics-scanner#egg=Mathics-Scanner[full] pip install -e . remake -x develop - name: Test Mathics diff --git a/.github/workflows/ubuntu-cython.yml b/.github/workflows/ubuntu-cython.yml index 453745833..17d83064a 100644 --- a/.github/workflows/ubuntu-cython.yml +++ b/.github/workflows/ubuntu-cython.yml @@ -25,7 +25,7 @@ jobs: sudo apt-get update -qq && sudo apt-get install -qq liblapack-dev llvm-dev tesseract-ocr python -m pip install --upgrade pip # We can comment out after next Mathics-Scanner release - # python -m pip install -e git+https://github.com/Mathics3/mathics-scanner#egg=Mathics-Scanner[full] + python -m pip install -e git+https://github.com/Mathics3/mathics-scanner#egg=Mathics-Scanner[full] pip install -e . cd .. diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 640f5e5db..da2a005bf 100755 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -34,7 +34,7 @@ jobs: - name: Install Mathics3 with Python dependencies run: | # We can comment out after next Mathics-Scanner release - # python -m pip install -e git+https://github.com/Mathics3/mathics-scanner#egg=Mathics-Scanner[full] + python -m pip install -e git+https://github.com/Mathics3/mathics-scanner#egg=Mathics-Scanner[full] pip install -e . # python -m pip install Mathics-Scanner[full] diff --git a/mathics/builtin/files_io/files.py b/mathics/builtin/files_io/files.py index 61b700b27..b2f33238b 100644 --- a/mathics/builtin/files_io/files.py +++ b/mathics/builtin/files_io/files.py @@ -34,7 +34,6 @@ SymbolFailed, SymbolHold, SymbolHoldExpression, - SymbolInputForm, SymbolInputStream, SymbolOutputForm, SymbolOutputStream, @@ -50,6 +49,7 @@ ) from mathics.eval.makeboxes import do_format, format_element from mathics.eval.stackframe import get_eval_Expression +from mathics.form import render_input_form class Input_(Predefined): @@ -596,11 +596,11 @@ def eval_input(self, exprs, name, n, evaluation: Evaluation): # Eventually, we are going to replace this by a `MakeBoxes` call. def do_format_output(expr, evaluation): try: - boxed_expr = format_element(expr, evaluation, SymbolInputForm) + # TODO: set character encoding? + return render_input_form(expr, evaluation) except BoxError: boxed_expr = format_element(expr, evaluation, SymbolFullForm) - - return boxed_expr.boxes_to_text() + return boxed_expr.boxes_to_text() text = [do_format_output(expr, evaluation) for expr in exprs.get_sequence()] text = "\n".join(text) + "\n" diff --git a/mathics/builtin/forms/output.py b/mathics/builtin/forms/output.py index 027591ab1..369103212 100644 --- a/mathics/builtin/forms/output.py +++ b/mathics/builtin/forms/output.py @@ -14,7 +14,7 @@ """ from typing import Optional -from mathics.builtin.box.layout import RowBox, StyleBox, TagBox +from mathics.builtin.box.layout import InterpretationBox, RowBox, StyleBox, TagBox from mathics.builtin.forms.base import FormBaseClass from mathics.core.atoms import Integer, Real, String, StringFromPython from mathics.core.builtin import Builtin @@ -32,6 +32,7 @@ from mathics.core.systemsymbols import ( SymbolAutomatic, SymbolInfinity, + SymbolInputForm, SymbolMakeBoxes, SymbolNumberForm, SymbolRowBox, @@ -48,6 +49,7 @@ eval_tableform, eval_texform, ) +from mathics.form import render_input_form class BaseForm(FormBaseClass): @@ -184,29 +186,74 @@ def eval_mathml(self, expr, evaluation) -> Expression: class InputForm(FormBaseClass): r""" - - :WMA link: - https://reference.wolfram.com/language/ref/InputForm.html + + :WMA link: + https://reference.wolfram.com/language/ref/InputForm.html -
-
'InputForm'[$expr$] -
displays $expr$ in an unambiguous form suitable for input. -
+
+
'InputForm'[$expr$] +
displays $expr$ in an unambiguous form suitable for input to Mathics3. +
- >> InputForm[a + b * c] - = a + b*c - >> InputForm["A string"] - = "A string" - >> InputForm[f'[x]] - = Derivative[1][f][x] - >> InputForm[Derivative[1, 0][f][x]] - = Derivative[1, 0][f][x] + 'InputForm' produces one-dimensional output that is suitable for input to Mathics3: + + >> InputForm["A string"] + = "A string" + + >> InputForm[f'[x]] + = Derivative[1][f][x] + + >> InputForm[Derivative[1, 0][f][x]] + = Derivative[1, 0][f][x] + + 'InputForm' shows arithmetic expressions in traditional mathematical notation: + + >> 2+F[x] // InputForm + = 2 + F[x] + + Compare this to 'FullForm': + + >> 2+F[x] // FullForm + = Plus[2, F[x]] + + 'InputForm' output can be altered via 'Format' assignment : + + >> Format[Foo[x], InputForm] := Bar + + >> Foo[x] // InputForm + = Bar + + In contrast, 'FullForm' output is not altered via 'Format' assignment : + >> Format[Foo[x], InputForm] := Baz + + >> Foo[x] // FullForm + = Foo[x] """ in_outputforms = True in_printforms = True summary_text = "plain-text input format" + # TODO: eventually, remove OutputForm in the second argument. + def eval_makeboxes(self, expr, evaluation): + """MakeBoxes[InputForm[expr_], Alternatives[StandardForm,TraditionalForm,OutputForm]]""" + + inputform = String(render_input_form(expr, evaluation)) + inputform = StyleBox( + inputform, + **{ + "System`ShowSpecialCharacters": SymbolFalse, + "System`ShowStringCharacters": SymbolTrue, + "System`NumberMarks": SymbolTrue, + }, + ) + expr = Expression(SymbolInputForm, expr) + return InterpretationBox( + inputform, + expr, + **{"System`Editable": SymbolTrue, "System`AutoDelete": SymbolTrue}, + ) + class _NumberForm(Builtin): """ diff --git a/mathics/builtin/makeboxes.py b/mathics/builtin/makeboxes.py index 4b314d633..4a4df8580 100644 --- a/mathics/builtin/makeboxes.py +++ b/mathics/builtin/makeboxes.py @@ -92,14 +92,13 @@ class MakeBoxes(Builtin): rules = { "MakeBoxes[Infix[head_[elements___]], " - " f:StandardForm|TraditionalForm|OutputForm|InputForm]": ( + " f:StandardForm|TraditionalForm|OutputForm]": ( 'MakeBoxes[Infix[head[elements], StringForm["~`1`~", head]], f]' ), "MakeBoxes[expr_]": "MakeBoxes[expr, StandardForm]", "MakeBoxes[(form:StandardForm|TraditionalForm|OutputForm|TeXForm|" "MathMLForm)[expr_], StandardForm|TraditionalForm]": ("MakeBoxes[expr, form]"), "MakeBoxes[(form:StandardForm|OutputForm|MathMLForm|TeXForm)[expr_], OutputForm]": "MakeBoxes[expr, form]", - "MakeBoxes[InputForm[expr_], StandardForm|TraditionalForm|OutputForm]": "StyleBox[MakeBoxes[expr, InputForm], ShowStringCharacters->True]", "MakeBoxes[PrecedenceForm[expr_, prec_], f_]": "MakeBoxes[expr, f]", "MakeBoxes[Style[expr_, OptionsPattern[Style]], f_]": ( "StyleBox[MakeBoxes[expr, f], " @@ -114,12 +113,12 @@ def eval_fullform(self, expr, evaluation): def eval_general(self, expr, f, evaluation): """MakeBoxes[expr_, - f:TraditionalForm|StandardForm|OutputForm|InputForm]""" + f:TraditionalForm|StandardForm|OutputForm]""" return eval_generic_makeboxes(self, expr, f, evaluation) def eval_outerprecedenceform(self, expr, precedence, form, evaluation): """MakeBoxes[PrecedenceForm[expr_, precedence_], - form:StandardForm|TraditionalForm|OutputForm|InputForm]""" + form:StandardForm|TraditionalForm|OutputForm]""" py_precedence = precedence.get_int_value() boxes = MakeBoxes(expr, form) @@ -127,13 +126,13 @@ def eval_outerprecedenceform(self, expr, precedence, form, evaluation): def eval_postprefix(self, p, expr, h, precedence, form, evaluation): """MakeBoxes[(p:Prefix|Postfix)[expr_, h_, precedence_:None], - form:StandardForm|TraditionalForm|OutputForm|InputForm]""" + form:StandardForm|TraditionalForm|OutputForm]""" return eval_postprefix(self, p, expr, h, precedence, form, evaluation) def eval_infix( self, expr, operator, precedence: Integer, grouping, form: Symbol, evaluation ): - """MakeBoxes[Infix[expr_, operator_, precedence_:None, grouping_:None], form:StandardForm|TraditionalForm|OutputForm|InputForm]""" + """MakeBoxes[Infix[expr_, operator_, precedence_:None, grouping_:None], form:StandardForm|TraditionalForm|OutputForm]""" return eval_infix(self, expr, operator, precedence, grouping, form, evaluation) diff --git a/mathics/core/parser/operators.py b/mathics/core/parser/operators.py index ab6e8814e..cc72da78a 100644 --- a/mathics/core/parser/operators.py +++ b/mathics/core/parser/operators.py @@ -35,6 +35,9 @@ nonassoc_binary_operators = OPERATOR_DATA["non-associative-binary-operators"] operator_precedences = OPERATOR_DATA["operator-precedences"] operator_to_amslatex = OPERATOR_DATA["operator-to-amslatex"] +operator_to_string = OPERATOR_DATA[ + "operator-to_string" +] # FIXME: should be operator-to-string postfix_operators = OPERATOR_DATA["postfix-operators"] prefix_operators = OPERATOR_DATA["prefix-operators"] right_binary_operators = OPERATOR_DATA["right-binary-operators"] diff --git a/mathics/doc/documentation/1-Manual.mdoc b/mathics/doc/documentation/1-Manual.mdoc index 0daad605d..5b717de11 100644 --- a/mathics/doc/documentation/1-Manual.mdoc +++ b/mathics/doc/documentation/1-Manual.mdoc @@ -1224,16 +1224,16 @@ A dice object shall be displayed as a rectangle with the given number of points #> Definition[Dice] = Attributes[Dice] = {Orderless} - . - . Format[Dice[n_Integer ? (1 <= #1 <= 6&)], MathMLForm] = Block[{p = 0.2, r = 0.05}, Graphics[{EdgeForm[Black], White, Rectangle[], Black, EdgeForm[], If[OddQ[n], Disk[{0.5, 0.5}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{p, p}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{Plus[1, Times[-1, p]], Plus[1, Times[-1, p]]}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{p, Plus[1, Times[-1, p]]}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{Plus[1, Times[-1, p]], p}, r]], If[n === 6, {Disk[{p, 0.5}, r], Disk[{Plus[1, Times[-1, p]], 0.5}, r]}]}, ImageSize -> Tiny]] - . - . Format[Dice[n_Integer ? (1 <= #1 <= 6&)], OutputForm] = Block[{p = 0.2, r = 0.05}, Graphics[{EdgeForm[Black], White, Rectangle[], Black, EdgeForm[], If[OddQ[n], Disk[{0.5, 0.5}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{p, p}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{Plus[1, Times[-1, p]], Plus[1, Times[-1, p]]}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{p, Plus[1, Times[-1, p]]}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{Plus[1, Times[-1, p]], p}, r]], If[n === 6, {Disk[{p, 0.5}, r], Disk[{Plus[1, Times[-1, p]], 0.5}, r]}]}, ImageSize -> Tiny]] - . - . Format[Dice[n_Integer ? (1 <= #1 <= 6&)], StandardForm] = Block[{p = 0.2, r = 0.05}, Graphics[{EdgeForm[Black], White, Rectangle[], Black, EdgeForm[], If[OddQ[n], Disk[{0.5, 0.5}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{p, p}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{Plus[1, Times[-1, p]], Plus[1, Times[-1, p]]}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{p, Plus[1, Times[-1, p]]}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{Plus[1, Times[-1, p]], p}, r]], If[n === 6, {Disk[{p, 0.5}, r], Disk[{Plus[1, Times[-1, p]], 0.5}, r]}]}, ImageSize -> Tiny]] - . - . Format[Dice[n_Integer ? (1 <= #1 <= 6&)], TeXForm] = Block[{p = 0.2, r = 0.05}, Graphics[{EdgeForm[Black], White, Rectangle[], Black, EdgeForm[], If[OddQ[n], Disk[{0.5, 0.5}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{p, p}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{Plus[1, Times[-1, p]], Plus[1, Times[-1, p]]}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{p, Plus[1, Times[-1, p]]}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{Plus[1, Times[-1, p]], p}, r]], If[n === 6, {Disk[{p, 0.5}, r], Disk[{Plus[1, Times[-1, p]], 0.5}, r]}]}, ImageSize -> Tiny]] - . - . Format[Dice[n_Integer ? (1 <= #1 <= 6&)], TraditionalForm] = Block[{p = 0.2, r = 0.05}, Graphics[{EdgeForm[Black], White, Rectangle[], Black, EdgeForm[], If[OddQ[n], Disk[{0.5, 0.5}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{p, p}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{Plus[1, Times[-1, p]], Plus[1, Times[-1, p]]}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{p, Plus[1, Times[-1, p]]}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{Plus[1, Times[-1, p]], p}, r]], If[n === 6, {Disk[{p, 0.5}, r], Disk[{Plus[1, Times[-1, p]], 0.5}, r]}]}, ImageSize -> Tiny]] + . + . Format[Dice[n_Integer ? (1 <= #1 <= 6&)], MathMLForm] = Block[{p = 0.2, r = 0.05}, Graphics[{EdgeForm[Black], White, Rectangle[], Black, EdgeForm[], If[OddQ[n], Disk[{0.5, 0.5}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{p, p}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{1 - p, 1 - p}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{p, 1 - p}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{1 - p, p}, r]], If[n === 6, {Disk[{p, 0.5}, r], Disk[{1 - p, 0.5}, r]}]}, ImageSize -> Tiny]] + . + . Format[Dice[n_Integer ? (1 <= #1 <= 6&)], OutputForm] = Block[{p = 0.2, r = 0.05}, Graphics[{EdgeForm[Black], White, Rectangle[], Black, EdgeForm[], If[OddQ[n], Disk[{0.5, 0.5}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{p, p}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{1 - p, 1 - p}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{p, 1 - p}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{1 - p, p}, r]], If[n === 6, {Disk[{p, 0.5}, r], Disk[{1 - p, 0.5}, r]}]}, ImageSize -> Tiny]] + . + . Format[Dice[n_Integer ? (1 <= #1 <= 6&)], StandardForm] = Block[{p = 0.2, r = 0.05}, Graphics[{EdgeForm[Black], White, Rectangle[], Black, EdgeForm[], If[OddQ[n], Disk[{0.5, 0.5}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{p, p}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{1 - p, 1 - p}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{p, 1 - p}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{1 - p, p}, r]], If[n === 6, {Disk[{p, 0.5}, r], Disk[{1 - p, 0.5}, r]}]}, ImageSize -> Tiny]] + . + . Format[Dice[n_Integer ? (1 <= #1 <= 6&)], TeXForm] = Block[{p = 0.2, r = 0.05}, Graphics[{EdgeForm[Black], White, Rectangle[], Black, EdgeForm[], If[OddQ[n], Disk[{0.5, 0.5}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{p, p}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{1 - p, 1 - p}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{p, 1 - p}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{1 - p, p}, r]], If[n === 6, {Disk[{p, 0.5}, r], Disk[{1 - p, 0.5}, r]}]}, ImageSize -> Tiny]] + . + . Format[Dice[n_Integer ? (1 <= #1 <= 6&)], TraditionalForm] = Block[{p = 0.2, r = 0.05}, Graphics[{EdgeForm[Black], White, Rectangle[], Black, EdgeForm[], If[OddQ[n], Disk[{0.5, 0.5}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{p, p}, r]], If[MemberQ[{2, 3, 4, 5, 6}, n], Disk[{1 - p, 1 - p}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{p, 1 - p}, r]], If[MemberQ[{4, 5, 6}, n], Disk[{1 - p, p}, r]], If[n === 6, {Disk[{p, 0.5}, r], Disk[{1 - p, 0.5}, r]}]}, ImageSize -> Tiny]] The empty series of dice shall be displayed as an empty dice: >> Format[Dice[]] := Graphics[{EdgeForm[Black], White, Rectangle[]}, ImageSize -> Tiny] diff --git a/mathics/eval/makeboxes/__init__.py b/mathics/eval/makeboxes/__init__.py index b3ca977f6..876ccccfd 100644 --- a/mathics/eval/makeboxes/__init__.py +++ b/mathics/eval/makeboxes/__init__.py @@ -19,7 +19,11 @@ eval_tableform, eval_texform, ) -from mathics.eval.makeboxes.precedence import builtins_precedence, parenthesize +from mathics.eval.makeboxes.precedence import ( + builtins_precedence, + compare_precedence, + parenthesize, +) __all__ = [ "NumberForm_to_String", @@ -27,6 +31,7 @@ "StringRParen", "_boxed_string", "builtins_precedence", + "compare_precedence", "do_format", "eval_baseform", "eval_generic_makeboxes", @@ -40,5 +45,6 @@ "format_element", "int_to_string_shorter_repr", "parenthesize", + "render_input_form", "to_boxes", ] diff --git a/mathics/eval/makeboxes/makeboxes.py b/mathics/eval/makeboxes/makeboxes.py index bc381385f..7b2f70b05 100644 --- a/mathics/eval/makeboxes/makeboxes.py +++ b/mathics/eval/makeboxes/makeboxes.py @@ -21,6 +21,7 @@ ) from mathics.core.systemsymbols import ( # SymbolRule, SymbolRuleDelayed, SymbolComplex, + SymbolInputForm, SymbolRational, SymbolStandardForm, ) @@ -253,9 +254,14 @@ def eval_makeboxes( Basically: MakeBoxes[expr // form] """ - # This is going to be reimplemented. + # This is going to be reimplemented. By now, much of the formatting + # relies in rules of the form `MakeBoxes[expr, OutputForm]` + # which is wrong. if form is SymbolFullForm: return eval_makeboxes_fullform(expr, evaluation) + if form is SymbolInputForm: + expr = Expression(form, expr) + form = SymbolStandardForm return Expression(SymbolMakeBoxes, expr, form).evaluate(evaluation) diff --git a/mathics/form/__init__.py b/mathics/form/__init__.py new file mode 100644 index 000000000..1b37251f4 --- /dev/null +++ b/mathics/form/__init__.py @@ -0,0 +1,7 @@ +""" +Module containing functions for rendering $PrintForms Forms +""" + +from mathics.form.inputform import render_input_form + +__all__ = ["render_input_form"] diff --git a/mathics/form/inputform.py b/mathics/form/inputform.py new file mode 100644 index 000000000..1ffc4f3c9 --- /dev/null +++ b/mathics/form/inputform.py @@ -0,0 +1,434 @@ +"""This module contains functions for turning Mathics3 expressions to +InputForm-formatted strings. + +`InputForm` produces textual output suitable for being parsed and +evaluated in Mathics CLI. + +`InputForm` is not affected by MakeBox assignment. + +InputForm versus FullForm +-------------------------- + +In contrast to `FullForm`, `InputForm` shows arithmetic expressions in +traditional mathematical notation. Apart from that and the allowance +of `InputForm` output to be altered via a `Format` assignment, the +appearance of the result is about the same as `FullForm`. + +Internally, `FullForm` produces `String` object, while `FullForm` +produces a nested `RowBox` structure. + +`InputForm` conversion produces an `InterpretationBox` The +`InterpetationBox` preserves information about the original +expression. In contrast, `FullForm` output produces a `TagBox`. In +both cases, underneath the `InterpretationBox` or `Tagbox` is a +`StyleBox`. + +""" + +from typing import Callable, Dict, Final, FrozenSet, List, Optional, Tuple + +from mathics.core.atoms import Integer, String +from mathics.core.convert.op import operator_to_ascii, operator_to_unicode +from mathics.core.evaluation import Evaluation +from mathics.core.expression import Expression +from mathics.core.parser.operators import OPERATOR_DATA, operator_to_string +from mathics.core.symbols import Atom, Symbol +from mathics.core.systemsymbols import ( + SymbolBlank, + SymbolBlankNullSequence, + SymbolBlankSequence, + SymbolInfix, + SymbolInputForm, + SymbolLeft, + SymbolNone, + SymbolRight, +) +from mathics.eval.makeboxes.formatvalues import do_format # , format_element +from mathics.eval.makeboxes.precedence import compare_precedence +from mathics.settings import SYSTEM_CHARACTER_ENCODING + +SymbolNonAssociative = Symbol("System`NonAssociative") +SymbolPostfix = Symbol("System`Postfix") +SymbolPrefix = Symbol("System`Prefix") + + +# Use 670 until BoxGroup precedence gets in. +PRECEDENCE_BOX_GROUP: Final[int] = 670 # box_operators["BoxGroup"] + +PRECEDENCES: Final = OPERATOR_DATA.get("operator-precedences") +PRECEDENCE_PLUS: Final[int] = PRECEDENCES.get("Plus", 310) +PRECEDENCE_TIMES: Final[int] = PRECEDENCES.get("Times", 400) +PRECEDENCE_POWER: Final[int] = PRECEDENCES.get("Power", 590) + +EXPR_TO_INPUTFORM_TEXT_MAP: Dict[str, Callable] = {} + + +# This Exception if the expression should +# be processed by the default routine +class _WrongFormattedExpression(Exception): + pass + + +def get_operator_str(head, evaluation, **kwargs) -> str: + encoding = kwargs["encoding"] + if isinstance(head, String): + op_str = head.value + elif isinstance(head, Symbol): + op_str = head.short_name + else: + return render_input_form(head, evaluation, **kwargs) + + if encoding == "ASCII": + operator = operator_to_ascii.get(op_str, op_str) + else: + operator = operator_to_unicode.get(op_str, op_str) + return operator + + +def bracket(expr_str: str) -> str: + """Wrap `expr_str` with square braces""" + return f"[{expr_str}]" + + +def parenthesize(expr_str: str) -> str: + """Wrap `expr_str` with parenthesis""" + return f"({expr_str})" + + +def register_inputform(head_name): + def _register(func): + EXPR_TO_INPUTFORM_TEXT_MAP[head_name] = func + return func + + return _register + + +def render_input_form(expr, evaluation, **kwargs): + """ + Build a string with the InputForm of the expression. + """ + format_expr: Expression = do_format(expr, evaluation, SymbolInputForm) + while format_expr.has_form("HoldForm", 1): # type: ignore + format_expr = format_expr.elements[0] + + lookup_name: str = format_expr.get_head().get_lookup_name() + + try: + result = EXPR_TO_INPUTFORM_TEXT_MAP[lookup_name]( + format_expr, evaluation, **kwargs + ) + return result + except _WrongFormattedExpression: + # If the key is not present, or the execution fails for any reason, use + # the default + pass + except KeyError: + pass + return _generic_to_inputform_text(format_expr, evaluation, **kwargs) + + return "" + + +@register_inputform("System`Association") +def _association_expression_to_inputform_text( + expr: Expression, evaluation: Evaluation, **kwargs +): + elements = expr.elements + result = ", ".join( + [render_input_form(elem, evaluation, **kwargs) for elem in elements] + ) + return f"<|{result}|>" + + +def _generic_to_inputform_text( + expr: Expression, evaluation: Evaluation, **kwargs +) -> str: + """ + Default representation of a function + """ + if isinstance(expr, Atom): + result = expr.atom_to_boxes(SymbolInputForm, evaluation) + if isinstance(result, String): + return result.value + return result.boxes_to_text(**kwargs) + + expr_head = expr.head + head = render_input_form(expr_head, evaluation, **kwargs) + comma = ", " + elements = [render_input_form(elem, evaluation, **kwargs) for elem in expr.elements] + result = elements.pop(0) if elements else "" + while elements: + result = result + comma + elements.pop(0) + + return head + bracket(result) + + +@register_inputform("System`List") +def _list_expression_to_inputform_text( + expr: Expression, evaluation: Evaluation, **kwargs +) -> str: + elements = tuple( + render_input_form(element, evaluation, **kwargs) for element in expr.elements + ) + result = "{" + if elements: + first, *rest = elements + result += first + for elem in rest: + result += ", " + elem + return result + "}" + + +def collect_in_pre_post_arguments( + expr: Expression, evaluation: Evaluation, **kwargs +) -> Tuple[list, str | List[str], int, Optional[Symbol]]: + """ + Determine operands, operator(s), precedence, and grouping + """ + # Processing the second argument, if it is there: + elements = expr.elements + # expr at least has to have one element + if len(elements) < 1: + raise _WrongFormattedExpression + + target = elements[0] + if isinstance(target, Atom): + raise _WrongFormattedExpression + + if not (0 <= len(elements) <= 4): + raise _WrongFormattedExpression + + head = expr.head + group = None + precedence = PRECEDENCE_BOX_GROUP + operands = list(target.elements) + + # Just one parameter: + if len(elements) == 1: + operator_spec = render_input_form(head, evaluation, **kwargs) + if head is SymbolInfix: + operator_spec = [ + f"{operator_to_string['Infix']}{operator_spec}{operator_to_string['Infix']}" + ] + elif head is SymbolPrefix: + operator_spec = f"{operator_spec}{operator_to_string['Prefix']}" + elif head is SymbolPostfix: + operator_spec = f"{operator_to_string['Postfix']}{operator_spec}" + return operands, operator_spec, precedence, group + + # At least two parameters: get the operator spec. + ops = elements[1] + if head is SymbolInfix: + # This is not the WMA behaviour, but the Mathics3 current implementation requires it: + ops = ops.elements if ops.has_form("List", None) else (ops,) + operator_spec = [get_operator_str(op, evaluation, **kwargs) for op in ops] + else: + operator_spec = get_operator_str(ops, evaluation, **kwargs) + + # At least three arguments: get the precedence + if len(elements) > 2: + if isinstance(elements[2], Integer): + precedence = elements[2].value + else: + raise _WrongFormattedExpression + + # Four arguments: get the grouping: + if len(elements) > 3: + group = elements[3] + if group not in (SymbolNone, SymbolLeft, SymbolRight, SymbolNonAssociative): + raise _WrongFormattedExpression + if group is SymbolNone: + group = None + + return operands, operator_spec, precedence, group + + +ARITHMETIC_OPERATOR_STRINGS: Final[FrozenSet[str]] = frozenset( + [ + *operator_to_string["Divide"], + *operator_to_string["NonCommutativeMultiply"], + *operator_to_string["Power"], + *operator_to_string["Times"], + " ", + ] +) + + +@register_inputform("System`Infix") +def _infix_expression_to_inputform_text( + expr: Expression, evaluation: Evaluation, **kwargs +) -> str: + """ + Convert Infix[...] into a InputForm string. + """ + # In WMA, expressions associated to Infix operators are not + # formatted using this path: in some way, when an expression + # has a head that matches with a symbol associated to an infix + # operator, WMA builds its inputform without passing through + # its "Infix" form. + kwargs["encoding"] = kwargs.get("encoding", SYSTEM_CHARACTER_ENCODING) + operands, ops_lst, precedence, group = collect_in_pre_post_arguments( + expr, evaluation, **kwargs + ) + # Infix needs at least two operands: + if len(operands) < 2: + raise _WrongFormattedExpression + + # Process the operands: + parenthesized = group in (None, SymbolRight, SymbolNonAssociative) + for index, operand in enumerate(operands): + operand_txt = str(render_input_form(operand, evaluation, **kwargs)) + cmp_precedence = compare_precedence(operand, precedence) + if cmp_precedence is not None and ( + cmp_precedence == -1 or (cmp_precedence == 0 and parenthesized) + ): + operand_txt = parenthesize(operand_txt) + + if index == 0: + result = operand_txt + # After the first element, for lateral + # associativity, parenthesized is flipped: + if group in (SymbolLeft, SymbolRight): + parenthesized = not parenthesized + else: + num_ops = len(ops_lst) + curr_op = ops_lst[index % num_ops] + if curr_op not in ARITHMETIC_OPERATOR_STRINGS: + # In the tests, we add spaces just for + and -: + curr_op = f" {curr_op} " + + result = "".join( + ( + result, + curr_op, + operand_txt, + ) + ) + return result + + +@register_inputform("System`Prefix") +def _prefix_expression_to_inputform_text( + expr: Expression, evaluation: Evaluation, **kwargs +) -> str: + """ + Convert Prefix[...] into a InputForm string. + """ + kwargs["encoding"] = kwargs.get("encoding", SYSTEM_CHARACTER_ENCODING) + operands, op_head, precedence, group = collect_in_pre_post_arguments( + expr, evaluation, **kwargs + ) + # Prefix works with just one operand: + if len(operands) != 1: + raise _WrongFormattedExpression + operand = operands[0] + kwargs["encoding"] = kwargs.get("encoding", SYSTEM_CHARACTER_ENCODING) + cmp_precedence = compare_precedence(operand, precedence) + target_txt = render_input_form(operand, evaluation, **kwargs) + if cmp_precedence is not None and cmp_precedence != -1: + target_txt = parenthesize(target_txt) + return op_head + target_txt + + +@register_inputform("System`Postfix") +def _postfix_expression_to_inputform_text( + expr: Expression, evaluation: Evaluation, **kwargs +) -> str: + """ + Convert Postfix[...] into a InputForm string. + """ + kwargs["encoding"] = kwargs.get("encoding", SYSTEM_CHARACTER_ENCODING) + operands, op_head, precedence, group = collect_in_pre_post_arguments( + expr, evaluation, **kwargs + ) + # Prefix works with just one operand: + if len(operands) != 1: + raise _WrongFormattedExpression + operand = operands[0] + cmp_precedence = compare_precedence(operand, precedence) + target_txt = render_input_form(operand, evaluation, **kwargs) + if cmp_precedence is not None and cmp_precedence != -1: + target_txt = parenthesize(target_txt) + return target_txt + op_head + + +@register_inputform("System`Blank") +@register_inputform("System`BlankSequence") +@register_inputform("System`BlankNullSequence") +def _blanks(expr: Expression, evaluation: Evaluation, **kwargs): + elements = expr.elements + if len(elements) > 1: + return _generic_to_inputform_text(expr, evaluation, **kwargs) + if elements: + elem = render_input_form(elements[0], evaluation, **kwargs) + else: + elem = "" + head = expr.head + if head is SymbolBlank: + return "_" + elem + elif head is SymbolBlankSequence: + return "__" + elem + elif head is SymbolBlankNullSequence: + return "___" + elem + return _generic_to_inputform_text(expr, evaluation, **kwargs) + + +@register_inputform("System`Pattern") +def _pattern(expr: Expression, evaluation: Evaluation, **kwargs): + elements = expr.elements + if len(elements) != 2: + return _generic_to_inputform_text(expr, evaluation, **kwargs) + name, pat = (render_input_form(elem, evaluation, **kwargs) for elem in elements) + return name + pat + + +@register_inputform("System`Rule") +@register_inputform("System`RuleDelayed") +def _rule_to_inputform_text(expr, evaluation: Evaluation, **kwargs): + """Rule|RuleDelayed[{...}]""" + head = expr.head + elements = expr.elements + kwargs["encoding"] = kwargs.get("encoding", SYSTEM_CHARACTER_ENCODING) + if len(elements) != 2: + return _generic_to_inputform_text(expr, evaluation, **kwargs) + pat, rule = (render_input_form(elem, evaluation, **kwargs) for elem in elements) + + op_str = get_operator_str(head, evaluation, **kwargs) + # In WMA there are spaces between operators. + return pat + f" {op_str} " + rule + + +@register_inputform("System`Slot") +def _slot_expression_to_inputform_text( + expr: Expression, evaluation: Evaluation, **kwargs +): + elements = expr.elements + if len(elements) != 1: + raise _WrongFormattedExpression + slot = elements[0] + if isinstance(slot, Integer): + slot_value = slot.value + if slot_value < 0: + raise _WrongFormattedExpression + return f"#{slot_value}" + if isinstance(slot, String): + return f"#{slot.value}" + raise _WrongFormattedExpression + + +@register_inputform("System`SlotSequence") +def _slotsequence_expression_to_inputform_text( + expr: Expression, evaluation: Evaluation, **kwargs +): + elements = expr.elements + if len(elements) != 1: + raise _WrongFormattedExpression + slot = elements[0] + if isinstance(slot, Integer): + slot_value = slot.value + if slot_value < 0: + raise _WrongFormattedExpression + return f"##{slot_value}" + if isinstance(slot, String): + return f"##{slot.value}" + raise _WrongFormattedExpression diff --git a/test/builtin/box/test_custom_boxexpression.py b/test/builtin/box/test_custom_boxexpression.py index d7bcb8afe..d3b36fdcb 100644 --- a/test/builtin/box/test_custom_boxexpression.py +++ b/test/builtin/box/test_custom_boxexpression.py @@ -43,7 +43,11 @@ class CustomAtom(Predefined): } def eval_to_boxes(self, evaluation): - "System`MakeBoxes[System`CustomAtom, StandardForm|TraditionalForm|OutputForm|InputForm]" + "System`MakeBoxes[System`CustomAtom, StandardForm|TraditionalForm|OutputForm]" + return CustomBoxExpression(evaluation=evaluation) + + def eval_to_boxes_inputform(self, evaluation): + "System`MakeBoxes[InputForm[System`CustomAtom], StandardForm|TraditionalForm|OutputForm]" return CustomBoxExpression(evaluation=evaluation) @@ -67,6 +71,13 @@ def eval_box(self, expr, evaluation: Evaluation, options: dict): instance = CustomGraphicsBox(*(expr.elements), evaluation=evaluation) return instance + def eval_box_outputForm(self, expr, evaluation: Evaluation, options: dict): + """System`MakeBoxes[System`OutputForm[System`Graphics[System`expr_, System`OptionsPattern[System`Graphics]]], + System`StandardForm|System`TraditionalForm]""" + print("MakeBoxes OutputForm") + instance = CustomGraphicsBox(*(expr.elements), evaluation=evaluation) + return instance + def boxes_to_text(self, elements=None, **options): if elements: self._elements = elements diff --git a/test/builtin/test_forms.py b/test/builtin/test_forms.py index 1bc31a0c5..25a1d6d88 100644 --- a/test/builtin/test_forms.py +++ b/test/builtin/test_forms.py @@ -3,11 +3,32 @@ Unit tests from mathics.builtin.forms. """ -from test.helper import check_evaluation +from test.helper import check_evaluation, session import pytest +@pytest.mark.parametrize( + ("expr", "form", "head", "subhead"), + [ + ("x", "InputForm", "InterpretationBox", "StyleBox"), + ("x", "OutputForm", "InterpretationBox", "PaneBox"), + ("x", "TeXForm", "InterpretationBox", "String"), + ("x", "StandardForm", "TagForm", "FormBox"), + ("x", "FullForm", "TagBox", "StyleBox"), + ], +) +@pytest.mark.xfail +def test_makeboxes_form(expr, form, head, subhead): + """ + Check the structure of the result of MakeBoxes + on expressions with different forms. + """ + expr = session.evaluate("MakeBoxes[{form}[{expr}]]") + assert expr.get_head_name() == f"System`{head}" + assert expr.elements[0].get_head_name() == f"System`{subhead}" + + @pytest.mark.parametrize( ("str_expr", "msgs", "str_expected", "fail_msg"), [ @@ -361,11 +382,11 @@ ( '{"hi","you"} //InputForm //TeXForm', None, - "\\left\\{\\text{``hi''}, \\text{``you''}\\right\\}", + r'\text{\{"hi", "you"\}}', None, ), ("a=.;b=.;c=.;TeXForm[a+b*c]", None, "a+b c", None), - ("TeXForm[InputForm[a+b*c]]", None, r"a\text{ + }b*c", None), + ("TeXForm[InputForm[a+b*c]]", None, r"\text{a + b*c}", None), ("TableForm[{}]", None, "", None), ( "{{2*a, 0},{0,0}}//MatrixForm", diff --git a/test/format/format_tests-WMA.yaml b/test/format/format_tests-WMA.yaml index 062955c2f..f0e35a50e 100644 --- a/test/format/format_tests-WMA.yaml +++ b/test/format/format_tests-WMA.yaml @@ -1,7 +1,7 @@ # Tests for formatting according WMA. # # These tests are prepared to compare the output obtained using WL code in -# both WMA and Mathics interpreters: +# both WMA and Mathics3 interpreters: # ./convert_yaml2json.py format_tests.yaml && $(WMAINTERPRETER) -f format_tests.m # # In this case, 'text' are certificated against the WMA result, @@ -12,7 +12,7 @@ # Running the same code against `mathics` CLI, most of these tests fails because # - `ToString` with `CharacterEncoding->"ASCII"` does not produce string # representations of Boxes. -# - `OutputForm` in Mathics does not produce *pretty-print-like* output. +# - `OutputForm` in Mathics3 does not produce *pretty-print-like* output. # And eventually, if we start to do it, probably we can also do it better, # so we are not going to coincide neither. # - Box constructions are still too diferent in both interpreters. @@ -25,10 +25,10 @@ '"-7.32"': latex: - InputForm: \\text{``-7.32''} - OutputForm: \\text{-7.32} - StandardForm: \\text{-7.32} - TraditionalForm: \\text{-7.32} + InputForm: \text{``-7.32''} + OutputForm: \text{-7.32} + StandardForm: \text{-7.32} + TraditionalForm: \text{-7.32} mathml: InputForm: -7.32 OutputForm: -7.32 @@ -85,7 +85,7 @@ OutputForm: '-0.00001' -1. 10^-6: latex: - InputForm: -1.\text{*${}^{\wedge}$}-6 + InputForm: -1.*{}^{\wedge}-6 OutputForm: -1.\times 10^{-6} mathml: {} msg: very small negative real number (<10^-6) @@ -103,7 +103,7 @@ OutputForm: '-100000.' -1. 10^6: latex: - InputForm: -1.0\text{*${}^{\wedge}$}6 + InputForm: -1.*{}^{\wedge}6 OutputForm: -1.\times 10^6 StandardForm: -1.0\text{*${}^{\wedge}$}6 TraditionalForm: -1.0\times 10^6 @@ -193,7 +193,7 @@ OutputForm: '0.00001' 1. 10^-6: latex: - InputForm: 1.\text{*${}^{\wedge}$}-6 + InputForm: 1.*{}^{\wedge}-6 OutputForm: 1.\times 10^{-6} mathml: {} msg: very small real number (<10^-6) @@ -215,7 +215,7 @@ TraditionalForm: "\\!\\(\\*FormBox[\"100000.`\", TraditionalForm]\\)" 1. 10^6: latex: - InputForm: 1.0\text{*${}^{\wedge}$}6 + InputForm: 1.*{}^{\wedge}6 OutputForm: 1.\times 10^6 StandardForm: 1.0\text{*${}^{\wedge}$}6 TraditionalForm: 1.0\times 10^6 @@ -228,8 +228,7 @@ TraditionalForm: "\\!\\(\\*FormBox[\"1.`*^6\", TraditionalForm]\\)" 1/(1+1/(1+1/a)): latex: - InputForm: 1\text{ / }\left(1\text{ + }1\text{ / }\left(1\text{ + }1\text{ - / }a\right)\right) + InputForm: 1/(1 + 1/(1 + 1/a)) OutputForm: 1\text{ / }\left(1\text{ + }1\text{ / }\left(1\text{ + }1\text{ / }a\right)\right) StandardForm: \frac{1}{1+\frac{1}{1+\frac{1}{a}}} @@ -262,8 +261,7 @@ # Nested Association <|a \[Rule] x, b \[Rule] y, c \[Rule] <|d \[Rule] t|>|>: latex: - InputForm: \text{<$\vert$}a\text{ -> }x, b\text{ -> }y, c\text{ -> }\text{<$\vert$}d\text{ - -> }t\text{$\vert$>}\text{$\vert$>} + InputForm: \text{<$\vert$a -> x, b -> y, c -> <$\vert$d -> t$\vert$>$\vert$>} OutputForm: \text{<$\vert$}a\text{ -> }x, b\text{ -> }y, c\text{ -> }\text{<$\vert$}d\text{ -> }t\text{$\vert$>}\text{$\vert$>} StandardForm: \text{<$\vert$}a \[Rule] x,b \[Rule] y,c \[Rule] \text{<$\vert$}d \[Rule] t\text{$\vert$>}\text{$\vert$>} @@ -296,8 +294,7 @@ # Association nested 2 Association[a -> x, b -> y, c -> Association[d -> t, Association[e -> u]]]: latex: - InputForm: \text{<$\vert$}a\text{ -> }x, b\text{ -> }y, c\text{ -> }\text{<$\vert$}d\text{ - -> }t, e\text{ -> }u\text{$\vert$>}\text{$\vert$>} + InputForm: \text{<$\vert$a -> x, b -> y, c -> <$\vert$d -> t, e -> u$\vert$>$\vert$>} OutputForm: \text{<$\vert$}a\text{ -> }x, b\text{ -> }y, c\text{ -> }\text{<$\vert$}d\text{ -> }t, e\text{ -> }u\text{$\vert$>}\text{$\vert$>} StandardForm: \text{<$\vert$}a->x,b->y,c->\text{<$\vert$}d->t,e->u\text{$\vert$>}\text{$\vert$>} @@ -333,7 +330,7 @@ Association[a -> x, b -> y, c -> Association[d -> t, Association[e -> u]]]: TraditionalForm: "\\!\\(\\*FormBox[RowBox[{\"\\[LeftAssociation]\", RowBox[{RowBox[{\"a\", \"\\[Rule]\", \"x\"}], \",\", RowBox[{\"b\", \"\\[Rule]\", \"y\"}], \",\", RowBox[{\"c\", \"\\[Rule]\", RowBox[{\"\\[LeftAssociation]\", RowBox[{RowBox[{\"d\", \"\\[Rule]\", \"t\"}], \",\", RowBox[{\"e\", \"\\[Rule]\", \"u\"}]}], \"\\[RightAssociation]\"}]}]}], \"\\[RightAssociation]\"}], TraditionalForm]\\)" Complex[1.09*^12, 3.]: latex: - InputForm: 1.09\text{*${}^{\wedge}$}12\text{ + }3.*I + InputForm: 1.09*{}^{\wedge}12 + 3.*I OutputForm: 1.09\times 10^{12}\text{ + }3. I StandardForm: 1.09\text{*${}^{\wedge}$}12+3. I TraditionalForm: 1.09\times 10^{12}+3. I @@ -356,8 +353,7 @@ Complex[1.09*^12, 3.]: TraditionalForm: "\\!\\(\\*FormBox[RowBox[{\"1.09`*^12\", \"+\", RowBox[{\"3.`\", \" \", \"\\[ImaginaryI]\"}]}], TraditionalForm]\\)" Graphics[{Text[a^b,{0,0}]}]: latex: - InputForm: \text{Graphics}\left[\left\{\text{Text}\left[\text{Power}\left[a, - b\right], \left\{0, 0\right\}\right]\right\}\right] + InputForm: \text{Graphics[\{Text[a${}^{\wedge}$b, \{0, 0\}]\}]} OutputForm: ' \begin{asy} @@ -426,7 +422,7 @@ Graphics[{Text[a^b,{0,0}]}]: TraditionalForm: "\\!\\(\\*FormBox[GraphicsBox[List[InsetBox[FormBox[SuperscriptBox[\"a\", \"b\"], TraditionalForm], List[0, 0]]]], TraditionalForm]\\)" Graphics[{}]: latex: - InputForm: \text{Graphics}\left[\left\{\right\}\right] + InputForm: \text{Graphics[\{\}]} OutputForm: ' \begin{asy} @@ -483,10 +479,7 @@ Graphics[{}]: TraditionalForm: "\\!\\(\\*FormBox[GraphicsBox[List[]], TraditionalForm]\\)" "Grid[{{\"Spanish\", \"Hola!\"},{\"Portuguese\", \"Ol\\[AGrave]!\"},{\"English\", \"Hi!\"}}]": latex: - InputForm: "\\text{Grid}\\left[\\left\\{\\left\\{\\text{``Spanish''}, \\\ - text{``Hola!''}\\right\\}, \\left\\{\\text{``Portuguese''}, \\text{``Ol\xE0\ - !''}\\right\\}, \\left\\{\\text{``English''}, \\text{``Hi!''}\\right\\}\\right\\\ - }\\right]" + InputForm: \text{Grid[\{\{"Spanish", "Hola!"\}, \{"Portuguese", "Olà!"\}, \{"English", "Hi!"\}\}]} OutputForm: "\\begin{array}{cc} \\text{Spanish} & \\text{Hola!}\\\\ \\\ text{Portuguese} & \\text{Ol\\`a!}\\\\ \\text{English} & \\text{Hi!}\\end{array}" StandardForm: "\\begin{array}{cc} \\text{Spanish} & \\text{Hola!}\\\\ \\\ @@ -528,7 +521,7 @@ Graphics[{}]: TraditionalForm: "\\!\\(\\*FormBox[TagBox[GridBox[{{\"\\\"Spanish\\\"\", \"\\\"Hola!\\\"\"}, {\"\\\"Portuguese\\\"\", \"\\\"Ol\\[AGrave]!\\\"\"}, {\"\\\"English\\\"\", \"\\\"Hi!\\\"\"}}, Rule[AutoDelete, False], Rule[GridBoxItemSize, List[Rule[\"Columns\", List[List[Automatic]]], Rule[\"Rows\", List[List[Automatic]]]]]], \"Grid\"], TraditionalForm]\\)" Grid[{{a,b},{c,d}}]: latex: - InputForm: \text{Grid}\left[\left\{\left\{a, b\right\}, \left\{c, d\right\}\right\}\right] + InputForm: \text{Grid[\{\{a, b\}, \{c, d\}\}]} OutputForm: \begin{array}{cc} a & b\\ c & d\end{array} StandardForm: \begin{array}{cc} a & b\\ c & d\end{array} TraditionalForm: \begin{array}{cc} a & b\\ c & d\end{array} @@ -572,7 +565,7 @@ Grid[{{a,b},{c,d}}]: # Integrate[F[x], {x, a, g[b]}]: latex: - InputForm: \text{Integrate}\left[F\left[x\right], \left\{x, a, g\left[b\right]\right\}\right] + InputForm: \text{Integrate[F[x], \{x, a, g[b]\}]} OutputForm: \text{Integrate}\left[F\left[x\right], \left\{x, a, g\left[b\right]\right\}\right] StandardForm: \int_a^{g\left[b\right]} F\left[x\right] \, dx TraditionalForm: \int_a^{g\left(b\right)} F\left(x\right) \, dx @@ -590,8 +583,7 @@ Integrate[F[x], {x, a, g[b]}]: OutputForm: Integrate[F[x], {x, a, g[b]}] MatrixForm[{{a,b},{c,d}}]: latex: - InputForm: \text{MatrixForm}\left[\left\{\left\{a, b\right\}, \left\{c, - d\right\}\right\}\right] + InputForm: \text{MatrixForm[\{\{a, b\}, \{c, d\}\}]} OutputForm: \begin{array}{cc} a & b\\ c & d\end{array} StandardForm: \left(\begin{array}{cc} a & b\\ c & d\end{array}\right) TraditionalForm: \left(\begin{array}{cc} a & b\\ c & d\end{array}\right) @@ -632,8 +624,7 @@ MatrixForm[{{a,b},{c,d}}]: TraditionalForm: "\\!\\(\\*FormBox[TagBox[RowBox[{\"(\", \"\\[NoBreak]\", GridBox[{{\"a\", \"b\"}, {\"c\", \"d\"}}, Rule[RowSpacings, 1], Rule[ColumnSpacings, 1], Rule[RowAlignments, Baseline], Rule[ColumnAlignments, Center]], \"\\[NoBreak]\", \")\"}], Function[BoxForm`e$, MatrixForm[BoxForm`e$]]], TraditionalForm]\\)" Sqrt[1/(1+1/(1+1/a))]: latex: - InputForm: \text{Sqrt}\left[1\text{ / }\left(1\text{ + }1\text{ / }\left(1\text{ - + }1\text{ / }a\right)\right)\right] + InputForm: \text{Sqrt[1/(1 + 1/(1 + 1/a))]} OutputForm: \text{Sqrt}\left[1\text{ / }\left(1\text{ + }1\text{ / }\left(1\text{ + }1\text{ / }a\right)\right)\right] StandardForm: \sqrt{\frac{1}{1+\frac{1}{1+\frac{1}{a}}}} @@ -667,7 +658,7 @@ Sqrt[1/(1+1/(1+1/a))]: TraditionalForm: "\\!\\(\\*FormBox[SqrtBox[FractionBox[\"1\", RowBox[{FractionBox[\"1\", RowBox[{FractionBox[\"1\", \"a\"], \"+\", \"1\"}]], \"+\", \"1\"}]]], TraditionalForm]\\)" Subscript[a, 4]: latex: - InputForm: \text{Subscript}\left[a, 4\right] + InputForm: \text{Subscript[a, 4]} OutputForm: \text{Subscript}\left[a, 4\right] StandardForm: a_4 TraditionalForm: a_4 @@ -692,7 +683,7 @@ Subscript[a, 4]: TraditionalForm: *id003 Subsuperscript[a, p, q]: latex: - InputForm: \text{Subsuperscript}\left[a, p, q\right] + InputForm: \text{Subsuperscript[a, p, q]} OutputForm: \text{Subsuperscript}\left[a, p, q\right] StandardForm: a_p^q TraditionalForm: a_p^q @@ -737,8 +728,7 @@ TableForm[{Graphics[{Text[a^b,{0,0}]}], Graphics[{Text[a^b,{0,0}]}]}]: # TableForm[{{a,b},{c,d}}]: latex: - InputForm: \text{TableForm}\left[\left\{\left\{a, b\right\}, \left\{c, - d\right\}\right\}\right] + InputForm: \text{TableForm[\{\{a, b\}, \{c, d\}\}]} OutputForm: \begin{array}{cc} a & b\\ c & d\end{array} StandardForm: \begin{array}{cc} a & b\\ c & d\end{array} TraditionalForm: \begin{array}{cc} a & b\\ c & d\end{array} @@ -813,7 +803,7 @@ a: TraditionalForm: "\\!\\(\\*FormBox[\"a\", TraditionalForm]\\)" a^(g[b]/c): latex: - InputForm: a{}^{\wedge}\left(g(b)\text{ / }c\right) + InputForm: \text{a${}^{\wedge}$(g[b]/c)} OutputForm: a\text{ ${}^{\wedge}$ }\left(g(b)\text{ / }c\right) StandardForm: a^{\frac{g(b)}{c}} TraditionalForm: a^{\frac{g(b)}{c}} @@ -832,7 +822,7 @@ a^(g[b]/c): TraditionalForm: "\\!\\(\\*FormBox[SuperscriptBox[\"a\", FractionBox[RowBox[{\"g\", \"(\", \"b\", \")\"}], \"c\"]], TraditionalForm]\\)" a^4: latex: - InputForm: a{}^{\wedge}4 + InputForm: \text{a${}^{\wedge}$4} OutputForm: a\text{ ${}^{\wedge}$ }4 StandardForm: a^4 TraditionalForm: a^4 diff --git a/test/format/format_tests.m b/test/format/format_tests.m index de0e3f962..44f184cf7 100755 --- a/test/format/format_tests.m +++ b/test/format/format_tests.m @@ -1,7 +1,7 @@ (************************************************************************************** Run the format tests in WMA. -Notice that some of the tests that produce meaninful outputs in Mathics, +Notice that some of the tests that produce meaninful outputs in Mathics3, fails miserably to produce an output in WMA. Also, the results of these tests in the Notebook interface, the CLI (math) and wolframscript are not fully consistent. @@ -29,9 +29,9 @@ Do[form = ToExpression[subtest[[1]]]; expr = form[key]; result = ToString[expr, CharacterEncoding->"ASCII"]; expected = subtest[[2]]; - If[result != expected, - Print[" * ", FullForm[expr], " //", form, "(text) [Failed]\n result:", "<<" <> result <> ">>(", StringLength[result], - ")\n expected: ", "<<" <> expected <> ">> (", StringLength[expected],")\n"], + If[result != expected, + Print[" * ", FullForm[expr], " //", form, "(text) [Failed]\n result:", "<<" <> result <> ">>(", StringLength[result], + ")\n expected: ", "<<" <> expected <> ">> (", StringLength[expected],")\n"], Print[" * ", FullForm[expr], " //", form, "(text) [OK]"]];, {subtest, text}] ]; @@ -41,23 +41,23 @@ Do[form = ToExpression[subtest[[1]]]; expr = form[key]; result = ToString[expr, TeXForm, CharacterEncoding->"ASCII"]; expected = subtest[[2]]; - If[result != subtest[[2]], - Print[" * ", key, " //", form, "(latex) [Failed]\n result:", - "<<" <> result <> ">>", "\n expected: ", - "<<" <> expected <> ">>\n"], + If[result != subtest[[2]], + Print[" * ", key, " //", form, "(latex) [Failed]\n result:", + "<<" <> result <> ">>", "\n expected: ", + "<<" <> expected <> ">>\n"], Print[" * ", key, " //", form, "(latex) [OK]"]];, {subtest, latex}] ]; (*MathML*) - If[And[ISMATHICSINTERPRETER, Head[mathml]===List], + If[And[ISMATHICSINTERPRETER, Head[mathml]===List], Print[" mathml", "\n ------", "\n"]; Do[form = ToExpression[subtest[[1]]]; expr = form[key]; result = ToString[expr, MathMLForm, CharacterEncoding->"ASCII"]; expected = subtest[[2]]; - If[result != subtest[[2]], - Print[" * ", key, " //", form, "(mathml) [Failed]\n result:", - "<<" <> result <> ">>", "\n expected: ", - "<<" <> expected <> ">>\n"], + If[result != subtest[[2]], + Print[" * ", key, " //", form, "(mathml) [Failed]\n result:", + "<<" <> result <> ">>", "\n expected: ", + "<<" <> expected <> ">>\n"], Print[" * ", key, " //", form, "(mathml) [OK]"]];, {subtest, mathml}]]; , {tests, data} ] diff --git a/test/format/format_tests.yaml b/test/format/format_tests.yaml index 2cc7acb8e..0664d3586 100644 --- a/test/format/format_tests.yaml +++ b/test/format/format_tests.yaml @@ -75,20 +75,20 @@ System`StandardForm: "\u03C0 is a trascendental number" System`TraditionalForm: "\u03C0 is a trascendental number" -1. 10^-5: + msg: small negative real number (>10^-5) latex: System`InputForm: '-0.00001' System`OutputForm: '-0.00001' mathml: {} - msg: small negative real number (>10^-5) text: System`InputForm: '-0.00001' System`OutputForm: '-0.00001' -1. 10^-6: + msg: very small negative real number (<10^-6) latex: - System`InputForm: -1.\text{*${}^{\wedge}$}-6 + System`InputForm: -1.*{}^{\wedge}-6 System`OutputForm: -1.\times 10^{-6} mathml: {} - msg: very small negative real number (<10^-6) text: System`InputForm: -1.*^-6 System`OutputForm: "-1.\xD710^-6" @@ -97,24 +97,25 @@ System`InputForm: '-100000.' System`OutputForm: '-100000.' mathml: {} - msg: large negative real number (<10^6) + msg: large negative real number (>10^6) text: System`InputForm: '-100000.' System`OutputForm: '-100000.' -1. 10^6: + msg: large negative real number (>10^6) latex: - System`InputForm: -1.\text{*${}^{\wedge}$}6 + System`InputForm: -1.*{}^{\wedge}6 System`OutputForm: -1.\times 10^6 System`StandardForm: -1.\text{*${}^{\wedge}$}6 System`TraditionalForm: -1.\times 10^6 mathml: {} - msg: large negative real number (>10^6) text: System`InputForm: -1.*^6 System`OutputForm: "-1.\xD710^6" System`StandardForm: -1.`*^6 System`TraditionalForm: "-1.`\xD710^6" '-4': + msg: An Integer latex: System`InputForm: '-4' System`OutputForm: '-4' @@ -125,13 +126,13 @@ System`OutputForm: -4 System`StandardForm: - 4 System`TraditionalForm: - 4 - msg: An Integer text: System`InputForm: '-4' System`OutputForm: '-4' System`StandardForm: '-4' System`TraditionalForm: '-4' '-4.32': + msg: A MachineReal number latex: System`InputForm: '-4.32' System`OutputForm: '-4.32' @@ -142,7 +143,6 @@ System`OutputForm: -4.32 System`StandardForm: - 4.32 System`TraditionalForm: - 4.32 - msg: A MachineReal number text: System`InputForm: '-4.32' System`OutputForm: '-4.32' @@ -183,20 +183,20 @@ System`StandardForm: -4.32`4. System`TraditionalForm: -4.32`4. 1. 10^-5: + msg: small real number (<10^-5) latex: System`InputForm: '0.00001' System`OutputForm: '0.00001' mathml: {} - msg: small real number (<10^-5) text: System`InputForm: '0.00001' System`OutputForm: '0.00001' 1. 10^-6: + msg: very small real number (<10^-6) latex: - System`InputForm: 1.\text{*${}^{\wedge}$}-6 + System`InputForm: 1.*{}^{\wedge}-6 System`OutputForm: 1.\times 10^{-6} mathml: {} - msg: very small real number (<10^-6) text: System`InputForm: 1.*^-6 System`OutputForm: "1.\xD710^-6" @@ -207,20 +207,20 @@ System`StandardForm: '100000.' System`TraditionalForm: '100000.' mathml: {} - msg: large real number (<10^6) + msg: large real number (>10^6) text: System`InputForm: '100000.' System`OutputForm: '100000.' System`StandardForm: 100000.` System`TraditionalForm: 100000.` 1. 10^6: + msg: very large real number (>10^6) latex: - System`InputForm: 1.\text{*${}^{\wedge}$}6 + System`InputForm: 1.*{}^{\wedge}6 System`OutputForm: 1.\times 10^6 System`StandardForm: 1.\text{*${}^{\wedge}$}6 System`TraditionalForm: 1.\times 10^6 mathml: {} - msg: very large real number (>10^6) text: System`InputForm: 1.*^6 System`OutputForm: "1.\xD710^6" @@ -228,15 +228,14 @@ System`TraditionalForm: "1.`\xD710^6" 1/(1+1/(1+1/a)): latex: - System`InputForm: 1\text{ / }\left(1\text{ + }1\text{ / }\left(1\text{ + }1\text{ - / }a\right)\right) + System`InputForm: 1/(1 + 1/(1 + 1/a)) System`OutputForm: 1\text{ / }\left(1\text{ + }1\text{ / }\left(1\text{ + }1\text{ / }a\right)\right) System`StandardForm: \frac{1}{1+\frac{1}{1+\frac{1}{a}}} System`TraditionalForm: \frac{1}{1+\frac{1}{1+\frac{1}{a}}} mathml: System`InputForm: - - 1  /  ( 1  +  1  /  ( 1  +  1  /  a ) ) + - 1/(1 + 1/(1 + 1/a)) - Fragile! System`OutputForm: - 1  /  ( 1 @@ -251,24 +250,20 @@ System`TraditionalForm: *id001 msg: FractionBox text: - System`InputForm: 1 / (1 + 1 / (1 + 1 / a)) + System`InputForm: 1/(1 + 1/(1 + 1/a)) System`OutputForm: 1 / (1 + 1 / (1 + 1 / a)) System`StandardForm: 1 / (1+1 / (1+1 / a)) System`TraditionalForm: 1 / (1+1 / (1+1 / a)) <|a -> x, b -> y, c -> <|d -> t|>|>: + msg: Association latex: - System`InputForm: \text{<$\vert$}a\text{ -> }x, b\text{ -> }y, c\text{ -> }\text{<$\vert$}d\text{ - -> }t\text{$\vert$>}\text{$\vert$>} + System`InputForm: \text{<$\vert$a -> x, b -> y, c -> <$\vert$d -> t$\vert$>$\vert$>} System`OutputForm: \text{<$\vert$}a\text{ -> }x, b\text{ -> }y, c\text{ -> }\text{<$\vert$}d\text{ -> }t\text{$\vert$>}\text{$\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$>} mathml: - System`InputForm: <| a  ->  - x b  ->  - y c  ->  - <| d  ->  - t |> |> + System`InputForm: <|a -> x, b -> y, c -> <|d -> t|>|> System`OutputForm: <| a  ->  x b  ->  y c  ->  @@ -282,27 +277,21 @@ x , b -> y , c -> <| d -> t |> |> - msg: Association text: System`InputForm: <|a -> x, b -> y, c -> <|d -> t|>|> System`OutputForm: <|a -> x, b -> y, c -> <|d -> t|>|> System`StandardForm: <|a->x, b->y, c-><|d->t|>|> System`TraditionalForm: <|a->x, b->y, c-><|d->t|>|> Association[a -> x, b -> y, c -> Association[d -> t, Association[e -> u]]]: + msg: Nested Association latex: - System`InputForm: \text{<$\vert$}a\text{ -> }x, b\text{ -> }y, c\text{ -> }\text{<$\vert$}d\text{ - -> }t, e\text{ -> }u\text{$\vert$>}\text{$\vert$>} + System`InputForm: \text{<$\vert$a -> x, b -> y, c -> <$\vert$d -> t, e -> u$\vert$>$\vert$>} System`OutputForm: \text{<$\vert$}a\text{ -> }x, b\text{ -> }y, c\text{ -> }\text{<$\vert$}d\text{ -> }t, e\text{ -> }u\text{$\vert$>}\text{$\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$>} mathml: - System`InputForm: <| a  ->  - x b  ->  - y c  ->  - <| d  ->  - t e  ->  - u |> |> + System`InputForm: <|a -> x, b -> y, c -> <|d -> t, e -> u|>|> System`OutputForm: <| a  ->  x b  ->  y c  ->  @@ -319,7 +308,6 @@ Association[a -> x, b -> y, c -> Association[d -> t, Association[e -> u]]]: , c -> <| d -> t , e -> u |> |> - msg: Nested Association text: System`InputForm: <|a -> x, b -> y, c -> <|d -> t, e -> u|>|> System`OutputForm: <|a -> x, b -> y, c -> <|d -> t, e -> u|>|> @@ -327,13 +315,12 @@ Association[a -> x, b -> y, c -> Association[d -> t, Association[e -> u]]]: System`TraditionalForm: <|a->x, b->y, c-><|d->t, e->u|>|> Complex[1.09*^12, 3.]: latex: - System`InputForm: 1.09\text{*${}^{\wedge}$}12\text{ + }3.*I + System`InputForm: 1.09*{}^{\wedge}12 + 3.*I System`OutputForm: 1.09\times 10^{12}\text{ + }3. I System`StandardForm: 1.09\text{*${}^{\wedge}$}12+3. I System`TraditionalForm: 1.09\times 10^{12}+3. I mathml: - System`InputForm: 1.09 *^ 12 -  +  3. * I + System`InputForm: 1.09*^12 + 3.*I System`OutputForm: "1.09 \xD7 10\ \ 12  +  3.  \ \ I" @@ -349,9 +336,9 @@ Complex[1.09*^12, 3.]: System`StandardForm: 1.09`*^12+3.` I System`TraditionalForm: "1.09`\xD710^12+3.`\u2062I" Graphics[{Text[a^b,{0,0}]}]: + msg: Nontrivial Graphics - Fragile! latex: - System`InputForm: \text{Graphics}\left[\left\{\text{Text}\left[\text{Power}\left[a, - b\right], \left\{0, 0\right\}\right]\right\}\right] + System`InputForm: \text{Graphics[\{Text[a${}^{\wedge}$b, \{0, 0\}]\}]} System`OutputForm: ' \begin{asy} @@ -412,15 +399,14 @@ Graphics[{Text[a^b,{0,0}]}]: \end{asy} ' - msg: Nontrivial Graphics - Fragile! text: - System`InputForm: Graphics[{Text[Power[a, b], {0, 0}]}] + System`InputForm: Graphics[{Text[a^b, {0, 0}]}] System`OutputForm: -Graphics- System`StandardForm: -Graphics- System`TraditionalForm: -Graphics- Graphics[{}]: latex: - System`InputForm: \text{Graphics}\left[\left\{\right\}\right] + System`InputForm: \text{Graphics[\{\}]} System`OutputForm: ' \begin{asy} @@ -477,10 +463,7 @@ Graphics[{}]: System`TraditionalForm: -Graphics- "Grid[{{\"Spanish\", \"Hola!\"},{\"Portuguese\", \"Ol\xE0!\"},{\"English\", \"Hi!\"}}]": latex: - System`InputForm: "\\text{Grid}\\left[\\left\\{\\left\\{\\text{``Spanish''}, \\\ - text{``Hola!''}\\right\\}, \\left\\{\\text{``Portuguese''}, \\text{``Ol\xE0\ - !''}\\right\\}, \\left\\{\\text{``English''}, \\text{``Hi!''}\\right\\}\\right\\\ - }\\right]" + System`InputForm: \text{Grid[\{\{"Spanish", "Hola!"\}, \{"Portuguese", "Olà!"\}, \{"English", "Hi!"\}\}]} System`OutputForm: "\\begin{array}{cc} \\text{Spanish} & \\text{Hola!}\\\\ \\\ text{Portuguese} & \\text{Ol\xE0!}\\\\ \\text{English} & \\text{Hi!}\\end{array}" System`StandardForm: "\\begin{array}{cc} \\text{Spanish} & \\text{Hola!}\\\\ \\\ @@ -488,12 +471,7 @@ Graphics[{}]: System`TraditionalForm: "\\begin{array}{cc} \\text{Spanish} & \\text{Hola!}\\\\\ \ \\text{Portuguese} & \\text{Ol\xE0!}\\\\ \\text{English} & \\text{Hi!}\\end{array}" mathml: - System`InputForm: "Grid [ { {\ - \ Spanish Hola! }\ - \ { Portuguese \ - \ Ol\xE0! } {\ - \ English Hi! }\ - \ } ]" + System`InputForm: "Grid[{{"Spanish", "Hola!"}, {"Portuguese", "Olà!"}, {"English", "Hi!"}}]" System`OutputForm: "\nSpanishHola!\n\ PortugueseGrid [ { { - a b } - { c - d } } ] + System`InputForm: Grid[{{a, b}, {c, d}}] System`OutputForm: ' ab @@ -577,15 +552,12 @@ Grid[{{a,b},{c,d}}]: ' Integrate[F[x], {x, a, g[b]}]: latex: - System`InputForm: \text{Integrate}\left[F\left[x\right], \left\{x, a, g\left[b\right]\right\}\right] + System`InputForm: \text{Integrate[F[x], \{x, a, g[b]\}]} System`OutputForm: \text{Integrate}\left[F\left[x\right], \left\{x, a, g\left[b\right]\right\}\right] 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 mathml: - System`InputForm: Integrate [ F [ - x ] { x - a g [ - b ] } ] + System`InputForm: Integrate[F[x], {x, a, g[b]}] System`OutputForm: Integrate [ F [ x ] { x a g @@ -595,18 +567,14 @@ Integrate[F[x], {x, a, g[b]}]: System`OutputForm: Integrate[F[x], {x, a, g[b]}] MatrixForm[{{a,b},{c,d}}]: latex: - System`InputForm: \text{MatrixForm}\left[\left\{\left\{a, b\right\}, \left\{c, - d\right\}\right\}\right] + System`InputForm: \text{MatrixForm[\{\{a, b\}, \{c, d\}\}]} System`OutputForm: \begin{array}{cc} a & b\\ c & d\end{array} System`StandardForm: \left(\begin{array}{cc} a & b\\ c & d\end{array}\right) System`TraditionalForm: \left(\begin{array}{cc} a & b\\ c & d\end{array}\right) mathml: - System`InputForm: MatrixForm [ { { - a b } - { c - d } } ] + System`InputForm: MatrixForm[{{a, b}, {c, d}}] System`OutputForm: ' - + ab cd @@ -648,16 +616,16 @@ MatrixForm[{{a,b},{c,d}}]: )' Sqrt[1/(1+1/(1+1/a))]: + msg: SqrtBox latex: - System`InputForm: \text{Sqrt}\left[1\text{ / }\left(1\text{ + }1\text{ / }\left(1\text{ - + }1\text{ / }a\right)\right)\right] + System`InputForm: \text{Sqrt[1/(1 + 1/(1 + 1/a))]} System`OutputForm: \text{Sqrt}\left[1\text{ / }\left(1\text{ + }1\text{ / }\left(1\text{ + }1\text{ / }a\right)\right)\right] System`StandardForm: \sqrt{\frac{1}{1+\frac{1}{1+\frac{1}{a}}}} System`TraditionalForm: \sqrt{\frac{1}{1+\frac{1}{1+\frac{1}{a}}}} mathml: System`InputForm: - - Sqrt [ 1  /  ( 1  +  1  /  ( 1  +  1  /  a ) ) ] + - Sqrt[1/(1 + 1/(1 + 1/a))] - Fragile! System`OutputForm: - Sqrt [ 1  /  @@ -672,22 +640,20 @@ Sqrt[1/(1+1/(1+1/a))]: - Fragile! System`TraditionalForm: *id002 - msg: SqrtBox text: - System`InputForm: Sqrt[1 / (1 + 1 / (1 + 1 / a))] + System`InputForm: Sqrt[1/(1 + 1/(1 + 1/a))] System`OutputForm: Sqrt[1 / (1 + 1 / (1 + 1 / a))] System`StandardForm: Sqrt[1 / (1+1 / (1+1 / a))] System`TraditionalForm: Sqrt[1 / (1+1 / (1+1 / a))] Subscript[a, 4]: latex: - System`InputForm: \text{Subscript}\left[a, 4\right] + System`InputForm: \text{Subscript[a, 4]} System`OutputForm: \text{Subscript}\left[a, 4\right] System`StandardForm: a_4 System`TraditionalForm: a_4 mathml: System`InputForm: - - Subscript [ a - 4 ] + - Subscript[a, 4] - Fragile! System`OutputForm: - Subscript [ a @@ -705,13 +671,12 @@ Subscript[a, 4]: System`TraditionalForm: *id003 Subsuperscript[a, p, q]: latex: - System`InputForm: \text{Subsuperscript}\left[a, p, q\right] + System`InputForm: \text{Subsuperscript[a, p, q]} System`OutputForm: \text{Subsuperscript}\left[a, p, q\right] System`StandardForm: a_p^q System`TraditionalForm: a_p^q mathml: - System`InputForm: Subsuperscript [ a - p q ] + System`InputForm: Subsuperscript[a, p, q] System`OutputForm: Subsuperscript [ a p q ] System`StandardForm: a p q @@ -723,6 +688,7 @@ Subsuperscript[a, p, q]: System`StandardForm: Subsuperscript[a, p, q] System`TraditionalForm: Subsuperscript[a, p, q] TableForm[{Graphics[{Text[a^b,{0,0}]}], Graphics[{Text[a^b,{0,0}]}]}]: + msg: A table of graphics - Fragile! latex: System`StandardForm: "\\begin{array}{c} \n\\begin{asy}\nusepackage(\"amsmath\"\ );\nsize(2.45cm, 2.9167cm);\n\n// InsetBox\nlabel(\"$a^b$\", (73.5,87.5), align=SW,\ @@ -736,10 +702,8 @@ TableForm[{Graphics[{Text[a^b,{0,0}]}], Graphics[{Text[a^b,{0,0}]}]}]: \\\\ \n\\begin{asy}\nusepackage(\"amsmath\");\nsize(2.45cm, 2.9167cm);\n\n//\ \ InsetBox\nlabel(\"$a^b$\", (73.5,87.5), align=SW, rgb(0, 0, 0)+fontsize(3));\n\ \nclip(box((63,75), (84,100)));\n\n\\end{asy}\n\\end{array}" - msg: A table of graphics - Fragile! text: - System`InputForm: TableForm[{Graphics[{Text[Power[a, b], {0, 0}]}], Graphics[{Text[Power[a, - b], {0, 0}]}]}] + System`InputForm: TableForm[{Graphics[{Text[a^b, {0, 0}]}], Graphics[{Text[a^b, {0, 0}]}]}] System`OutputForm: '-Graphics- @@ -760,16 +724,12 @@ TableForm[{Graphics[{Text[a^b,{0,0}]}], Graphics[{Text[a^b,{0,0}]}]}]: ' TableForm[{{a,b},{c,d}}]: latex: - System`InputForm: \text{TableForm}\left[\left\{\left\{a, b\right\}, \left\{c, - d\right\}\right\}\right] + System`InputForm: \text{TableForm[\{\{a, b\}, \{c, d\}\}]} System`OutputForm: \begin{array}{cc} a & b\\ c & d\end{array} System`StandardForm: \begin{array}{cc} a & b\\ c & d\end{array} System`TraditionalForm: \begin{array}{cc} a & b\\ c & d\end{array} mathml: - System`InputForm: TableForm [ { { - a b } - { c - d } } ] + System`InputForm: TableForm[{{a, b}, {c, d}}] System`OutputForm: ' ab @@ -848,29 +808,29 @@ a: System`TraditionalForm: a a^(g[b]/c): latex: - System`InputForm: a{}^{\wedge}\left(g\left[b\right]\text{ / }c\right) + System`InputForm: \text{a${}^{\wedge}$(g[b]/c)} System`OutputForm: a\text{ ${}^{\wedge}$ }\left(g\left[b\right]\text{ / }c\right) System`StandardForm: a^{\frac{g\left[b\right]}{c}} System`TraditionalForm: a^{\frac{g\left(b\right)}{c}} mathml: - System`InputForm: a ^ ( g [ b ]  /  c ) + System`InputForm: a^(g[b]/c) System`OutputForm: a  ^  ( g [ b ]  /  c ) System`StandardForm: a g [ b ] c System`TraditionalForm: a g ( b ) c msg: SuperscriptBox with a nested expression. text: - System`InputForm: a^(g[b] / c) + System`InputForm: a^(g[b]/c) System`OutputForm: a ^ (g[b] / c) System`StandardForm: a^((g[b]) / c) System`TraditionalForm: a^((g(b)) / c) a^4: latex: - System`InputForm: a{}^{\wedge}4 + System`InputForm: \text{a${}^{\wedge}$4} System`OutputForm: a\text{ ${}^{\wedge}$ }4 System`StandardForm: a^4 System`TraditionalForm: a^4 mathml: - System`InputForm: a ^ 4 + System`InputForm: a^4 System`OutputForm: a  ^  4 System`StandardForm: a 4 System`TraditionalForm: a 4 diff --git a/test/format/makeboxes_tests.m b/test/format/makeboxes_tests.m index 54eecc8c3..49360ed4c 100755 --- a/test/format/makeboxes_tests.m +++ b/test/format/makeboxes_tests.m @@ -28,8 +28,8 @@ result = ToExpression[expr]; expect = ToExpression["expect"/.rul]; If[SameQ[result, expect], - Print[" ", form, " [OK]"], - Print[" ", form, " [Failed]"]; + Print[" ", expr, " //", form, " [OK]"], + Print[" ", expr, " //", form, " [Failed]"]; Print[" expr = ", expr ]; Print[" result = ", result]; Print[" expected= ",expect]; diff --git a/test/format/test_format.py b/test/format/test_format.py index 588bc978a..ba469dafc 100644 --- a/test/format/test_format.py +++ b/test/format/test_format.py @@ -15,7 +15,7 @@ # In these tests, we check that the current behavior of makeboxes does not change # without noticing that it could affect compatibility with WL and with # mathics-django. Also looking at some issues in the current behavior regarding -# the WL standard (for instance, how to represent $a^(b/c)$) and the Mathics +# the WL standard (for instance, how to represent $a^(b/c)$) and the Mathics3 # own implementation (BoxError raising in some simple conditions). # These test should be updated as we fix pending issues.