reportlab/lib/yaml.py
author andy_robinson
Wed, 24 Jul 2002 19:56:39 +0000
changeset 1683 7fa753e4420a
parent 1559 2bb75ab0d0aa
child 2332 2a7ab4405e18
permissions -rw-r--r--
Removed all trailing whitespace
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
682
andy_robinson
parents:
diff changeset
     1
#copyright ReportLab Inc. 2000
andy_robinson
parents:
diff changeset
     2
#see license.txt for license details
817
8c3a399effda License text changes
rgbecker
parents: 682
diff changeset
     3
#history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/lib/yaml.py?cvsroot=reportlab
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1559
diff changeset
     4
#$Header: /tmp/reportlab/reportlab/lib/yaml.py,v 1.4 2002/07/24 19:56:37 andy_robinson Exp $
682
andy_robinson
parents:
diff changeset
     5
# parses "Yet Another Markup Language" into a list of tuples.
andy_robinson
parents:
diff changeset
     6
# Each tuple says what the data is e.g.
andy_robinson
parents:
diff changeset
     7
# ('Paragraph', 'Heading1', 'Why Reportlab Rules')
andy_robinson
parents:
diff changeset
     8
# and the pattern depends on type.
andy_robinson
parents:
diff changeset
     9
"""
andy_robinson
parents:
diff changeset
    10
.h1 Welcome to YAML!
andy_robinson
parents:
diff changeset
    11
YAML is "Yet Another Markup Language" - a markup language
andy_robinson
parents:
diff changeset
    12
which is easier to type in than XML, yet gives us a
andy_robinson
parents:
diff changeset
    13
reasonable selection of formats.
andy_robinson
parents:
diff changeset
    14
andy_robinson
parents:
diff changeset
    15
The general rule is that if a line begins with a '.',
andy_robinson
parents:
diff changeset
    16
it requires special processing. Otherwise lines
andy_robinson
parents:
diff changeset
    17
are concatenated to paragraphs, and blank lines
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1559
diff changeset
    18
separate paragraphs.
682
andy_robinson
parents:
diff changeset
    19
andy_robinson
parents:
diff changeset
    20
If the line ".foo bar bletch" is encountered,
andy_robinson
parents:
diff changeset
    21
it immediately ends and writes out any current
andy_robinson
parents:
diff changeset
    22
paragraph.
andy_robinson
parents:
diff changeset
    23
andy_robinson
parents:
diff changeset
    24
It then looks for a parser method called 'foo';
andy_robinson
parents:
diff changeset
    25
if found, it is called with arguments (bar, bletch).
andy_robinson
parents:
diff changeset
    26
andy_robinson
parents:
diff changeset
    27
If this is not found, it assumes that 'foo' is a
andy_robinson
parents:
diff changeset
    28
paragraph style, and the text for the first line
andy_robinson
parents:
diff changeset
    29
of the paragraph is 'bar bletch'.  It would be
andy_robinson
parents:
diff changeset
    30
up to the formatter to decide whether on not 'foo'
andy_robinson
parents:
diff changeset
    31
was a valid paragraph.
andy_robinson
parents:
diff changeset
    32
andy_robinson
parents:
diff changeset
    33
Special commands understood at present are:
andy_robinson
parents:
diff changeset
    34
dot image filename
andy_robinson
parents:
diff changeset
    35
- adds the image to the document
andy_robinson
parents:
diff changeset
    36
dot beginPre Code
andy_robinson
parents:
diff changeset
    37
- begins a Preformatted object in style 'Code'
andy_robinson
parents:
diff changeset
    38
dot endPre
andy_robinson
parents:
diff changeset
    39
- ends a preformatted object.
andy_robinson
parents:
diff changeset
    40
"""
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1559
diff changeset
    41
__version__=''' $Id: yaml.py,v 1.4 2002/07/24 19:56:37 andy_robinson Exp $ '''
682
andy_robinson
parents:
diff changeset
    42
andy_robinson
parents:
diff changeset
    43
andy_robinson
parents:
diff changeset
    44
import sys
andy_robinson
parents:
diff changeset
    45
import string
andy_robinson
parents:
diff changeset
    46
andy_robinson
parents:
diff changeset
    47
#modes:
andy_robinson
parents:
diff changeset
    48
PLAIN = 1
andy_robinson
parents:
diff changeset
    49
PREFORMATTED = 2
andy_robinson
parents:
diff changeset
    50
andy_robinson
parents:
diff changeset
    51
BULLETCHAR = '\267'  # assumes font Symbol, but works on all platforms
andy_robinson
parents:
diff changeset
    52
andy_robinson
parents:
diff changeset
    53
class BaseParser:
andy_robinson
parents:
diff changeset
    54
    """"Simplest possible parser with only the most basic options.
andy_robinson
parents:
diff changeset
    55
andy_robinson
parents:
diff changeset
    56
    This defines the line-handling abilities and basic mechanism.
andy_robinson
parents:
diff changeset
    57
    The class YAMLParser includes capabilities for a fairly rich
andy_robinson
parents:
diff changeset
    58
    story."""
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1559
diff changeset
    59
