Mapytex/mapytex/calculus/renderable.py

117 lines
3.2 KiB
Python

#!/usr/bin/env python
# encoding: utf-8
from .render import tex, txt
__all__ = ['Renderable']
class Renderable(object):
"""
A Renderable object is an object which can work with Render class. It means that it has to have attribute postfix_tokens.
"""
STR_RENDER = tex
DEFAULT_RENDER = tex
@classmethod
def set_render(cls, render):
cls.STR_RENDER = render
@classmethod
def get_render(cls):
return cls.STR_RENDER
@classmethod
def set_default_render(cls):
cls.set_render(cls.DEFAULT_RENDER)
@classmethod
def tmp_render(cls, render=tex):
""" Create a container in which Expression render is temporary modify
The default temporary render is Expression in order to perform calculus inside numbers
>>> from .expression import Expression
>>> from .explicable import Explicable
>>> exp = Expression("2*3/5")
>>> print(exp)
2 \\times \\frac{ 3 }{ 5 }
>>> for i in exp.simplify().explain():
... print(i)
2 \\times \\frac{ 3 }{ 5 }
\\frac{ 3 }{ 5 } \\times 2
\\frac{ 3 \\times 2 }{ 5 }
\\frac{ 6 }{ 5 }
>>> with Explicable.tmp_render(txt):
... for i in exp.simplify().explain():
... print(i)
2 * 3 / 5
3 / 5 * 2
( 3 * 2 ) / 5
6 / 5
>>> for i in exp.simplify().explain():
... print(i)
2 \\times \\frac{ 3 }{ 5 }
\\frac{ 3 }{ 5 } \\times 2
\\frac{ 3 \\times 2 }{ 5 }
\\frac{ 6 }{ 5 }
# TODO: essayer de ne pas afficher ce changement de position. |lun. avril 6 17:29:56 CEST 2015
"""
class TmpRenderEnv(object):
def __enter__(self):
self.old_render = Renderable.get_render()
Renderable.set_render(render)
def __exit__(self, type, value, traceback):
Renderable.set_render(self.old_render)
return TmpRenderEnv()
def __init__(self, pstf_tokens):
"""Initiate the renderable objet
:param pstf_tokens: the postfix list of tokens
"""
self.postfix_tokens = pstf_tokens
def __str__(self):
"""
Overload str
If you want to changer render use Expression.set_render(...) or use tmp_render context manager.
"""
return self.STR_RENDER(self.postfix_tokens)
def __repr__(self):
return "< {cls} {pstf_tokens}>".format(
cls = str(self.__class__).split('.')[-1][:-2],
pstf_tokens = str(self.postfix_tokens)
)
def __eq__(self, other):
""" Two Renderable objects are the same if they have same postfix_tokens """
try:
return self.postfix_tokens == other.postfix_tokens
except AttributeError:
return False
def __txt__(self):
try:
return txt(self.postfix_tokens)
except AttributeError:
return self
def __tex__(self):
try:
return tex(self.postfix_tokens)
except AttributeError:
return self
# -----------------------------
# Reglages pour 'vim'
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
# cursor: 16 del