Skip to content
Open
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
2 changes: 1 addition & 1 deletion mathics/builtin/atomic/strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -876,7 +876,7 @@ class ToString(Builtin):
>> "U" <> ToString[2]
= U2
>> ToString[Integrate[f[x],x], TeXForm]
= \\int f\\left(x\\right) \\, dx
= \\int f(x) \\, dx

"""

Expand Down
2 changes: 1 addition & 1 deletion mathics/builtin/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class Format(Builtin):

Format can be used to specify the request format:
>> Format[Integrate[F[x], x], TeXForm]
= \\int F\\left(x\\right) \\, dx
= \\int F(x) \\, dx

Format evaluates its first element before applying the format:
>> Format[Integrate[Cos[x], x], TeXForm]
Expand Down
4 changes: 2 additions & 2 deletions mathics/builtin/list/associations.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ class Association(Builtin):
>> <|a -> x, b -> y|>
= <|a -> x, b -> y|>

>> Association[{a -> x, b -> y}]
= <|a -> x, b -> y|>
>> Association[{a -> x^2, b -> y}]
= <|a -> x ^ 2, b -> y|>

Associations can be nested:
>> <|a -> x, b -> y, <|a -> z, d -> t|>|>
Expand Down
4 changes: 2 additions & 2 deletions mathics/builtin/numbers/calculus.py
Original file line number Diff line number Diff line change
Expand Up @@ -1007,8 +1007,8 @@ class Integrate(SympyFunction):
= Integrate[1, {x, Infinity, 0}]

Here how is an example of converting integral equation to TeX:
>> Integrate[f[x], {x, a, b}] // TeXForm
= \int_a^b f\left(x\right) \, dx
>> Integrate[f[x^2], {x, a, b}] // TeXForm
= \int_a^b f\left(x^2\right) \, dx

Sometimes there is a loss of precision during integration.
You can check the precision of your result with the following sequence \
Expand Down
6 changes: 3 additions & 3 deletions mathics/doc/documentation/1-Manual.mdoc
Original file line number Diff line number Diff line change
Expand Up @@ -942,7 +942,7 @@ For instance, you can override 'MakeBoxes' to format lists in a different way:
= {1, 2, 3}

>> {1, 2, 3} // TeXForm
= \left[1 2 3\right]
= [1 2 3]

However, this will not be accepted as input to \Mathics anymore:
>> [1 2 3]
Expand Down Expand Up @@ -970,7 +970,7 @@ The desired effect can be achieved in the following way:
= squared[1, 2]

#> squared[1, 2] // TeXForm
= \text{squared}\left[1, 2\right]^2
= \text{squared}[1, 2]^2

You can view the box structure of a formatted expression using 'ToBoxes':

Expand Down Expand Up @@ -1115,7 +1115,7 @@ Three-dimensional plots are supported as well:
Here are some examples written by Jan Pöschko that come from the very first version.

<section title="Curve Sketching">
Let\'s sketch the function
Let's sketch the function
>> f[x_] := 4 x / (x ^ 2 + 3 x + 5)

The derivatives are:
Expand Down
2 changes: 1 addition & 1 deletion mathics/docpipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ def create_output(test_pipeline, tests):
if output_format in ("latex", "xml"):

def out_wrapper(expr):
return f"{expr} // StandardForm"
return f"StandardForm[{expr}]"

else:

Expand Down
114 changes: 109 additions & 5 deletions mathics/format/render/latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,71 @@
# mathics_scanner does not generates this table in a way that we can load it here.
# When it get fixed, we can use that table instead of this one:

BRACKET_INFO = {
(
String("("),
String(")"),
): {
"latex_open": "(",
"latex_closing": ")",
"latex_open_large": r"\left(",
"latex_closing_large": r"\right)",
},
(
String("{"),
String("}"),
): {
"latex_open": r"\{",
"latex_closing": r"\}",
"latex_open_large": r"\left\{",
"latex_closing_large": r"\right\}",
},
(
String("["),
String("]"),
): {
"latex_open": "[",
"latex_closing": "]",
"latex_open_large": r"\left[",
"latex_closing_large": r"\right]",
},
(
String("\u301A"),
String("\u301B"),
): {
"latex_open": r"[[",
"latex_closing": "]]",
"latex_open_large": r"\left[\left[",
"latex_closing_large": r"\right]\right]",
},
(
String("\u2329"),
String("\u232A"),
): {
"latex_open": "\\langle",
"latex_closing": "\\rangle",
"latex_open_large": r"\left\langle ",
"latex_closing_large": r"\right\rangle ",
},
(
String("\u2016"),
String("\u2016"),
): {
"latex_open": r"\|",
"latex_closing": r"\|",
"latex_open_large": r"\left\|",
"latex_closing_large": r"\right\| ",
},
(
String("<|"),
String("|>"),
): {
"latex_open": r"\langle\vert ",
"latex_closing": r"\vert\rangle ",
"latex_open_large": r"\left\langle\left\vert ",
"latex_closing_large": r"\right\vert\right\rangle ",
},
}

TEX_REPLACE = {
"{": r"\{",
Expand Down Expand Up @@ -347,14 +412,13 @@ def subsuperscriptbox(self, **options):
add_conversion_fn(SubsuperscriptBox, subsuperscriptbox)


def rowbox(self, **options) -> str:
_options = self.box_options.copy()
_options.update(options)
options = _options
def rowbox_sequence(items, **options):
parts_str = [
lookup_conversion_method(element, "latex")(element, **options)
for element in self.items
for element in items
]
if len(parts_str) == 0:
return ""
if len(parts_str) == 1:
return parts_str[0]
# This loop integrate all the row adding spaces after a ",", followed
Expand All @@ -376,6 +440,46 @@ def rowbox(self, **options) -> str:
return result


def rowbox_parenthesized(items, **options):
if len(items) < 2:
return None
key = (
items[0],
items[-1],
)
items = items[1:-1]
try:
bracket_data = BRACKET_INFO[key]
except KeyError:
return None

contain = rowbox_sequence(items, **options) if len(items) > 0 else ""

if any(item.is_multiline for item in items):
return f'{bracket_data["latex_open_large"]}{contain}{bracket_data["latex_closing_large"]}'
return f'{bracket_data["latex_open"]}{contain}{bracket_data["latex_closing"]}'


def rowbox(self, **options) -> str:
_options = self.box_options.copy()
_options.update(options)
options = _options
items = self.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)
return head_latex + rest_latex
if len(items) >= 2:
parenthesized_latex = rowbox_parenthesized(items, **options)
if parenthesized_latex is not None:
return parenthesized_latex
return rowbox_sequence(items, **options)


add_conversion_fn(RowBox, rowbox)


Expand Down
4 changes: 2 additions & 2 deletions test/doc/test_latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ def test_load_latex_documentation():
r"\begin{testresult}o\end{testresult}\end{testcase}"
)
assert (
doc_in_section.latex(doc_data)[:40]
).strip() == "Let\\'s sketch the function\n\\begin{tests}"
doc_in_section.latex(doc_data)[:39]
).strip() == "Let's sketch the function\n\\begin{tests}"
assert (
first_section.latex(doc_data)[:30]
).strip() == "\\section{Curve Sketching}{}"
Expand Down
18 changes: 9 additions & 9 deletions test/format/format_tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,8 @@
latex:
System`InputForm: '\text{$<$$\vert$a -$>$ x, b -$>$ y, c -$>$ $<$$\vert$d -$>$ t$\vert$$>$$\vert$$>$}'
System`OutputForm: '\text{$<$$\vert$a -$>$ x, b -$>$ y, c -$>$ $<$$\vert$d -$>$ t$\vert$$>$$\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$$>$}'
System`StandardForm: '\langle\vert a->x, b->y, c->\langle\vert d->t\vert\rangle \vert\rangle'
System`TraditionalForm: '\langle\vert a->x, b->y, c->\langle\vert d->t\vert\rangle \vert\rangle'
mathml:
System`InputForm: <mtext>&lt;|a&nbsp;-&gt;&nbsp;x,&nbsp;b&nbsp;-&gt;&nbsp;y,&nbsp;c&nbsp;-&gt;&nbsp;&lt;|d&nbsp;-&gt;&nbsp;t|&gt;|&gt;</mtext>
System`OutputForm: '<mtext>&lt;|a&nbsp;-&gt;&nbsp;x,&nbsp;b&nbsp;-&gt;&nbsp;y,&nbsp;c&nbsp;-&gt;&nbsp;&lt;|d&nbsp;-&gt;&nbsp;t|&gt;|&gt;</mtext>'
Expand All @@ -313,8 +313,8 @@ Association[a -> x, b -> y, c -> Association[d -> t, Association[e -> u]]]:
latex:
System`InputForm: '\text{$<$$\vert$a -$>$ x, b -$>$ y, c -$>$ $<$$\vert$d -$>$ t, e -$>$ u$\vert$$>$$\vert$$>$}'
System`OutputForm: '\text{$<$$\vert$a -$>$ x, b -$>$ y, c -$>$ $<$$\vert$d -$>$ t, e -$>$ u$\vert$$>$$\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$$>$}'
System`StandardForm: '\langle\vert a->x, b->y, c->\langle\vert d->t, e->u\vert\rangle \vert\rangle'
System`TraditionalForm: '\langle\vert a->x, b->y, c->\langle\vert d->t, e->u\vert\rangle \vert\rangle'
mathml:
System`InputForm: <mtext>&lt;|a&nbsp;-&gt;&nbsp;x,&nbsp;b&nbsp;-&gt;&nbsp;y,&nbsp;c&nbsp;-&gt;&nbsp;&lt;|d&nbsp;-&gt;&nbsp;t,&nbsp;e&nbsp;-&gt;&nbsp;u|&gt;|&gt;</mtext>
System`OutputForm: '<mtext>&lt;|a&nbsp;-&gt;&nbsp;x,&nbsp;b&nbsp;-&gt;&nbsp;y,&nbsp;c&nbsp;-&gt;&nbsp;&lt;|d&nbsp;-&gt;&nbsp;t,&nbsp;e&nbsp;-&gt;&nbsp;u|&gt;|&gt;</mtext>'
Expand Down Expand Up @@ -556,8 +556,8 @@ Integrate[F[x], {x, a, g[b]}]:
latex:
System`InputForm: \text{Integrate[F[x], \{x, a, g[b]\}]}
System`OutputForm: '\text{Integrate[F[x], \{x, a, g[b]\}]}'
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
System`StandardForm: \int_a^{g[b]} F[x] \, dx
System`TraditionalForm: \int_a^{g(b)} F(x) \, dx
mathml:
System`InputForm: <mtext>Integrate[F[x],&nbsp;{x,&nbsp;a,&nbsp;g[b]}]</mtext>
System`OutputForm: '<mtext>Integrate[F[x],&nbsp;{x,&nbsp;a,&nbsp;g[b]}]</mtext>'
Expand Down Expand Up @@ -840,8 +840,8 @@ a^(g[b]/c):
latex:
System`InputForm: \text{a${}^{\wedge}$(g[b]/c)}
System`OutputForm: '\text{a ${}^{\wedge}$ (g[b] / c)}'
System`StandardForm: a^{\frac{g\left[b\right]}{c}}
System`TraditionalForm: a^{\frac{g\left(b\right)}{c}}
System`StandardForm: a^{\frac{g[b]}{c}}
System`TraditionalForm: a^{\frac{g(b)}{c}}
mathml:
System`InputForm: <mtext>a^(g[b]/c)</mtext>
System`OutputForm: '<mtext>a&nbsp;^&nbsp;(g[b]&nbsp;/&nbsp;c)</mtext>'
Expand Down Expand Up @@ -905,7 +905,7 @@ a+PrecedenceForm[b+c,10]:
msg: "PrecedenceForm"
latex:
System`OutputForm: '\text{a + (b + c)}'
System`StandardForm: 'a+\left(b+c\right)'
System`StandardForm: 'a+(b+c)'
mathml:
System`OutputForm: '<mtext>a&nbsp;+&nbsp;(b&nbsp;+&nbsp;c)</mtext>'
System`StandardForm: '<mrow><mi>a</mi> <mo>+</mo> <mrow><mo>(</mo> <mrow><mi>b</mi> <mo>+</mo> <mi>c</mi></mrow> <mo>)</mo></mrow></mrow>'
Expand Down
4 changes: 2 additions & 2 deletions test/format/test_latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ def get_latex(wl_expression):
('"_"', r"\text{\_}"),
('"["', r"\text{[}"),
('"]"', r"\text{]}"),
("HoldForm[A[[1,2]]]", r"A\left[\left[1, 2\right]\right]"),
("HoldForm[A[[1,2]]]", r"A[[1, 2]]"),
('"wrong ]"', r"\text{wrong ]}"),
("Integrate[F[x],x]", r"\int F\left[x\right] \, dx"),
("Integrate[F[x],x]", r"\int F[x] \, dx"),
("Cap[c,b]", r"c \cap b"),
("CupCap[c,b]", r"c \stackrel{\smile}{\frown} b"),
("Congruent[c,b]", r"c \equiv b"),
Expand Down
Loading