682
andy_robinson
parents:
diff changeset
    60
    def __init__(self):
andy_robinson
parents:
diff changeset
    61
        self.reset()
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1559
diff changeset
    62
682
andy_robinson
parents:
diff changeset
    63
    def reset(self):
andy_robinson
parents:
diff changeset
    64
        self._lineNo = 0
andy_robinson
parents:
diff changeset
    65
        self._style = 'Normal'  # the default
andy_robinson
parents:
diff changeset
    66
        self._results = []
andy_robinson
parents:
diff changeset
    67
        self._buf = []
andy_robinson
parents:
diff changeset
    68
        self._mode = PLAIN
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1559
diff changeset
    69
682
andy_robinson
parents:
diff changeset
    70
    def parseFile(self, filename):
andy_robinson
parents:
diff changeset
    71
        #returns list of objects
andy_robinson
parents:
diff changeset
    72
        data = open(filename, 'r').readlines()
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1559
diff changeset
    73
682
andy_robinson
parents:
diff changeset
    74
        for line in data:
andy_robinson
parents:
diff changeset
    75
            #strip trailing newlines
andy_robinson
parents:
diff changeset
    76
            self.readLine(line[:-1])
andy_robinson
parents:
diff changeset
    77
        self.endPara()
andy_robinson
parents:
diff changeset
    78
        return self._results
andy_robinson
parents:
diff changeset
    79
andy_robinson
parents:
diff changeset
    80
    def parseText(self, textBlock):
andy_robinson
parents:
diff changeset
    81
        "Parses the a possible multi-line text block"
andy_robinson
parents:
diff changeset
    82
        lines = string.split(textBlock, '\n')
andy_robinson
parents:
diff changeset
    83
        for line in lines:
andy_robinson
parents:
diff changeset
    84
            self.readLine(line)
andy_robinson
parents:
diff changeset
    85
        self.endPara()
andy_robinson
parents:
diff changeset
    86
        return self._results
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1559
diff changeset
    87
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1559
diff changeset
    88
    def readLine(self, line):
682
andy_robinson
parents:
diff changeset
    89
        #this is the inner loop
andy_robinson
parents:
diff changeset
    90
        self._lineNo = self._lineNo + 1
andy_robinson
parents:
diff changeset
    91
        stripped = string.lstrip(line)
andy_robinson
parents:
diff changeset
    92
        if len(stripped) == 0:
andy_robinson
parents:
diff changeset
    93
            if self._mode == PLAIN:
andy_robinson
parents:
diff changeset
    94
                self.endPara()
andy_robinson
parents:
diff changeset
    95
            else:  #preformatted, append it
andy_robinson
parents:
diff changeset
    96
                self._buf.append(line)
andy_robinson
parents:
diff changeset
    97
        elif line[0]=='.':
andy_robinson
parents:
diff changeset
    98
            # we have a command of some kind
andy_robinson
parents:
diff changeset
    99
            self.endPara()
andy_robinson
parents:
diff changeset
   100
            words = string.split(stripped[1:])
andy_robinson
parents:
diff changeset
   101
            cmd, args = words[0], words[1:]
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1559
diff changeset
   102
682
andy_robinson
parents:
diff changeset
   103
            #is it a parser method?
andy_robinson
parents:
diff changeset
   104
            if hasattr(self.__class__, cmd):
andy_robinson
parents:
diff changeset
   105
                method = eval('self.'+cmd)
andy_robinson
parents:
diff changeset
   106
                #this was very bad; any type error in the method was hidden
andy_robinson
parents:
diff changeset
   107
                #we have to hack the traceback
andy_robinson
parents:
diff changeset
   108
                try:
andy_robinson
parents:
diff changeset
   109
                    apply(method, tuple(args))
andy_robinson
parents:
diff changeset
   110
                except TypeError, err:
andy_robinson
parents:
diff changeset
   111
                    sys.stderr.write("Parser method: apply(%s,%s) %s at line %d\n" % (cmd, tuple(args), err, self._lineNo))
andy_robinson
parents:
diff changeset
   112
                    raise
andy_robinson
parents:
diff changeset
   113
            else:
andy_robinson
parents:
diff changeset
   114
                # assume it is a paragraph style -
andy_robinson
parents:
diff changeset
   115
                # becomes the formatter's problem
andy_robinson
parents:
diff changeset
   116
                self.endPara()  #end the last one
andy_robinson
parents:
diff changeset
   117
                words = string.split(stripped, ' ', 1)
andy_robinson
parents:
diff changeset
   118
                assert len(words)==2, "Style %s but no data at line %d" % (words[0], self._lineNo)
andy_robinson
parents:
diff changeset
   119
                (styletag, data) = words
andy_robinson
parents:
diff changeset
   120
                self._style = styletag[1:]
andy_robinson
parents:
diff changeset
   121
                self._buf.append(data)
andy_robinson
parents:
diff changeset
   122
        else:
