mercurial/dagparser.py
author Martin Geisler <mg@aragost.com>
Mon, 30 Aug 2010 17:17:20 +0200
branchstable
changeset 12134 26d86a6cf2af
parent 11885 08cd25ef8a38
child 12387 4f8067c94729
permissions -rw-r--r--
dagparser: translate and lowercase error messages
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11335
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
     1
# dagparser.py - parser and generator for concise description of DAGs
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
     2
#
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
     3
# Copyright 2010 Peter Arrenbrecht <peter@arrenbrecht.ch>
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
     4
#
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
     7
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
     8
import re, string
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
     9
import util
11885
08cd25ef8a38 dagparser: transplant part of 4e804302d30c
Martin Geisler <mg@lazybytes.net>
parents: 11344
diff changeset
    10
from i18n import _
11335
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    11
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    12
def parsedag(desc):
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    13
    '''parses a DAG from a concise textual description; generates events
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    14
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    15
    "+n" is a linear run of n nodes based on the current default parent
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    16
    "." is a single node based on the current default parent
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    17
    "$" resets the default parent to -1 (implied at the start);
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    18
        otherwise the default parent is always the last node created
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    19
    "<p" sets the default parent to the backref p
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    20
    "*p" is a fork at parent p, where p is a backref
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    21
    "*p1/p2/.../pn" is a merge of parents p1..pn, where the pi are backrefs
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    22
    "/p2/.../pn" is a merge of the preceding node and p2..pn
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    23
    ":name" defines a label for the preceding node; labels can be redefined
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    24
    "@text" emits an annotation event for text
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    25
    "!command" emits an action event for the current node
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    26
    "!!my command\n" is like "!", but to the end of the line
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    27
    "#...\n" is a comment up to the end of the line
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    28
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    29
    Whitespace between the above elements is ignored.
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    30
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    31
    A backref is either
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    32
     * a number n, which references the node curr-n, where curr is the current
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    33
       node, or
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    34
     * the name of a label you placed earlier using ":name", or
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    35
     * empty to denote the default parent.
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    36
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    37
    All string valued-elements are either strictly alphanumeric, or must
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    38
    be enclosed in double quotes ("..."), with "\" as escape character.
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    39
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    40
    Generates sequence of
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    41
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    42
      ('n', (id, [parentids])) for node creation
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    43
      ('l', (id, labelname)) for labels on nodes
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    44
      ('a', text) for annotations
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    45
      ('c', command) for actions (!)
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    46
      ('C', command) for line actions (!!)
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    47
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    48
    Examples
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    49
    --------
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    50
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    51
    Example of a complex graph (output not shown for brevity):
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    52
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    53
        >>> len(list(parsedag("""
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    54
        ...
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    55
        ... +3         # 3 nodes in linear run
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    56
        ... :forkhere  # a label for the last of the 3 nodes from above
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    57
        ... +5         # 5 more nodes on one branch
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    58
        ... :mergethis # label again
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    59
        ... <forkhere  # set default parent to labelled fork node
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    60
        ... +10        # 10 more nodes on a parallel branch
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    61
        ... @stable    # following nodes will be annotated as "stable"
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    62
        ... +5         # 5 nodes in stable
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    63
        ... !addfile   # custom command; could trigger new file in next node
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    64
        ... +2         # two more nodes
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    65
        ... /mergethis # merge last node with labelled node
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    66
        ... +4         # 4 more nodes descending from merge node
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    67
        ...
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    68
        ... """)))
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    69
        34
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    70
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    71
    Empty list:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    72
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    73
        >>> list(parsedag(""))
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    74
        []
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    75
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    76
    A simple linear run:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    77
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    78
        >>> list(parsedag("+3"))
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    79
        [('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [1]))]
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    80
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    81
    Some non-standard ways to define such runs:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    82
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    83
        >>> list(parsedag("+1+2"))
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    84
        [('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [1]))]
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    85
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    86
        >>> list(parsedag("+1*1*"))
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    87
        [('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [1]))]
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    88
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    89
        >>> list(parsedag("*"))
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    90
        [('n', (0, [-1]))]
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    91
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    92
        >>> list(parsedag("..."))
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    93
        [('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [1]))]
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    94
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    95
    A fork and a join, using numeric back references:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    96
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    97
        >>> list(parsedag("+2*2*/2"))
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    98
        [('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [0])), ('n', (3, [2, 1]))]
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    99
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   100
        >>> list(parsedag("+2<2+1/2"))
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   101
        [('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [0])), ('n', (3, [2, 1]))]
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   102
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   103
    Placing a label:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   104
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   105
        >>> list(parsedag("+1 :mylabel +1"))
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   106
        [('n', (0, [-1])), ('l', (0, 'mylabel')), ('n', (1, [0]))]
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   107
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   108
    An empty label (silly, really):
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   109
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   110
        >>> list(parsedag("+1:+1"))
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   111
        [('n', (0, [-1])), ('l', (0, '')), ('n', (1, [0]))]
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   112
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   113
    Fork and join, but with labels instead of numeric back references:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   114
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   115
        >>> list(parsedag("+1:f +1:p2 *f */p2"))
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   116
        [('n', (0, [-1])), ('l', (0, 'f')), ('n', (1, [0])), ('l', (1, 'p2')),
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   117
         ('n', (2, [0])), ('n', (3, [2, 1]))]
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   118
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   119
        >>> list(parsedag("+1:f +1:p2 <f +1 /p2"))
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   120
        [('n', (0, [-1])), ('l', (0, 'f')), ('n', (1, [0])), ('l', (1, 'p2')),
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   121
         ('n', (2, [0])), ('n', (3, [2, 1]))]
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   122
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   123
    Restarting from the root:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   124
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   125
        >>> list(parsedag("+1 $ +1"))
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   126
        [('n', (0, [-1])), ('n', (1, [-1]))]
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   127
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   128
    Annotations, which are meant to introduce sticky state for subsequent nodes:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   129
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   130
        >>> list(parsedag("+1 @ann +1"))
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   131
        [('n', (0, [-1])), ('a', 'ann'), ('n', (1, [0]))]
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   132
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   133
        >>> list(parsedag('+1 @"my annotation" +1'))
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   134
        [('n', (0, [-1])), ('a', 'my annotation'), ('n', (1, [0]))]
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   135
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   136
    Commands, which are meant to operate on the most recently created node:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   137
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   138
        >>> list(parsedag("+1 !cmd +1"))
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   139
        [('n', (0, [-1])), ('c', 'cmd'), ('n', (1, [0]))]
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   140
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   141
        >>> list(parsedag('+1 !"my command" +1'))
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   142
        [('n', (0, [-1])), ('c', 'my command'), ('n', (1, [0]))]
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   143
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   144
        >>> list(parsedag('+1 !!my command line\\n +1'))
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   145
        [('n', (0, [-1])), ('C', 'my command line'), ('n', (1, [0]))]
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   146
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   147
    Comments, which extend to the end of the line:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   148
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   149
        >>> list(parsedag('+1 # comment\\n+1'))
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   150
        [('n', (0, [-1])), ('n', (1, [0]))]
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   151
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   152
    Error:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   153
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   154
        >>> try: list(parsedag('+1 bad'))
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   155
        ... except Exception, e: print e
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   156
        invalid character in dag description: bad...
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   157
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   158
    '''
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   159
    if not desc:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   160
        return
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   161
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   162
    wordchars = string.ascii_letters + string.digits
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   163
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   164
    labels = {}
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   165
    p1 = -1
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   166
    r = 0
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   167
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   168
    def resolve(ref):
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   169
        if not ref:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   170
            return p1
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   171
        elif ref[0] in string.digits:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   172
            return r - int(ref)
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   173
        else:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   174
            return labels[ref]
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   175
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   176
    chiter = (c for c in desc)
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   177
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   178
    def nextch():
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   179
        try:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   180
            return chiter.next()
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   181
        except StopIteration:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   182
            return '\0'
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   183
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   184
    def nextrun(c, allow):
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   185
        s = ''
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   186
        while c in allow:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   187
            s += c
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   188
            c = nextch()
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   189
        return c, s
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   190
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   191
    def nextdelimited(c, limit, escape):
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   192
        s = ''
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   193
        while c != limit:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   194
            if c == escape:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   195
                c = nextch()
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   196
            s += c
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   197
            c = nextch()
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   198
        return nextch(), s
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   199
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   200
    def nextstring(c):
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   201
        if c == '"':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   202
            return nextdelimited(nextch(), '"', '\\')
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   203
        else:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   204
            return nextrun(c, wordchars)
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   205
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   206
    c = nextch()
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   207
    while c != '\0':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   208
        while c in string.whitespace:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   209
            c = nextch()
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   210
        if c == '.':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   211
            yield 'n', (r, [p1])
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   212
            p1 = r
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   213
            r += 1
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   214
            c = nextch()
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   215
        elif c == '+':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   216
            c, digs = nextrun(nextch(), string.digits)
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   217
            n = int(digs)
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   218
            for i in xrange(0, n):
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   219
                yield 'n', (r, [p1])
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   220
                p1 = r
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   221
                r += 1
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   222
        elif c == '*' or c == '/':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   223
            if c == '*':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   224
                c = nextch()
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   225
            c, pref = nextstring(c)
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   226
            prefs = [pref]
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   227
            while c == '/':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   228
                c, pref = nextstring(nextch())
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   229
                prefs.append(pref)
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   230
            ps = [resolve(ref) for ref in prefs]
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   231
            yield 'n', (r, ps)
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   232
            p1 = r
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   233
            r += 1
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   234
        elif c == '<':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   235
            c, ref = nextstring(nextch())
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   236
            p1 = resolve(ref)
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   237
        elif c == ':':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   238
            c, name = nextstring(nextch())
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   239
            labels[name] = p1
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   240
            yield 'l', (p1, name)
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   241
        elif c == '@':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   242
            c, text = nextstring(nextch())
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   243
            yield 'a', text
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   244
        elif c == '!':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   245
            c = nextch()
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   246
            if c == '!':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   247
                cmd = ''
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   248
                c = nextch()
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   249
                while c not in '\n\r\0':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   250
                    cmd += c
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   251
                    c = nextch()
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   252
                yield 'C', cmd
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   253
            else:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   254
                c, cmd = nextstring(c)
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   255
                yield 'c', cmd
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   256
        elif c == '#':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   257
            while c not in '\n\r\0':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   258
                c = nextch()
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   259
        elif c == '$':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   260
            p1 = -1
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   261
            c = nextch()
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   262
        elif c == '\0':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   263
            return # in case it was preceded by whitespace
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   264
        else:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   265
            s = ''
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   266
            i = 0
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   267
            while c != '\0' and i < 10:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   268
                s += c
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   269
                i += 1
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   270
                c = nextch()
