Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/workflows/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/plot-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 ..
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/pyodide.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ubuntu-bench.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ubuntu-cython.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 ..

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
8 changes: 4 additions & 4 deletions mathics/builtin/files_io/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
SymbolFailed,
SymbolHold,
SymbolHoldExpression,
SymbolInputForm,
SymbolInputStream,
SymbolOutputForm,
SymbolOutputStream,
Expand All @@ -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):
Expand Down Expand Up @@ -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"
Expand Down
79 changes: 63 additions & 16 deletions mathics/builtin/forms/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -32,6 +32,7 @@
from mathics.core.systemsymbols import (
SymbolAutomatic,
SymbolInfinity,
SymbolInputForm,
SymbolMakeBoxes,
SymbolNumberForm,
SymbolRowBox,
Expand All @@ -48,6 +49,7 @@
eval_tableform,
eval_texform,
)
from mathics.form import render_input_form


class BaseForm(FormBaseClass):
Expand Down Expand Up @@ -184,29 +186,74 @@ def eval_mathml(self, expr, evaluation) -> Expression:

class InputForm(FormBaseClass):
r"""
<url>
:WMA link:
https://reference.wolfram.com/language/ref/InputForm.html</url>
<url>
:WMA link:
https://reference.wolfram.com/language/ref/InputForm.html</url>

<dl>
<dt>'InputForm'[$expr$]
<dd>displays $expr$ in an unambiguous form suitable for input.
</dl>
<dl>
<dt>'InputForm'[$expr$]
<dd>displays $expr$ in an unambiguous form suitable for input to Mathics3.
</dl>

>> 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):
"""
Expand Down
11 changes: 5 additions & 6 deletions mathics/builtin/makeboxes.py
Original file line number Diff line number Diff line change
Expand Up @@ -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], "
Expand All @@ -114,26 +113,26 @@ 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)
return parenthesize(py_precedence, expr, boxes, True)

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)


Expand Down
3 changes: 3 additions & 0 deletions mathics/core/parser/operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
20 changes: 10 additions & 10 deletions mathics/doc/documentation/1-Manual.mdoc
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
8 changes: 7 additions & 1 deletion mathics/eval/makeboxes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,19 @@
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",
"StringLParen",
"StringRParen",
"_boxed_string",
"builtins_precedence",
"compare_precedence",
"do_format",
"eval_baseform",
"eval_generic_makeboxes",
Expand All @@ -40,5 +45,6 @@
"format_element",
"int_to_string_shorter_repr",
"parenthesize",
"render_input_form",
"to_boxes",
]
8 changes: 7 additions & 1 deletion mathics/eval/makeboxes/makeboxes.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
)
from mathics.core.systemsymbols import ( # SymbolRule, SymbolRuleDelayed,
SymbolComplex,
SymbolInputForm,
SymbolRational,
SymbolStandardForm,
)
Expand Down Expand Up @@ -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)


Expand Down
7 changes: 7 additions & 0 deletions mathics/form/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"""
Module containing functions for rendering $PrintForms Forms
"""

from mathics.form.inputform import render_input_form

__all__ = ["render_input_form"]
Loading
Loading