Skip to content

Commit 1d915c5

Browse files
authored
Revise render/latex.py for box attributes (#1677)
Revise render/latex.py and render/text.py for box attributes
1 parent 2acffaa commit 1d915c5

2 files changed

Lines changed: 85 additions & 98 deletions

File tree

mathics/format/render/latex.py

Lines changed: 26 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -284,12 +284,11 @@ def pane_box(box: PaneBox, **options):
284284

285285

286286
def fractionbox(box: FractionBox, **options) -> str:
287-
_options = box.box_options.copy()
288-
_options.update(options)
289-
options = _options
287+
# Note: values set in `options` take precedence over `box_options`
288+
child_options = {**options, **box.box_options}
290289
return "\\frac{%s}{%s}" % (
291-
lookup_conversion_method(box.num, "latex")(box.num, **options),
292-
lookup_conversion_method(box.den, "latex")(box.den, **options),
290+
lookup_conversion_method(box.num, "latex")(box.num, **child_options),
291+
lookup_conversion_method(box.den, "latex")(box.den, **child_options),
293292
)
294293

295294

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

342341

343342
def sqrtbox(box: SqrtBox, **options):
344-
_options = box.box_options.copy()
345-
_options.update(options)
346-
options = _options
343+
# Note: values set in `options` take precedence over `box_options`
344+
child_options = {**options, **box.box_options}
347345
if box.index:
348346
return "\\sqrt[%s]{%s}" % (
349347
lookup_conversion_method(box.radicand, "latex")(box.radicand, **options),
350348
lookup_conversion_method(box.index, "latex")(box.index, **options),
351349
)
352350
return "\\sqrt{%s}" % lookup_conversion_method(box.radicand, "latex")(
353-
box.radicand, **options
351+
box.radicand, **child_options
354352
)
355353

356354

357355
add_conversion_fn(SqrtBox, sqrtbox)
358356

359357

360358
def superscriptbox(box: SuperscriptBox, **options):
361-
_options = box.box_options.copy()
362-
_options.update(options)
363-
options = _options
359+
child_options = {**options, **box.box_options}
364360
base_to_tex = lookup_conversion_method(box.base, "latex")
365361
tex1 = base_to_tex(box.base, **options)
366362

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

389385

390386
def subscriptbox(box: SubscriptBox, **options):
391-
_options = box.box_options.copy()
392-
_options.update(options)
393-
options = _options
387+
# Note: values set in `options` take precedence over `box_options`
388+
child_options = {**options, **box.box_options}
394389
base_to_tex = lookup_conversion_method(box.base, "latex")
395390
subidx_to_tex = lookup_conversion_method(box.subindex, "latex")
396391
return "%s_%s" % (
397-
box.tex_block(base_to_tex(box.base, **options), True),
398-
box.tex_block(subidx_to_tex(box.subindex, **options)),
392+
box.tex_block(base_to_tex(box.base, **child_options), True),
393+
box.tex_block(subidx_to_tex(box.subindex, **child_options)),
399394
)
400395

401396

402397
add_conversion_fn(SubscriptBox, subscriptbox)
403398

404399

405400
def subsuperscriptbox(box: SubsuperscriptBox, **options):
406-
_options = box.box_options.copy()
407-
_options.update(options)
408-
options = _options
401+
# Note: values set in `options` take precedence over `box_options`
402+
child_options = {**box.box_options, **options}
409403
base_to_tex = lookup_conversion_method(box.base, "latex")
410404
subidx_to_tex = lookup_conversion_method(box.subindex, "latex")
411405
superidx_to_tex = lookup_conversion_method(box.superindex, "latex")
412406

413407
return "%s_%s^%s" % (
414-
box.tex_block(base_to_tex(box.base, **options), True),
415-
box.tex_block(subidx_to_tex(box.subindex, **options)),
416-
box.tex_block(superidx_to_tex(box.superindex, **options)),
408+
box.tex_block(base_to_tex(box.base, **child_options), True),
409+
box.tex_block(subidx_to_tex(box.subindex, **child_options)),
410+
box.tex_block(superidx_to_tex(box.superindex, **child_options)),
417411
)
418412

419413

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

470464

471465
def rowbox(box: RowBox, **options) -> str:
472-
_options = box.box_options.copy()
473-
_options.update(options)
474-
options = _options
466+
# Note: values set in `options` take precedence over `box_options`
467+
child_options = {**box.box_options, **options}
475468
items = box.items
476469
# Handle special cases
477470
if len(items) >= 3:
478471
head, *rest = items
479472
rest_latex = rowbox_parenthesized(rest, **options)
480473
if rest_latex is not None:
481474
# Must be a function-like expression f[]
482-
head_latex = lookup_conversion_method(head, "latex")(head, **options)
475+
head_latex = lookup_conversion_method(head, "latex")(head, **child_options)
483476
return head_latex + rest_latex
484477
if len(items) >= 2:
485-
parenthesized_latex = rowbox_parenthesized(items, **options)
478+
parenthesized_latex = rowbox_parenthesized(items, **child_options)
486479
if parenthesized_latex is not None:
487480
return parenthesized_latex
488-
return rowbox_sequence(items, **options)
481+
return rowbox_sequence(items, **child_options)
489482

490483

491484
add_conversion_fn(RowBox, rowbox)
492485

493486

494487
def stylebox(box: StyleBox, **options) -> str:
495-
_options = box.box_options.copy()
496-
_options.update(options)
497-
options = _options
498-
return lookup_conversion_method(box.boxes, "latex")(box.boxes, **options)
488+
# Note: values set in `options` take precedence over `box_options`
489+
child_options = {**box.box_options, **options}
490+
return lookup_conversion_method(box.boxes, "latex")(box.boxes, **child_options)
499491

500492

501493
add_conversion_fn(StyleBox, stylebox)

mathics/format/render/text.py

Lines changed: 59 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"""
55

66

7+
from mathics.builtin.box.expression import BoxExpression
78
from mathics.builtin.box.graphics import GraphicsBox
89
from mathics.builtin.box.graphics3d import Graphics3DBox
910
from mathics.builtin.box.layout import (
@@ -22,15 +23,18 @@
2223
)
2324
from mathics.core.atoms import String
2425
from mathics.core.exceptions import BoxConstructError
25-
from mathics.core.formatter import add_conversion_fn, lookup_method
26+
from mathics.core.formatter import (
27+
add_conversion_fn,
28+
lookup_method as lookup_conversion_method,
29+
)
2630
from mathics.core.symbols import Atom, SymbolTrue
2731
from mathics.format.box.graphics import prepare_elements as prepare_elements2d
2832
from mathics.format.box.graphics3d import prepare_elements as prepare_elements3d
2933
from mathics.format.form.util import _WrongFormattedExpression, text_cells_to_grid
3034

3135

3236
def boxes_to_text(boxes, **options) -> str:
33-
return lookup_method(boxes, "text")(boxes, **options)
37+
return lookup_conversion_method(boxes, "text")(boxes, **options)
3438

3539

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

4953

50-
def interpretation_box(self, **options):
51-
return boxes_to_text(self.boxes, **options)
54+
def interpretation_box(box: InterpretationBox, **options):
55+
return boxes_to_text(box.boxes, **options)
5256

5357

5458
add_conversion_fn(InterpretationBox, interpretation_box)
5559

5660

57-
def pane_box(self, **options):
58-
result = boxes_to_text(self.boxes, **options)
59-
return result
61+
def pane_box(box: PaneBox, **options):
62+
return boxes_to_text(box.boxes, **options)
6063

6164

6265
add_conversion_fn(PaneBox, pane_box)
6366

6467

65-
def fractionbox(self, **options) -> str:
66-
_options = self.box_options.copy()
67-
_options.update(options)
68-
options = _options
69-
num_text = boxes_to_text(self.num, **options)
70-
den_text = boxes_to_text(self.den, **options)
71-
if isinstance(self.num, RowBox):
68+
def fractionbox(box: FractionBox, **options) -> str:
69+
# Note: values set in `options` take precedence over `box_options`
70+
child_options = {**options, **box.box_options}
71+
num_text = boxes_to_text(box.num, **child_options)
72+
den_text = boxes_to_text(box.den, **child_options)
73+
if isinstance(box.num, RowBox):
7274
num_text = f"({num_text})"
73-
if isinstance(self.den, RowBox):
75+
if isinstance(box.den, RowBox):
7476
den_text = f"({den_text})"
7577

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

8183

82-
def gridbox(self, elements=None, **box_options) -> str:
84+
def gridbox(box: GridBox, elements=None, **box_options) -> str:
8385
if not elements:
84-
elements = self.items
86+
elements = box.items
8587
evaluation = box_options.get("evaluation", None)
86-
items, options = self.get_array(elements, evaluation)
88+
items, options = box.get_array(elements, evaluation)
8789

88-
box_options.update(self.options)
90+
box_options.update(box.options)
8991

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

114116

115-
def sqrtbox(self, **options) -> str:
116-
_options = self.box_options.copy()
117-
_options.update(options)
118-
options = _options
119-
if self.index:
117+
def sqrtbox(box: SqrtBox, **options) -> str:
118+
# Note: values set in `options` take precedence over `box_options`
119+
child_options = {**options, **box.box_options}
120+
if box.index:
120121
return "Sqrt[%s,%s]" % (
121-
boxes_to_text(self.radicand, **options),
122-
boxes_to_text(self.index, **options),
122+
boxes_to_text(box.radicand, **child_options),
123+
boxes_to_text(box.index, **child_options),
123124
)
124-
return "Sqrt[%s]" % (boxes_to_text(self.radicand, **options))
125+
return "Sqrt[%s]" % (boxes_to_text(box.radicand, **child_options))
125126

126127

127128
add_conversion_fn(SqrtBox, sqrtbox)
128129

129130

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

144144
fmt_str = "%s^%s" if no_parenthesize else "%s^(%s)"
145145
return fmt_str % (
146-
boxes_to_text(self.base, **options),
147-
boxes_to_text(self.superindex, **options),
146+
boxes_to_text(box.base, **child_options),
147+
boxes_to_text(box.superindex, **child_options),
148148
)
149149

150150

151151
add_conversion_fn(SuperscriptBox, superscriptbox)
152152

153153

154-
def subscriptbox(self, **options) -> str:
155-
_options = self.box_options.copy()
156-
_options.update(options)
157-
options = _options
154+
def subscriptbox(box: SubscriptBox, **options) -> str:
155+
# Note: values set in `options` take precedence over `box_options`
156+
child_options = {**box.box_options, **options}
158157
return "Subscript[%s, %s]" % (
159-
boxes_to_text(self.base, **options),
160-
boxes_to_text(self.subindex, **options),
158+
boxes_to_text(box.base, **child_options),
159+
boxes_to_text(box.subindex, **child_options),
161160
)
162161

163162

164163
add_conversion_fn(SubscriptBox, subscriptbox)
165164

166165

167-
def subsuperscriptbox(self, **options) -> str:
168-
_options = self.box_options.copy()
169-
_options.update(options)
170-
options = _options
166+
def subsuperscriptbox(box: SubsuperscriptBox, **options) -> str:
167+
# Note: values set in `options` take precedence over `box_options`
168+
child_options = {**box.box_options, **options}
171169
return "Subsuperscript[%s, %s, %s]" % (
172-
boxes_to_text(self.base, **options),
173-
boxes_to_text(self.subindex, **options),
174-
boxes_to_text(self.superindex, **options),
170+
boxes_to_text(box.base, **child_options),
171+
boxes_to_text(box.subindex, **child_options),
172+
boxes_to_text(box.superindex, **child_options),
175173
)
176174

177175

178176
add_conversion_fn(SubsuperscriptBox, subsuperscriptbox)
179177

180178

181-
def rowbox(self, elements=None, **options) -> str:
182-
_options = self.box_options.copy()
183-
_options.update(options)
184-
options = _options
185-
parts_str = [boxes_to_text(element, **options) for element in self.items]
179+
def rowbox(box: RowBox, elements=None, **options) -> str:
180+
# Note: values set in `options` take precedence over `box_options`
181+
child_options = {**box.box_options, **options}
182+
parts_str = [boxes_to_text(element, **child_options) for element in box.items]
186183
if len(parts_str) == 0:
187184
return ""
188185
if len(parts_str) == 1:
@@ -209,39 +206,37 @@ def rowbox(self, elements=None, **options) -> str:
209206
add_conversion_fn(RowBox, rowbox)
210207

211208

212-
def stylebox(self, **options) -> str:
213-
options.pop("evaluation", None)
214-
_options = self.box_options.copy()
215-
_options.update(options)
216-
options = _options
217-
return boxes_to_text(self.boxes, **options)
209+
def stylebox(box: StyleBox, **options) -> str:
210+
# Note: values set in `options` take precedence over `box_options`
211+
child_options = {**box.box_options, **options}
212+
return boxes_to_text(box.boxes, **child_options)
218213

219214

220215
add_conversion_fn(StyleBox, stylebox)
221216

222217

223-
def graphicsbox(self, elements=None, **options) -> str:
218+
def graphicsbox(box: GraphicsBox, elements=None, **options) -> str:
224219
assert elements is None
225220

226-
prepare_elements2d(self, self.content, options) # to test for Box errors
221+
prepare_elements2d(box, box.content, options) # to test for Box errors
227222
return "-Graphics-"
228223

229224

230225
add_conversion_fn(GraphicsBox, graphicsbox)
231226

232227

233-
def graphics3dbox(self, elements=None, **options) -> str:
228+
def graphics3dbox(box: Graphics3DBox, elements=None, **options) -> str:
234229
assert elements is None
235230

236-
prepare_elements3d(self, self.content, options) # to test for Box errors
231+
prepare_elements3d(box, box.content, options) # to test for Box errors
237232
return "-Graphics3D-"
238233

239234

240235
add_conversion_fn(Graphics3DBox, graphics3dbox)
241236

242237

243-
def tag_and_form_box(self, **options):
244-
return boxes_to_text(self.boxes, **options)
238+
def tag_and_form_box(box: BoxExpression, **options):
239+
return boxes_to_text(box.boxes, **options)
245240

246241

247242
add_conversion_fn(FormBox, tag_and_form_box)

0 commit comments

Comments
 (0)