12134
26d86a6cf2af dagparser: translate and lowercase error messages
Martin Geisler <mg@aragost.com>
parents: 11885
diff changeset
   271
            raise util.Abort(_("invalid character in dag description: %s...") % s)
11335
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   272
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   273
def dagtextlines(events,
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   274
                 addspaces=True,
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   275
                 wraplabels=False,
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   276
                 wrapannotations=False,
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   277
                 wrapcommands=False,
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   278
                 wrapnonlinear=False,
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   279
                 usedots=False,
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   280
                 maxlinewidth=70):
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   281
    '''generates single lines for dagtext()'''
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   282
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   283
    def wrapstring(text):
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   284
        if re.match("^[0-9a-z]*$", text):
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   285
            return text
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   286
        return '"' + text.replace('\\', '\\\\').replace('"', '\"') + '"'
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   287
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   288
    def gen():
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   289
        labels = {}
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   290
        run = 0
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   291
        wantr = 0
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   292
        needroot = False
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   293
        for kind, data in events:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   294
            if kind == 'n':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   295
                r, ps = data
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   296
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   297
                # sanity check
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   298
                if r != wantr:
12134
26d86a6cf2af dagparser: translate and lowercase error messages
Martin Geisler <mg@aragost.com>
parents: 11885
diff changeset
   299
                    raise util.Abort(_("expected id %i, got %i") % (wantr, r))
