diff --git a/Makefile b/Makefile index 58d7915e2..105ac61a6 100644 --- a/Makefile +++ b/Makefile @@ -134,7 +134,7 @@ mypy: mypy --install-types --ignore-missing-imports --non-interactive mathics plot-detailed-tests: - MATHICS_CHARACTER_ENCODING="ASCII" MATHICS_PLOT_DETAILED_TESTS="1" $(PYTHON) -m pytest -x $(PYTEST_OPTIONS) test/builtin/drawing/test_plot_detail.py + MATHICS_PLOT_DETAILED_TESTS="1" $(PYTHON) -m pytest -x $(PYTEST_OPTIONS) test/builtin/drawing/test_plot_detail.py #: Run pytest tests. Use environment variable "PYTEST_OPTIONS" for pytest options pytest: @@ -156,7 +156,7 @@ latex-doctest-data: mathics/builtin/*.py mathics/doc/documentation/*.mdoc mathic #: Run tests that appear in docstring in the code. Use environment variable "DOCTEST_OPTIONS" for doctest options doctest: - MATHICS_CHARACTER_ENCODING="ASCII" MATHICS3_SANDBOX=$(MATHICS3_SANDBOX) $(PYTHON) mathics/docpipeline.py $(DOCTEST_OPTIONS) + MATHICS3_SANDBOX=$(MATHICS3_SANDBOX) $(PYTHON) mathics/docpipeline.py $(DOCTEST_OPTIONS) #: Run tests that appear in docstring in the code, stopping on the first error. doctest-x: diff --git a/mathics/Data/ExampleData/HelloWorld.wl b/mathics/Data/ExampleData/HelloWorld.wl new file mode 100644 index 000000000..bd83ab015 --- /dev/null +++ b/mathics/Data/ExampleData/HelloWorld.wl @@ -0,0 +1,2 @@ +(* An example of a Wolfram Language/Mathics3 program that can be used for testing. *) +"Hello, " <> "World!" diff --git a/mathics/SystemFiles/Formats/WL/Import.wl b/mathics/SystemFiles/Formats/WL/Import.wl new file mode 100644 index 000000000..32794e48c --- /dev/null +++ b/mathics/SystemFiles/Formats/WL/Import.wl @@ -0,0 +1,17 @@ +(* ::Package:: *) + +(* Note: this is stripped down a lot from what WMA handles. *) + +Begin["System`Convert`WLDump`"]; + + +ImportExport`RegisterImport[ + "WL", (* WMA mime-type name *) + WLDump`ImportWL (* Default Function name that handles this. *), + {}, + "AvailableElements" -> {"Get", "Script"}, + "DefaultElement" -> "Get" +]; + + +End[]; diff --git a/mathics/builtin/atomic/symbols.py b/mathics/builtin/atomic/symbols.py index c576905a2..f541b5bbf 100644 --- a/mathics/builtin/atomic/symbols.py +++ b/mathics/builtin/atomic/symbols.py @@ -422,7 +422,7 @@ class FormatValues(Builtin): The replacement pattern on the right in the delayed rule is formatted according to the top-level form. To see the rule input, we can use 'InputForm': >> FormatValues[F] //InputForm - = {HoldPattern[Format[F[x_], OutputForm]] ⧴ Subscript[x, F]} + = {HoldPattern[Format[F[x_], OutputForm]] :> Subscript[x, F]} """ summary_text = ( diff --git a/mathics/builtin/fileformats/wlformat.py b/mathics/builtin/fileformats/wlformat.py new file mode 100644 index 000000000..4fd5e2e94 --- /dev/null +++ b/mathics/builtin/fileformats/wlformat.py @@ -0,0 +1,52 @@ +""" +WL File Format + +WL and Mathics3 importer +""" + +from mathics.core.builtin import Builtin, String +from mathics.core.evaluation import Evaluation +from mathics.eval.fileformats.wlformat import eval_WLImport + + +class ImportWL(Builtin): + """ + :WMA link:https://reference.wolfram.com/language/ref/format/WL.html + +
+
'WLDump`ImportWL[$path$]' +
Read $path$ as a Wolfram package and 'Get' it. +
+ + This command is hooked into the 'Import' command via \ + 'SystemFiles/Formats/WL/Import.wl'. + + When running this command directly, a list of rules is returned: + + >> WLDump`ImportWL["ExampleData/HelloWorld.wl"] + = {Get ⇾ Hello, World!, Script ⇾ Hello, World!} + + The left-hand side is a element name that can be provided to 'Import', \ + and the right-hand side is the value associated with that element. Here it \ + represents the last evaluation value when evaluating the contents of the file. + + When an 'Import' is done and the file mentioned is a Mathics3 or a \ + Wolfram-Language file, this command is run underneath selecting value of the \ + "Get" element: + + >> Import["ExampleData/HelloWorld.wl"] + = Hello, World! + + All of this is the same as just running a simple 'Get': + >> << "ExampleData/HelloWorld.wl" + = Hello, World! + + In sum, the built-in provides the glue to the 'Import' accees mechanism for 'Get'. + """ + + context = "WLDump`" + summary_text = "import WL file" + + def eval(self, path: String, evaluation: Evaluation): + "WLDump`ImportWL[path_String]" + return eval_WLImport(path, evaluation) diff --git a/mathics/builtin/functional/apply_fns_to_lists.py b/mathics/builtin/functional/apply_fns_to_lists.py index f5e0529cd..1eeed7b38 100644 --- a/mathics/builtin/functional/apply_fns_to_lists.py +++ b/mathics/builtin/functional/apply_fns_to_lists.py @@ -224,11 +224,11 @@ class MapAt(Builtin): Map $f$ onto at the second position of an association: >> MapAt[f, <|"a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4|>, 2] - = <|a -> 1, b -> f[2], c -> 3, d -> 4|> + = <|a ⇾ 1, b ⇾ f[2], c ⇾ 3, d ⇾ 4|> Same as above, but select the second-from-the-end position: >> MapAt[f, <|"a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4|>, -2] - = <|a -> 1, b -> 2, c -> f[3], d -> 4|> + = <|a ⇾ 1, b ⇾ 2, c ⇾ f[3], d ⇾ 4|> """ diff --git a/mathics/builtin/layout.py b/mathics/builtin/layout.py index d246705ef..4f1ae83f0 100644 --- a/mathics/builtin/layout.py +++ b/mathics/builtin/layout.py @@ -100,7 +100,7 @@ class Format(Builtin): Mathics3 input: >> Format[{a -> Integrate[F[x], x]}, StandardForm] //InputForm - = Format[{a ⇾ Integrate[F[x], x]}, StandardForm] + = Format[{a -> Integrate[F[x], x]}, StandardForm] In WMA, you might not get something that can be used as input. diff --git a/mathics/builtin/numbers/algebra.py b/mathics/builtin/numbers/algebra.py index 36f3ab273..c5cc00c70 100644 --- a/mathics/builtin/numbers/algebra.py +++ b/mathics/builtin/numbers/algebra.py @@ -135,7 +135,7 @@ class Apart(Builtin): = Sin[1 / (x ^ 2 - y ^ 2)] >> a == "A" // Apart // InputForm - = a ⩵ "A" + = a == "A" """ attributes = A_LISTABLE | A_PROTECTED @@ -175,7 +175,7 @@ class Cancel(Builtin): But it does not touch other expressions: >> a == "A" // Cancel // InputForm - = a ⩵ "A" + = a == "A" """ attributes = A_LISTABLE | A_PROTECTED @@ -976,7 +976,7 @@ class Factor(Builtin): But it does not touch other expressions: >> a == "A" // Factor // InputForm - = a ⩵ "A" + = a == "A" """ attributes = A_LISTABLE | A_PROTECTED diff --git a/mathics/doc/documentation/1-Manual.mdoc b/mathics/doc/documentation/1-Manual.mdoc index 4b7f03726..be91db740 100644 --- a/mathics/doc/documentation/1-Manual.mdoc +++ b/mathics/doc/documentation/1-Manual.mdoc @@ -1233,15 +1233,15 @@ 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[{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&)], 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&)], 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&)], 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&)], 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]] + . 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]