Source code for pharmpy.parse_utils.prettyprint

"""Pretty printing of :class:`generic.AttrTree` via :class:`treeprint.Node`."""
from functools import partial

import lark

from . import treeprint

MAXLEN = 60


def _preview(content):
    """Represents str and cut into shorts if too long"""
    cut = len(content) - MAXLEN
    if cut > 0:
        preview = '"' + repr(content[0:MAXLEN])[1:-1] + '"'
        preview = '%s+%d' % (preview, cut)
    else:
        preview = '"' + repr(content)[1:-1] + '"'
    return preview


def _formatter(content, ast_node):
    """Formats AST node (Tree and Token) for treeprint"""
    if not content:
        return '%s' % (ast_node.rule,)
    elif content != 'full':
        return '%s %s' % (ast_node.rule, _preview(str(ast_node)))
    lines = [ast_node.rule] + str(ast_node).splitlines(True)
    lines[1:] = [_preview(line) for line in lines[1:]]
    return '\n'.join(lines)


def _format_tree(content, ast_tree):
    return _formatter(content, ast_tree)


def _format_token(content, ast_token):
    return _formatter(content, ast_token)


[docs]def transform(ast_tree, content=True): """ Traverses tree and generates :class:`treeprint.Node`, which can format a multiline (command) tree-styled string. Args: content: If True, include text preview (or all if 'full') on each node. Returns: Multiline string, ready for the printing press. """ if not any(isinstance(ast_tree, x) for x in [lark.Tree, lark.lexer.Token]): raise TypeError( "can't transform %s object (is not a Lark Tree or Token')" % repr(ast_tree.__class__.__name__) ) tree = treeprint.Node(ast_tree) try: nodes = ast_tree.children except AttributeError: tree.set_formatter(partial(_format_token, content)) else: if isinstance(nodes, str): raise TypeError( "'children' of tree appears to be 'str' (expects list/iterable): %s" % repr(ast_tree) ) tree.set_formatter(partial(_format_tree, content)) for ast_node in list(nodes): node = transform(ast_node, content) tree.add(node) return tree