11335
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   300
                if not ps:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   301
                    ps = [-1]
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   302
                else:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   303
                    for p in ps:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   304
                        if p >= r:
12134
26d86a6cf2af dagparser: translate and lowercase error messages
Martin Geisler <mg@aragost.com>
parents: 11885
diff changeset
   305
                            raise util.Abort(_("parent id %i is larger than "
26d86a6cf2af dagparser: translate and lowercase error messages
Martin Geisler <mg@aragost.com>
parents: 11885
diff changeset
   306
                                               "current id %i") % (p, r))
11335
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   307
                wantr += 1
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   308
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   309
                # new root?
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   310
                p1 = r - 1
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   311
                if len(ps) == 1 and ps[0] == -1:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   312
                    if needroot:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   313
                        if run:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   314
                            yield '+' + str(run)
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   315
                            run = 0
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   316
                        if wrapnonlinear:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   317
                            yield '\n'
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   318
                        yield '$'
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   319
                        p1 = -1
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   320
                    else:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   321
                        needroot = True
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   322
                if len(ps) == 1 and ps[0] == p1:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   323
                    if usedots:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   324
                        yield "."
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   325
                    else:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   326
                        run += 1
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   327
                else:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   328
                    if run:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   329
                        yield '+' + str(run)
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   330
                        run = 0
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   331
                    if wrapnonlinear:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   332
                        yield '\n'
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   333
                    prefs = []
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   334
                    for p in ps:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   335
                        if p == p1:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   336
                            prefs.append('')
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   337
                        elif p in labels:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   338
                            prefs.append(labels[p])
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   339
                        else:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   340
                            prefs.append(str(r - p))
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   341
                    yield '*' + '/'.join(prefs)
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   342
            else:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   343
                if run:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   344
                    yield '+' + str(run)
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   345
                    run = 0
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   346
                if kind == 'l':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   347
                    rid, name = data
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   348
                    labels[rid] = name
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   349
                    yield ':' + name
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   350
                    if wraplabels:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   351
                        yield '\n'
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   352
                elif kind == 'c':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   353
                    yield '!' + wrapstring(data)
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   354
                    if wrapcommands:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   355
                        yield '\n'
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   356
                elif kind == 'C':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   357
                    yield '!!' + data
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   358
                    yield '\n'
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   359
                elif kind == 'a':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   360
                    if wrapannotations:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   361
                        yield '\n'
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   362
                    yield '@' + wrapstring(data)
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   363
                elif kind == '#':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   364
                    yield '#' + data
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   365
                    yield '\n'
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   366
                else:
