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
60 changes: 26 additions & 34 deletions mathics/format/render/latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,12 +284,11 @@ def pane_box(box: PaneBox, **options):


def fractionbox(box: FractionBox, **options) -> str:
_options = box.box_options.copy()
_options.update(options)
options = _options
# Note: values set in `options` take precedence over `box_options`
child_options = {**options, **box.box_options}
return "\\frac{%s}{%s}" % (
lookup_conversion_method(box.num, "latex")(box.num, **options),
lookup_conversion_method(box.den, "latex")(box.den, **options),
lookup_conversion_method(box.num, "latex")(box.num, **child_options),
lookup_conversion_method(box.den, "latex")(box.den, **child_options),
)


Expand Down Expand Up @@ -341,26 +340,23 @@ def boxes_to_tex(box, **options):


def sqrtbox(box: SqrtBox, **options):
_options = box.box_options.copy()
_options.update(options)
options = _options
# Note: values set in `options` take precedence over `box_options`
child_options = {**options, **box.box_options}
if box.index:
return "\\sqrt[%s]{%s}" % (
lookup_conversion_method(box.radicand, "latex")(box.radicand, **options),
lookup_conversion_method(box.index, "latex")(box.index, **options),
)
return "\\sqrt{%s}" % lookup_conversion_method(box.radicand, "latex")(
box.radicand, **options
box.radicand, **child_options
)


add_conversion_fn(SqrtBox, sqrtbox)


def superscriptbox(box: SuperscriptBox, **options):
_options = box.box_options.copy()
_options.update(options)
options = _options
child_options = {**options, **box.box_options}
base_to_tex = lookup_conversion_method(box.base, "latex")
tex1 = base_to_tex(box.base, **options)

