Skip to content

Commit

Permalink
✨ Add support for \middle (#258)
Browse files Browse the repository at this point in the history
* ✨ Add support for \middle

* Fix lint error

* Raise error if \left and/or \right are missing
  • Loading branch information
roniemartinez authored Mar 19, 2022
1 parent 8a29b7c commit 2036a15
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 2 deletions.
2 changes: 2 additions & 0 deletions latex2mathml/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
DPRIME = r"\dprime"

LEFT = r"\left"
MIDDLE = r"\middle"
RIGHT = r"\right"

ABOVE = r"\above"
Expand Down Expand Up @@ -412,6 +413,7 @@ def font_factory(default: Optional[str], replacement: Dict[str, Optional[str]])
**MSTYLE_SIZES,
**{limit: ("mo", {}) for limit in LIMIT},
LEFT: ("mo", OrderedDict([("stretchy", "true"), ("fence", "true"), ("form", "prefix")])),
MIDDLE: ("mo", OrderedDict([("stretchy", "true"), ("fence", "true"), ("lspace", "0.05em"), ("rspace", "0.05em")])),
RIGHT: ("mo", OrderedDict([("stretchy", "true"), ("fence", "true"), ("form", "postfix")])),
# styles
COLOR: ("mstyle", {}),
Expand Down
4 changes: 3 additions & 1 deletion latex2mathml/converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,9 @@ def _convert_command(node: Node, parent: Element, font: Optional[Dict[str, Optio
element.text = "mod"
SubElement(parent, "mspace", width="0.333em")
elif node.text is not None:
if command == commands.HBOX:
if command == commands.MIDDLE:
element.text = "&#x{};".format(convert_symbol(node.text))
elif command == commands.HBOX:
mtext: Optional[Element] = element
for text, mode in separate_by_mode(node.text):
if mode == Mode.TEXT:
Expand Down
3 changes: 2 additions & 1 deletion latex2mathml/walker.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def _walk(tokens: Iterator[str], terminator: str = None, limit: int = 0) -> List
delimiter = next(tokens)
group.append(Node(token=token, delimiter=delimiter))
break
elif token == commands.RIGHT != terminator:
elif (token == commands.RIGHT != terminator) or (token == commands.MIDDLE and terminator != commands.RIGHT):
raise ExtraLeftOrMissingRightError
elif token == commands.LEFT:
delimiter = next(tokens)
Expand Down Expand Up @@ -132,6 +132,7 @@ def _walk(tokens: Iterator[str], terminator: str = None, limit: int = 0) -> List
commands.FBOX,
commands.HBOX,
commands.MBOX,
commands.MIDDLE,
commands.TEXT,
commands.TEXTBF,
commands.TEXTIT,
Expand Down
22 changes: 22 additions & 0 deletions tests/test_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3792,6 +3792,28 @@
),
id="pmod",
),
pytest.param(
r"\left\{\middle|\right\}",
{
"mrow": MultiDict(
[
("mo", {"@stretchy": "true", "@fence": "true", "@form": "prefix", "$": "{"}),
(
"mo",
{
"@stretchy": "true",
"@fence": "true",
"@lspace": "0.05em",
"@rspace": "0.05em",
"$": "|",
},
),
("mo", {"@stretchy": "true", "@fence": "true", "@form": "postfix", "$": "}"}),
]
)
},
id="middle",
),
],
)
def test_converter(latex: str, json: MultiDict) -> None:
Expand Down
1 change: 1 addition & 0 deletions tests/test_walker.py
Original file line number Diff line number Diff line change
Expand Up @@ -1681,6 +1681,7 @@ def test_walk(latex: str, expected: list) -> None:
[
pytest.param(r"\right)", ExtraLeftOrMissingRightError, id=r"missing-\left"),
pytest.param(r"\left(x", ExtraLeftOrMissingRightError, id=r"missing-\right"),
pytest.param(r"\middle|", ExtraLeftOrMissingRightError, id=r"missing-\left"),
pytest.param(r"{ \over 2}", NumeratorNotFoundError, id="fraction-without-numerator"),
pytest.param(r"{1 \over }", DenominatorNotFoundError, id="fraction-without-denominator"),
pytest.param(r"1_", MissingSuperScriptOrSubscriptError, id="missing-subscript"),
Expand Down

0 comments on commit 2036a15

Please sign in to comment.