#!/usr/bin/env python
##############################################################################
#
# diffpy.srfit by DANSE Diffraction group
# Simon J. L. Billinge
# (c) 2008 The Trustees of Columbia University
# in the City of New York. All rights reserved.
#
# File coded by: Chris Farrow
#
# See AUTHORS.txt for a list of people who contributed.
# See LICENSE_DANSE.txt for license information.
#
##############################################################################
"""Printer visitor for printing the equation represented by a Literal
tree.
The Printer visitor creates a one-line representation of the Literal
tree, which is valid as a string equivalent of the equation.
"""
__all__ = ["Printer"]
import re
from diffpy.srfit.equation.visitors.visitor import Visitor
[docs]
class Printer(Visitor):
"""Printer for printing a Literal tree.
Attributes
----------
eqskip : str or None
The regular expression pattern for Equation objects that should
not be expanded, but printed under their own name. Expand all
equations when None.
output : str
The output generated by the printer.
"""
# store compiled RE pattern for eqskip or None when none.
_eqpat = None
def __init__(self):
self.reset()
return
[docs]
def reset(self):
"""Reset the output string."""
self.output = ""
return
@property
def eqskip(self):
"""Pattern for equation objects to be skipped.
Expand all equations when None.
"""
rv = None
if self._eqpat is not None:
rv = self._eqpat.pattern
return rv
@eqskip.setter
def eqskip(self, value):
if value is None:
self._eqpat = None
else:
self._eqpat = re.compile(value)
return
[docs]
def on_argument(self, arg):
"""Write an Argument node.
The name is written, or the value if the Argument has no name.
No assumption is made about the argument type.
Parameters
----------
arg : Argument
The Argument to write.
Returns
-------
str
The output so far.
"""
if arg.name is None:
self.output += str(arg.value)
else:
self.output += str(arg.name)
return self.output
[docs]
def on_operator(self, op):
"""Write an Operator node.
Binary operators whose symbol differs from their name are
written in infix form, such as "(a + b)". Others are written as
a function call, such as "sin(a)".
Parameters
----------
op : Operator
The Operator to write.
Returns
-------
str
The output so far.
"""
# We have to deal with infix operators
if op.name != op.symbol and op.nin == 2:
self._on_infix(op)
return self.output
self.output += str(op.name) + "("
for idx, literal in enumerate(op.args):
if idx != 0:
self.output += ", "
literal.identify(self)
self.output += ")"
return self.output
[docs]
def on_equation(self, eq):
"""Write an Equation node.
The Equation is written by name if it matches ``eqskip``, and
expanded otherwise.
Parameters
----------
eq : Equation
The Equation to write.
Returns
-------
str
The output so far.
"""
skipthis = (
self._eqpat is not None and eq.name and self._eqpat.match(eq.name)
)
if skipthis:
self.on_argument(eq)
else:
eq.root.identify(self)
return self.output
def _on_infix(self, op):
"""Process infix operators."""
self.output += "("
op.args[0].identify(self)
self.output += " %s " % op.symbol
op.args[1].identify(self)
self.output += ")"
return
# End of file