andy_robinson
parents:
diff changeset
   123
            #we have data, add to para
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1559
diff changeset
   124
            self._buf.append(line)
682
andy_robinson
parents:
diff changeset
   125
andy_robinson
parents:
diff changeset
   126
    def endPara(self):
andy_robinson
parents:
diff changeset
   127
        #ends the current paragraph, or preformatted block
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1559
diff changeset
   128
682
andy_robinson
parents:
diff changeset
   129
        text = string.join(self._buf, ' ')
andy_robinson
parents:
diff changeset
   130
        if text:
andy_robinson
parents:
diff changeset
   131
            if self._mode == PREFORMATTED:
andy_robinson
parents:
diff changeset
   132
                #item 3 is list of lines
andy_robinson
parents:
diff changeset
   133
                self._results.append(('PREFORMATTED', self._style,
andy_robinson
parents:
diff changeset
   134
                                 string.join(self._buf,'\n')))
andy_robinson
parents:
diff changeset
   135
            else:
andy_robinson
parents:
diff changeset
   136
                self._results.append(('PARAGRAPH', self._style, text))
andy_robinson
parents:
diff changeset
   137
        self._buf = []
andy_robinson
parents:
diff changeset
   138
        self._style = 'Normal'
andy_robinson
parents:
diff changeset
   139
andy_robinson
parents:
diff changeset
   140
    def beginPre(self, stylename):
andy_robinson
parents:
diff changeset
   141
        self._mode = PREFORMATTED
andy_robinson
parents:
diff changeset
   142
        self._style = stylename
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1559
diff changeset
   143
682
andy_robinson
parents:
diff changeset
   144
    def endPre(self):
andy_robinson
parents:
diff changeset
   145
        self.endPara()
andy_robinson
parents:
diff changeset
   146
        self._mode = PLAIN
andy_robinson
parents:
diff changeset
   147
andy_robinson
parents:
diff changeset
   148
    def image(self, filename):
andy_robinson
parents:
diff changeset
   149
        self.endPara()
andy_robinson
parents:
diff changeset
   150
        self._results.append(('IMAGE', filename))
andy_robinson
parents:
diff changeset
   151
andy_robinson
parents:
diff changeset
   152
andy_robinson
parents:
diff changeset
   153
class Parser(BaseParser):
andy_robinson
parents:
diff changeset
   154
    """This adds a basic set of "story" components compatible with HTML & PDF.
andy_robinson
parents:
diff changeset
   155
andy_robinson
parents:
diff changeset
   156
    Images, spaces"""
andy_robinson
parents:
diff changeset
   157
andy_robinson
parents:
diff changeset
   158
    def vSpace(self, points):
andy_robinson
parents:
diff changeset
   159
        """Inserts a vertical spacer"""
andy_robinson
parents:
diff changeset
   160
        self._results.append(('VSpace', points))
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1559
diff changeset
   161
682
andy_robinson
parents:
diff changeset
   162
    def pageBreak(self):
andy_robinson
parents:
diff changeset
   163
        """Inserts a frame break"""
andy_robinson
parents:
diff changeset
   164
        self._results.append(('PageBreak','blah'))  # must be a tuple
andy_robinson
parents:
diff changeset
   165
andy_robinson
parents:
diff changeset
   166
    def custom(self, moduleName, funcName):
andy_robinson
parents:
diff changeset
   167
        """Goes and gets the Python object and adds it to the story"""
andy_robinson
parents:
diff changeset
   168
        self.endPara()
andy_robinson
parents:
diff changeset
   169
        self._results.append(('Custom',moduleName, funcName))
andy_robinson
parents:
diff changeset
   170
andy_robinson
parents:
diff changeset
   171
    def nextPageTemplate(self, templateName):
andy_robinson
parents:
diff changeset
   172
        self._results.append(('NextPageTemplate',templateName))
andy_robinson
parents:
diff changeset
   173
andy_robinson
parents:
diff changeset
   174
def parseFile(filename):
andy_robinson
parents:
diff changeset
   175
    p = Parser()
andy_robinson
parents:
diff changeset
   176
    return p.parseFile(filename)
andy_robinson
parents:
diff changeset
   177
andy_robinson
parents:
diff changeset
   178
def parseText(textBlock):
andy_robinson
parents:
diff changeset
   179
    p = Parser()
andy_robinson
parents:
diff changeset
   180
    return p.parseText(textBlock)
andy_robinson
parents:
diff changeset
   181
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1559
diff changeset
   182
682
andy_robinson
parents:
diff changeset
   183
if __name__=='__main__': #NORUNTESTS
andy_robinson
parents:
diff changeset
   184
    if len(sys.argv) <> 2:
andy_robinson
parents:
diff changeset
   185
        results = parseText(__doc__)
andy_robinson
parents:
diff changeset
   186
    else:
andy_robinson
parents:
diff changeset
   187
        results = parseFile(sys.argv[1])
andy_robinson
parents:
diff changeset
   188
    import pprint
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1559
diff changeset
   189
    pprint.pprint(results)