From b2239e0e56fe48f9dc99e13ce672a03083dec377 Mon Sep 17 00:00:00 2001 From: Bertrand Benjamin Date: Sat, 10 Mar 2018 16:08:28 +0300 Subject: [PATCH] str2tex done and integrate into MO --- mapytex/calculus/core/MO/mo.py | 15 +- mapytex/calculus/core/renders/__init__.py | 1 + mapytex/calculus/core/renders/tree2tex.py | 226 ++++++++++++++++++++++ 3 files changed, 241 insertions(+), 1 deletion(-) create mode 100644 mapytex/calculus/core/renders/tree2tex.py diff --git a/mapytex/calculus/core/MO/mo.py b/mapytex/calculus/core/MO/mo.py index 737d79d..5ab1ad0 100644 --- a/mapytex/calculus/core/MO/mo.py +++ b/mapytex/calculus/core/MO/mo.py @@ -7,7 +7,7 @@ # Distributed under terms of the MIT license. from ..coroutine import coroutine, STOOOP -from ..renders import tree2txt +from ..renders import tree2txt, tree2tex from decimal import Decimal @@ -91,6 +91,13 @@ class MO(object): except AttributeError: return str(self.value) + @property + def __tex__(self): + try: + return tree2tex(self.value) + except AttributeError: + return str(self.value) + def __add__(self, other): """ Overload + for MOs @@ -195,6 +202,12 @@ class MOnumber(MO): return f"- {abs(self.value)}" + @property + def __tex__(self): + if self.value > 0: + return str(self.value) + + return f"- {abs(self.value)}" class MOstr(MO): diff --git a/mapytex/calculus/core/renders/__init__.py b/mapytex/calculus/core/renders/__init__.py index cde6421..168bd6c 100644 --- a/mapytex/calculus/core/renders/__init__.py +++ b/mapytex/calculus/core/renders/__init__.py @@ -13,6 +13,7 @@ Tree renders __all__ = ["tree2txt"] from .tree2txt import tree2txt +from .tree2tex import tree2tex # ----------------------------- # Reglages pour 'vim' diff --git a/mapytex/calculus/core/renders/tree2tex.py b/mapytex/calculus/core/renders/tree2tex.py new file mode 100644 index 0000000..7d12520 --- /dev/null +++ b/mapytex/calculus/core/renders/tree2tex.py @@ -0,0 +1,226 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +# vim:fenc=utf-8 +# +# Copyright © 2017 lafrite +# +# Distributed under terms of the MIT license. + +from mapytex.calculus.core.operator import OPERATORS + +__all__ = ['tree2tex'] + +def plus2tex(left, right): + r""" + rendering + + >>> from ..MO import mo + >>> plus2tex(mo.MOnumber(2), mo.MOnumber(3)) + '2 + 3' + >>> from ..tree import Tree + >>> t = Tree.from_str("1+2") + >>> plus2tex(t, mo.MOnumber(3)) + '1 + 2 + 3' + >>> plus2tex(t, mo.MOnumber(-3)) + '1 + 2 - 3' + >>> plus2tex(mo.MOnumber(-3), t) + '- 3 + 1 + 2' + >>> t = Tree.from_str("-2*3") + >>> plus2tex(mo.MOnumber(3), t) + '3 - 2 \\times 3' + """ + display_plus = True + try: + left.node + except AttributeError: + left_ = left.__tex__ + else: + left_ = tree2tex(left) + + try: + right.node + except AttributeError: + right_ = right.__tex__ + else: + right_ = tree2tex(right) + finally: + if right_.startswith("-"): + display_plus = False + + if display_plus: + return f"{left_} + {right_}" + + return f"{left_} {right_}" + +def minus2tex(left, right): + r""" - rendering + + >>> from ..MO import mo + >>> minus2tex(None, mo.MO(3)) + '- 3' + >>> from ..tree import Tree + >>> t = Tree.from_str("1+2") + >>> minus2tex(None, t) + '- (1 + 2)' + """ + try: + right_need_parenthesis = False + if OPERATORS[right.node]["precedence"] < OPERATORS['-']["precedence"]: + right_need_parenthesis = True + except AttributeError: + right_ = right.__tex__ + else: + if right_need_parenthesis: + right_ = f"({tree2tex(right)})" + else: + right_ = tree2tex(right) + + return f"- {right_}" + +def mul2tex(left, right): + r""" * rendering + + >>> from ..MO import mo + >>> mul2tex(mo.MO(2), mo.MO(3)) + '2 \\times 3' + >>> from ..tree import Tree + >>> t = Tree.from_str("1*2") + >>> mul2tex(t, mo.MO(3)) + '1 \\times 2 \\times 3' + >>> t = Tree.from_str("1+2") + >>> mul2tex(t, mo.MO(3)) + '(1 + 2) \\times 3' + >>> mul2tex(mo.MO(3), t) + '3(1 + 2)' + >>> a = mo.MOstr('x') + >>> mul2tex(mo.MO(3), a) + '3x' + """ + display_time = True + try: + left_need_parenthesis = False + if OPERATORS[left.node]["precedence"] < OPERATORS['*']["precedence"]: + left_need_parenthesis = True + except AttributeError: + left_ = left.__tex__ + else: + if left_need_parenthesis: + left_ = f"({tree2tex(left)})" + else: + left_ = tree2tex(left) + + try: + right_need_parenthesis = False + if OPERATORS[right.node]["precedence"] < OPERATORS['*']["precedence"]: + right_need_parenthesis = True + except AttributeError: + right_ = right.__tex__ + else: + if right_need_parenthesis: + display_time = False + right_ = f"({tree2tex(right)})" + else: + right_ = tree2tex(right) + finally: + if right_[0].isalpha(): + display_time = False + + if display_time: + return f"{left_} \\times {right_}" + else: + return f"{left_}{right_}" + +def div2tex(left, right): + r""" / rendering + + >>> from ..MO import mo + >>> div2tex(mo.MO(2), mo.MO(3)) + '\\frac{2}{3}' + >>> from ..tree import Tree + >>> t = Tree.from_str("1/2") + >>> div2tex(t, mo.MO(3)) + '\\frac{\\frac{1}{2}}{3}' + >>> t = Tree.from_str("1+2") + >>> div2tex(t, mo.MO(3)) + '\\frac{1 + 2}{3}' + >>> t = Tree.from_str("1*2") + >>> div2tex(mo.MO(3), t) + '\\frac{3}{1 \\times 2}' + """ + try: + left_ = tree2tex(left) + except AttributeError: + left_ = left.__tex__ + try: + right_ = tree2tex(right) + except AttributeError: + right_ = right.__tex__ + + return "\\frac{" + left_ + "}{" + right_ + "}" + +def pow2tex(left, right): + r""" ^ rendering + + >>> from ..MO import mo + >>> pow2tex(mo.MO(2), mo.MO(3)) + '2 ^ 3' + >>> from ..tree import Tree + >>> t = Tree.from_str("1^2") + >>> pow2tex(t, mo.MO(3)) + '1 ^ 2 ^ 3' + >>> t = Tree.from_str("1+2") + >>> pow2tex(t, mo.MO(3)) + '(1 + 2) ^ 3' + >>> t = Tree.from_str("1*2") + >>> pow2tex(mo.MO(3), t) + '3 ^ (1 \\times 2)' + """ + try: + left_need_parenthesis = False + if OPERATORS[left.node]["precedence"] < OPERATORS['^']["precedence"]: + left_need_parenthesis = True + except AttributeError: + left_ = left.__tex__ + else: + if left_need_parenthesis: + left_ = f"({tree2tex(left)})" + else: + left_ = tree2tex(left) + try: + right_need_parenthesis = False + if OPERATORS[right.node]["precedence"] < OPERATORS['^']["precedence"]: + right_need_parenthesis = True + except AttributeError: + right_ = right.__tex__ + else: + if right_need_parenthesis: + right_ = f"({tree2tex(right)})" + else: + right_ = tree2tex(right) + + return f"{left_} ^ {right_}" + +OPERATOR2tex = { + "+": plus2tex, + "-": minus2tex, + "*": mul2tex, + "/": div2tex, + "^": pow2tex, +} + +def tree2tex(tree): + r""" Convert a tree into its tex version + + It calls __tex__ to render MOs. + + >>> from ..tree import Tree + >>> t = Tree.from_str("2+3*4") + >>> tree2tex(t) + '2 + 3 \\times 4' + """ + return OPERATOR2tex[tree.node](tree.left_value, tree.right_value) + + +# ----------------------------- +# Reglages pour 'vim' +# vim:set autoindent expandtab tabstop=4 shiftwidth=4: +# cursor: 16 del