Expand All @@ -372,7 +368,7 @@ def superscriptbox(box: SuperscriptBox, **options):
return "%s''" % tex1
base = box.tex_block(tex1, True)
superidx_to_tex = lookup_conversion_method(box.superindex, "latex")
superindx = box.tex_block(superidx_to_tex(box.superindex, **options), True)
superindx = box.tex_block(superidx_to_tex(box.superindex, **child_options), True)
if len(superindx) == 1 and isinstance(box.superindex, (String, StyleBox)):
return "%s^%s" % (
base,
Expand All @@ -388,32 +384,30 @@ def superscriptbox(box: SuperscriptBox, **options):


def subscriptbox(box: SubscriptBox, **options):
_options = box.box_options.copy()
_options.update(options)
options = _options
# Note: values set in `options` take precedence over `box_options`
child_options = {**options, **box.box_options}
base_to_tex = lookup_conversion_method(box.base, "latex")
subidx_to_tex = lookup_conversion_method(box.subindex, "latex")
return "%s_%s" % (
box.tex_block(base_to_tex(box.base, **options), True),
box.tex_block(subidx_to_tex(box.subindex, **options)),
box.tex_block(base_to_tex(box.base, **child_options), True),
box.tex_block(subidx_to_tex(box.subindex, **child_options)),
)


add_conversion_fn(SubscriptBox, subscriptbox)


def subsuperscriptbox(box: SubsuperscriptBox, **options):
_options = box.box_options.copy()
_options.update(options)
options = _options
# Note: values set in `options` take precedence over `box_options`
child_options = {**box.box_options, **options}
base_to_tex = lookup_conversion_method(box.base, "latex")
subidx_to_tex = lookup_conversion_method(box.subindex, "latex")
superidx_to_tex = lookup_conversion_method(box.superindex, "latex")

return "%s_%s^%s" % (
box.tex_block(base_to_tex(box.base, **options), True),
box.tex_block(subidx_to_tex(box.subindex, **options)),
box.tex_block(superidx_to_tex(box.superindex, **options)),
box.tex_block(base_to_tex(box.base, **child_options), True),
box.tex_block(subidx_to_tex(box.subindex, **child_options)),
box.tex_block(superidx_to_tex(box.superindex, **child_options)),
)


Expand Down Expand Up @@ -469,33 +463,31 @@ def rowbox_parenthesized(items, **options):


def rowbox(box: RowBox, **options) -> str:
_options = box.box_options.copy()
_options.update(options)
options = _options
# Note: values set in `options` take precedence over `box_options`
child_options = {**box.box_options, **options}
items = box.items
# Handle special cases
if len(items) >= 3:
head, *rest = items
rest_latex = rowbox_parenthesized(rest, **options)
if rest_latex is not None:
# Must be a function-like expression f[]
head_latex = lookup_conversion_method(head, "latex")(head, **options)
head_latex = lookup_conversion_method(head, "latex")(head, **child_options)
return head_latex + rest_latex
if len(items) >= 2:
parenthesized_latex = rowbox_parenthesized(items, **options)
parenthesized_latex = rowbox_parenthesized(items, **child_options)
if parenthesized_latex is not None:
return parenthesized_latex
return rowbox_sequence(items, **options)
return rowbox_sequence(items, **child_options)


add_conversion_fn(RowBox, rowbox)


def stylebox(box: StyleBox, **options) -> str:
_options = box.box_options.copy()
_options.update(options)
options = _options
return lookup_conversion_method(box.boxes, "latex")(box.boxes, **options)
# Note: values set in `options` take precedence over `box_options`
child_options = {**box.box_options, **options}
return lookup_conversion_method(box.boxes, "latex")(box.boxes, **child_options)


add_conversion_fn(StyleBox, stylebox)
Expand Down
123 changes: 59 additions & 64 deletions mathics/format/render/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"""


from mathics.builtin.box.expression import BoxExpression
from mathics.builtin.box.graphics import GraphicsBox
from mathics.builtin.box.graphics3d import Graphics3DBox
from mathics.builtin.box.layout import (
Expand All @@ -22,15 +23,18 @@
)
from mathics.core.atoms import String
from mathics.core.exceptions import BoxConstructError
from mathics.core.formatter import add_conversion_fn, lookup_method
from mathics.core.formatter import (
add_conversion_fn,
lookup_method as lookup_conversion_method,
)
from mathics.core.symbols import Atom, SymbolTrue
from mathics.format.box.graphics import prepare_elements as prepare_elements2d
from mathics.format.box.graphics3d import prepare_elements as prepare_elements3d
from mathics.format.form.util import _WrongFormattedExpression, text_cells_to_grid


def boxes_to_text(boxes, **options) -> str:
return lookup_method(boxes, "text")(boxes, **options)
return lookup_conversion_method(boxes, "text")(boxes, **options)


def string(s: String, **options) -> str:
Expand All @@ -47,30 +51,28 @@ def string(s: String, **options) -> str:
add_conversion_fn(String, string)


def interpretation_box(self, **options):
return boxes_to_text(self.boxes, **options)
def interpretation_box(box: InterpretationBox, **options):
return boxes_to_text(box.boxes, **options)


add_conversion_fn(InterpretationBox, interpretation_box)


def pane_box(self, **options):
result = boxes_to_text(self.boxes, **options)
return result
def pane_box(box: PaneBox, **options):
return boxes_to_text(box.boxes, **options)


add_conversion_fn(PaneBox, pane_box)


def fractionbox(self, **options) -> str:
_options = self.box_options.copy()
_options.update(options)
options = _options
num_text = boxes_to_text(self.num, **options)
den_text = boxes_to_text(self.den, **options)
if isinstance(self.num, RowBox):
def fractionbox(box: FractionBox, **options) -> str:
# Note: values set in `options` take precedence over `box_options`
child_options = {**options, **box.box_options}
num_text = boxes_to_text(box.num, **child_options)
den_text = boxes_to_text(box.den, **child_options)
if isinstance(box.num, RowBox):
num_text = f"({num_text})"
if isinstance(self.den, RowBox):
if isinstance(box.den, RowBox):
den_text = f"({den_text})"

return " / ".join([num_text, den_text])
Expand All @@ -79,13 +81,13 @@ def fractionbox(self, **options) -> str:
add_conversion_fn(FractionBox, fractionbox)


def gridbox(self, elements=None, **box_options) -> str:
def gridbox(box: GridBox, elements=None, **box_options) -> str:
if not elements:
elements = self.items
elements = box.items
evaluation = box_options.get("evaluation", None)
items, options = self.get_array(elements, evaluation)
items, options = box.get_array(elements, evaluation)

box_options.update(self.options)
box_options.update(box.options)

if not items:
return ""
Expand All @@ -112,27 +114,25 @@ def gridbox(self, elements=None, **box_options) -> str:
add_conversion_fn(GridBox, gridbox)


def sqrtbox(self, **options) -> str:
_options = self.box_options.copy()
_options.update(options)
options = _options
if self.index:
def sqrtbox(box: SqrtBox, **options) -> str:
# Note: values set in `options` take precedence over `box_options`
child_options = {**options, **box.box_options}
if box.index:
return "Sqrt[%s,%s]" % (
boxes_to_text(self.radicand, **options),
boxes_to_text(self.index, **options),
boxes_to_text(box.radicand, **child_options),
boxes_to_text(box.index, **child_options),
)
return "Sqrt[%s]" % (boxes_to_text(self.radicand, **options))
return "Sqrt[%s]" % (boxes_to_text(box.radicand, **child_options))


add_conversion_fn(SqrtBox, sqrtbox)


def superscriptbox(self, **options) -> str:
_options = self.box_options.copy()
_options.update(options)
options = _options
def superscriptbox(box: SuperscriptBox, **options) -> str:
# Note: values set in `options` take precedence over `box_options`
child_options = {**options, **box.box_options}
no_parenthesize = True
index = self.superindex
index = box.superindex
while not isinstance(index, Atom):
if isinstance(index, StyleBox):
index = index.boxes
Expand All @@ -143,46 +143,43 @@ def superscriptbox(self, **options) -> str:

fmt_str = "%s^%s" if no_parenthesize else "%s^(%s)"
return fmt_str % (
boxes_to_text(self.base, **options),
boxes_to_text(self.superindex, **options),
boxes_to_text(box.base, **child_options),
boxes_to_text(box.superindex, **child_options),
)


add_conversion_fn(SuperscriptBox, superscriptbox)


def subscriptbox(self, **options) -> str:
_options = self.box_options.copy()
_options.update(options)
options = _options
def subscriptbox(box: SubscriptBox, **options) -> str:
# Note: values set in `options` take precedence over `box_options`
child_options = {**box.box_options, **options}
return "Subscript[%s, %s]" % (
boxes_to_text(self.base, **options),
boxes_to_text(self.subindex, **options),
boxes_to_text(box.base, **child_options),
boxes_to_text(box.subindex, **child_options),
)


add_conversion_fn(SubscriptBox, subscriptbox)


def subsuperscriptbox(self, **options) -> str:
_options = self.box_options.copy()
_options.update(options)
options = _options
def subsuperscriptbox(box: SubsuperscriptBox, **options) -> str:
# Note: values set in `options` take precedence over `box_options`
child_options = {**box.box_options, **options}
return "Subsuperscript[%s, %s, %s]" % (
boxes_to_text(self.base, **options),
boxes_to_text(self.subindex, **options),
boxes_to_text(self.superindex, **options),
boxes_to_text(box.base, **child_options),
boxes_to_text(box.subindex, **child_options),
boxes_to_text(box.superindex, **child_options),
)


add_conversion_fn(SubsuperscriptBox, subsuperscriptbox)


def rowbox(self, elements=None, **options) -> str:
_options = self.box_options.copy()
_options.update(options)
options = _options
parts_str = [boxes_to_text(element, **options) for element in self.items]
def rowbox(box: RowBox, elements=None, **options) -> str:
# Note: values set in `options` take precedence over `box_options`
child_options = {**box.box_options, **options}
parts_str = [boxes_to_text(element, **child_options) for element in box.items]
if len(parts_str) == 0:
return ""
if len(parts_str) == 1:
Expand All @@ -209,39 +206,37 @@ def rowbox(self, elements=None, **options) -> str:
add_conversion_fn(RowBox, rowbox)


def stylebox(self, **options) -> str:
options.pop("evaluation", None)
_options = self.box_options.copy()
_options.update(options)
options = _options
return boxes_to_text(self.boxes, **options)
def stylebox(box: StyleBox, **options) -> str:
# Note: values set in `options` take precedence over `box_options`
child_options = {**box.box_options, **options}
return boxes_to_text(box.boxes, **child_options)


add_conversion_fn(StyleBox, stylebox)


def graphicsbox(self, elements=None, **options) -> str:
def graphicsbox(box: GraphicsBox, elements=None, **options) -> str:
assert elements is None

prepare_elements2d(self, self.content, options) # to test for Box errors
prepare_elements2d(box, box.content, options) # to test for Box errors
return "-Graphics-"


add_conversion_fn(GraphicsBox, graphicsbox)


def graphics3dbox(self, elements=None, **options) -> str:
def graphics3dbox(box: Graphics3DBox, elements=None, **options) -> str:
assert elements is None

prepare_elements3d(self, self.content, options) # to test for Box errors
prepare_elements3d(box, box.content, options) # to test for Box errors
return "-Graphics3D-"


add_conversion_fn(Graphics3DBox, graphics3dbox)


def tag_and_form_box(self, **options):
return boxes_to_text(self.boxes, **options)
def tag_and_form_box(box: BoxExpression, **options):
return boxes_to_text(box.boxes, **options)


add_conversion_fn(FormBox, tag_and_form_box)
Expand Down
Loading