diff options
Diffstat (limited to 'bin/reportlab/lib/yaml.py')
| -rw-r--r-- | bin/reportlab/lib/yaml.py | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/bin/reportlab/lib/yaml.py b/bin/reportlab/lib/yaml.py new file mode 100644 index 00000000000..b7799ce9c52 --- /dev/null +++ b/bin/reportlab/lib/yaml.py @@ -0,0 +1,188 @@ +#Copyright ReportLab Europe Ltd. 2000-2004 +#see license.txt for license details +#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/lib/yaml.py +# parses "Yet Another Markup Language" into a list of tuples. +# Each tuple says what the data is e.g. +# ('Paragraph', 'Heading1', 'Why Reportlab Rules') +# and the pattern depends on type. +""" +.h1 Welcome to YAML! +YAML is "Yet Another Markup Language" - a markup language +which is easier to type in than XML, yet gives us a +reasonable selection of formats. + +The general rule is that if a line begins with a '.', +it requires special processing. Otherwise lines +are concatenated to paragraphs, and blank lines +separate paragraphs. + +If the line ".foo bar bletch" is encountered, +it immediately ends and writes out any current +paragraph. + +It then looks for a parser method called 'foo'; +if found, it is called with arguments (bar, bletch). + +If this is not found, it assumes that 'foo' is a +paragraph style, and the text for the first line +of the paragraph is 'bar bletch'. It would be +up to the formatter to decide whether on not 'foo' +was a valid paragraph. + +Special commands understood at present are: +dot image filename +- adds the image to the document +dot beginPre Code +- begins a Preformatted object in style 'Code' +dot endPre +- ends a preformatted object. +""" +__version__=''' $Id$ ''' + + +import sys +import string + +#modes: +PLAIN = 1 +PREFORMATTED = 2 + +BULLETCHAR = '\267' # assumes font Symbol, but works on all platforms + +class BaseParser: + """"Simplest possible parser with only the most basic options. + + This defines the line-handling abilities and basic mechanism. + The class YAMLParser includes capabilities for a fairly rich + story.""" + + def __init__(self): + self.reset() + + def reset(self): + self._lineNo = 0 + self._style = 'Normal' # the default + self._results = [] + self._buf = [] + self._mode = PLAIN + + def parseFile(self, filename): + #returns list of objects + data = open(filename, 'r').readlines() + + for line in data: + #strip trailing newlines + self.readLine(line[:-1]) + self.endPara() + return self._results + + def parseText(self, textBlock): + "Parses the a possible multi-line text block" + lines = string.split(textBlock, '\n') + for line in lines: + self.readLine(line) + self.endPara() + return self._results + + def readLine(self, line): + #this is the inner loop + self._lineNo = self._lineNo + 1 + stripped = string.lstrip(line) + if len(stripped) == 0: + if self._mode == PLAIN: + self.endPara() + else: #preformatted, append it + self._buf.append(line) + elif line[0]=='.': + # we have a command of some kind + self.endPara() + words = string.split(stripped[1:]) + cmd, args = words[0], words[1:] + + #is it a parser method? + if hasattr(self.__class__, cmd): + method = eval('self.'+cmd) + #this was very bad; any type error in the method was hidden + #we have to hack the traceback + try: + apply(method, tuple(args)) + except TypeError, err: + sys.stderr.write("Parser method: apply(%s,%s) %s at line %d\n" % (cmd, tuple(args), err, self._lineNo)) + raise + else: + # assume it is a paragraph style - + # becomes the formatter's problem + self.endPara() #end the last one + words = string.split(stripped, ' ', 1) + assert len(words)==2, "Style %s but no data at line %d" % (words[0], self._lineNo) + (styletag, data) = words + self._style = styletag[1:] + self._buf.append(data) + else: + #we have data, add to para + self._buf.append(line) + + def endPara(self): + #ends the current paragraph, or preformatted block + + text = string.join(self._buf, ' ') + if text: + if self._mode == PREFORMATTED: + #item 3 is list of lines + self._results.append(('PREFORMATTED', self._style, + string.join(self._buf,'\n'))) + else: + self._results.append(('PARAGRAPH', self._style, text)) + self._buf = [] + self._style = 'Normal' + + def beginPre(self, stylename): + self._mode = PREFORMATTED + self._style = stylename + + def endPre(self): + self.endPara() + self._mode = PLAIN + + def image(self, filename): + self.endPara() + self._results.append(('IMAGE', filename)) + + +class Parser(BaseParser): + """This adds a basic set of "story" components compatible with HTML & PDF. + + Images, spaces""" + + def vSpace(self, points): + """Inserts a vertical spacer""" + self._results.append(('VSpace', points)) + + def pageBreak(self): + """Inserts a frame break""" + self._results.append(('PageBreak','blah')) # must be a tuple + + def custom(self, moduleName, funcName): + """Goes and gets the Python object and adds it to the story""" + self.endPara() + self._results.append(('Custom',moduleName, funcName)) + + def nextPageTemplate(self, templateName): + self._results.append(('NextPageTemplate',templateName)) + +def parseFile(filename): + p = Parser() + return p.parseFile(filename) + +def parseText(textBlock): + p = Parser() + return p.parseText(textBlock) + + +if __name__=='__main__': #NORUNTESTS + if len(sys.argv) <> 2: + results = parseText(__doc__) + else: + results = parseFile(sys.argv[1]) + import pprint + pprint.pprint(results)
\ No newline at end of file |