11344
32a9744acf1e dagparser: replace format with str
Martin Geisler <mg@aragost.com>
parents: 11335
diff changeset
   367
                    raise util.Abort(_("invalid event type in dag: %s")
32a9744acf1e dagparser: replace format with str
Martin Geisler <mg@aragost.com>
parents: 11335
diff changeset
   368
                                     % str((type, data)))
11335
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   369
        if run:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   370
            yield '+' + str(run)
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   371
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   372
    line = ''
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   373
    for part in gen():
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   374
        if part == '\n':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   375
            if line:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   376
                yield line
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   377
                line = ''
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   378
        else:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   379
            if len(line) + len(part) >= maxlinewidth:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   380
                yield line
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   381
                line = ''
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   382
            elif addspaces and line and part != '.':
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   383
                line += ' '
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   384
            line += part
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   385
    if line:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   386
        yield line
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   387
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   388
def dagtext(dag,
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   389
            addspaces=True,
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   390
            wraplabels=False,
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   391
            wrapannotations=False,
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   392
            wrapcommands=False,
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   393
            wrapnonlinear=False,
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   394
            usedots=False,
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   395
            maxlinewidth=70):
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   396
    '''generates lines of a textual representation for a dag event stream
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   397
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   398
    events should generate what parsedag() does, so:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   399
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   400
      ('n', (id, [parentids])) for node creation
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   401
      ('l', (id, labelname)) for labels on nodes
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   402
      ('a', text) for annotations
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   403
      ('c', text) for commands
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   404
      ('C', text) for line commands ('!!')
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   405
      ('#', text) for comment lines
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   406
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   407
    Parent nodes must come before child nodes.
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   408
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   409
    Examples
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   410
    --------
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   411
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   412
    Linear run:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   413
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   414
        >>> dagtext([('n', (0, [-1])), ('n', (1, [0]))])
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   415
        '+2'
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   416
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   417
    Two roots:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   418
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   419
        >>> dagtext([('n', (0, [-1])), ('n', (1, [-1]))])
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   420
        '+1 $ +1'
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   421
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   422
    Fork and join:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   423
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   424
        >>> dagtext([('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [0])),
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   425
        ...          ('n', (3, [2, 1]))])
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   426
        '+2 *2 */2'
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   427
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   428
    Fork and join with labels:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   429
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   430
        >>> dagtext([('n', (0, [-1])), ('l', (0, 'f')), ('n', (1, [0])),
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   431
        ...          ('l', (1, 'p2')), ('n', (2, [0])), ('n', (3, [2, 1]))])
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   432
        '+1 :f +1 :p2 *f */p2'
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   433
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   434
    Annotations:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   435
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   436
        >>> dagtext([('n', (0, [-1])), ('a', 'ann'), ('n', (1, [0]))])
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   437
        '+1 @ann +1'
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   438
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   439
        >>> dagtext([('n', (0, [-1])), ('a', 'my annotation'), ('n', (1, [0]))])
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   440
        '+1 @"my annotation" +1'
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   441
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   442
    Commands:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   443
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   444
        >>> dagtext([('n', (0, [-1])), ('c', 'cmd'), ('n', (1, [0]))])
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   445
        '+1 !cmd +1'
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   446
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   447
        >>> dagtext([('n', (0, [-1])), ('c', 'my command'), ('n', (1, [0]))])
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   448
        '+1 !"my command" +1'
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   449
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   450
        >>> dagtext([('n', (0, [-1])), ('C', 'my command line'), ('n', (1, [0]))])
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   451
        '+1 !!my command line\\n+1'
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   452
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   453
    Comments:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   454
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   455
        >>> dagtext([('n', (0, [-1])), ('#', ' comment'), ('n', (1, [0]))])
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   456
        '+1 # comment\\n+1'
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   457
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   458
        >>> dagtext([])
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   459
        ''
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   460
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   461
    Combining parsedag and dagtext:
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   462
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   463
        >>> dagtext(parsedag('+1 :f +1 :p2 *f */p2'))
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   464
        '+1 :f +1 :p2 *f */p2'
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   465
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   466
    '''
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   467
    return "\n".join(dagtextlines(dag,
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   468
                                  addspaces,
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   469
                                  wraplabels,
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   470
                                  wrapannotations,
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   471
                                  wrapcommands,
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   472
                                  wrapnonlinear,
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   473
                                  usedots,
3201ff1459dd dagparser: parses and formats DAGs as concise text
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   474
                                  maxlinewidth))