Exemple #1
0
 def __init__(self, reference_converter=None, types_printer=None):
     # type: (IReferenceConverter,TypesPrinter) -> None
     # todo by kp: this should expect a ITypesPrinter as the second arg
     self.reference_converter = LatexReferenceConverter()
     if types_printer is not None:
         self.types_printer = types_printer
     else:
         self.types_printer = TypesPrinter()
 def __init__(self,
              reference_converter: IReferenceConverter = None,
              types_printer: TypesPrinter = None):
     self.reference_converter = LatexReferenceConverter()
     if types_printer is not None:
         self.types_printer = types_printer
     else:
         self.types_printer = LatexTypesPrinter()
    def setup_model_generation_helpers(self, neuron: ASTNeuron):
        """
        Returns a namespace for Jinja2 neuron model documentation template.

        :param neuron: a single neuron instance
        :type neuron: ASTNeuron
        :return: a map from name to functionality.
        :rtype: dict
        """
        converter = LatexReferenceConverter()
        latex_expression_printer = LatexExpressionPrinter(converter)

        namespace = dict()

        namespace['now'] = datetime.datetime.utcnow()
        namespace['neuron'] = neuron
        namespace['neuronName'] = str(neuron.get_name())
        namespace['printer'] = NestPrinter(latex_expression_printer)
        namespace['assignments'] = NestAssignmentsHelper()
        namespace['names'] = NestNamesConverter()
        namespace['declarations'] = NestDeclarationsHelper()
        namespace['utils'] = ASTUtils()
        namespace['odeTransformer'] = OdeTransformer()

        import textwrap
        pre_comments_bak = neuron.pre_comments
        neuron.pre_comments = []
        namespace['neuron_source_code'] = textwrap.indent(
            neuron.__str__(), "   ")
        neuron.pre_comments = pre_comments_bak

        return namespace
    def setup_index_generation_helpers(self, neurons: List[ASTNeuron]):
        """
        Returns a namespace for Jinja2 neuron model index page template.

        :param neurons: a list of neuron instances
        :type neurons: List[ASTNeuron]
        :return: a map from name to functionality.
        :rtype: dict
        """
        converter = LatexReferenceConverter()
        latex_expression_printer = LatexExpressionPrinter(converter)

        namespace = dict()

        namespace['now'] = datetime.datetime.utcnow()
        namespace['neurons'] = neurons
        namespace['neuronNames'] = [
            str(neuron.get_name()) for neuron in neurons
        ]
        namespace['printer'] = NestPrinter(latex_expression_printer)
        namespace['assignments'] = NestAssignmentsHelper()
        namespace['names'] = NestNamesConverter()
        namespace['declarations'] = NestDeclarationsHelper()
        namespace['utils'] = ASTUtils()
        namespace['odeTransformer'] = OdeTransformer()

        return namespace
Exemple #5
0
class LatexExpressionPrinter():
    """
    Pretty printer for LaTeX. Assumes to be printing in a LaTeX environment where math mode is already on.
    """
    def __init__(self, reference_converter=None, types_printer=None):
        # type: (IReferenceConverter,TypesPrinter) -> None
        # todo by kp: this should expect a ITypesPrinter as the second arg
        self.reference_converter = LatexReferenceConverter()
        if types_printer is not None:
            self.types_printer = types_printer
        else:
            self.types_printer = TypesPrinter()

    def print_expression(self, node):
        # type: (ASTExpressionNode) -> str
        return self.__do_print(node)
        if node.get_implicit_conversion_factor() is not None:
            return str(node.get_implicit_conversion_factor()
                       ) + ' * (' + self.__do_print(node) + ')'
        else:
            return self.__do_print(node)

    def __do_print(self, node):
        # type: (ASTExpressionNode) -> str
        if isinstance(node, ASTVariable):
            return self.reference_converter.convert_name_reference(node)
        elif isinstance(node, ASTSimpleExpression):
            if node.has_unit():
                # todo by kp: this should not be done in the typesPrinter, obsolete
                s = ""
                if node.get_numeric_literal() != 1:
                    s += "{0:E}".format(node.get_numeric_literal())
                    s += r"\cdot"
                s += self.reference_converter.convert_name_reference(
                    node.get_variable())
                return s
            elif node.is_numeric_literal():
                return str(node.get_numeric_literal())
            elif node.is_inf_literal:
                return r"\infty"
            elif node.is_string():
                return self.types_printer.pretty_print(node.get_string())
            elif node.is_boolean_true:
                return self.types_printer.pretty_print(True)
            elif node.is_boolean_false:
                return self.types_printer.pretty_print(False)
            elif node.is_variable():
                return self.reference_converter.convert_name_reference(
                    node.get_variable())
            elif node.is_function_call():
                return self.print_function_call(node.get_function_call())
        elif isinstance(node, ASTExpression):
            # a unary operator
            if node.is_unary_operator():
                op = self.reference_converter.convert_unary_op(
                    node.get_unary_operator())
                rhs = self.print_expression(node.get_expression())
                return op % rhs
            # encapsulated in brackets
            elif node.is_encapsulated:
                return self.reference_converter.convert_encapsulated(
                ) % self.print_expression(node.get_expression())
            # logical not
            elif node.is_logical_not:
                op = self.reference_converter.convert_logical_not()
                rhs = self.print_expression(node.get_expression())
                return op % rhs
            # compound rhs with lhs + rhs
            elif node.is_compound_expression():
                lhs = self.print_expression(node.get_lhs())
                rhs = self.print_expression(node.get_rhs())
                wide = False
                if node.get_binary_operator().is_div_op \
                        and len(lhs) > 3 * len(rhs):
                    # if lhs (numerator) is much wider than rhs (denominator), rewrite as a factor
                    wide = True
                op = self.reference_converter.convert_binary_op(
                    node.get_binary_operator(), wide=wide)
                return op % ({"lhs": lhs, "rhs": rhs})
            elif node.is_ternary_operator():
                condition = self.print_expression(node.get_condition())
                if_true = self.print_expression(node.get_if_true())
                if_not = self.print_expression(node.if_not)
                return self.reference_converter.convert_ternary_operator() % (
                    condition, if_true, if_not)
        else:
            raise RuntimeError('Unsupported rhs in rhs pretty printer!')

    def print_function_call(self, function_call):
        # type: (ASTFunctionCall) -> str
        function_name = self.reference_converter.convert_function_call(
            function_call)
        if ASTUtils.needs_arguments(function_call):
            return function_name % self.print_function_call_argument_list(
                function_call)
        else:
            return function_name

    def print_function_call_argument_list(self, function_call):
        # type: (ASTFunctionCall) -> tuple of str
        ret = []
        for arg in function_call.get_args():
            ret.append(self.print_expression(arg))
        return tuple(ret)