############################################################################## # # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE # ############################################################################## import re, STDOM ##################################################################### # Updated functions # ##################################################################### def indention(str,front = re.compile("^\s+").match): """ Find the number of leading spaces. If none, return 0. """ result = front(str) if result is not None: start, end = result.span() return end-start else: return 0 # no leading spaces def insert(struct, top, level): """ find what will be the parant paragraph of a sentence and return that paragraph's sub-paragraphs. The new paragraph will be appended to those sub-paragraphs """ #print "struct", struct, top-1 if not top-1 in range(len(struct)): if struct: return struct[len(struct)-1].getSubparagraphs() return struct run = struct[top-1] i = 0 while i+1 < level: run = run.getSubparagraphs()[len(run.getSubparagraphs())-1] i = i + 1 #print "parent for level ", level, " was => ", run.getColorizableTexts() return run.getSubparagraphs() def display(struct): """ runs through the structure and prints out the paragraphs. If the insertion works correctly, display's results should mimic the orignal paragraphs. """ if struct.getColorizableTexts(): print join(struct.getColorizableTexts()),"\n" if struct.getSubparagraphs(): for x in struct.getSubparagraphs(): display(x) def display2(struct): """ runs through the structure and prints out the paragraphs. If the insertion works correctly, display's results should mimic the orignal paragraphs. """ if struct.getNodeValue(): print struct.getNodeValue(),"\n" if struct.getSubparagraphs(): for x in struct.getSubparagraphs(): display(x) def findlevel(levels,indent): """ remove all level information of levels with a greater level of indentation. Then return which level should insert this paragraph """ keys = levels.keys() for key in keys: if levels[key] > indent: del(levels[key]) keys = levels.keys() if not(keys): return 0 else: for key in keys: if levels[key] == indent: return key highest = 0 for key in keys: if key > highest: highest = key return highest-1 para_delim = r'(\n\s*\n|\r\n\s*\r\n)' # UNIX or DOS line endings, respectively ##################################################################### # Golly, the capitalization of this function always makes me think it's a class def StructuredText(paragraphs, delimiter=re.compile(para_delim)): """ StructuredText accepts paragraphs, which is a list of lines to be parsed. StructuredText creates a structure which mimics the structure of the paragraphs. Structure => [paragraph,[sub-paragraphs]] """ currentlevel = 0 currentindent = 0 levels = {0:0} level = 0 # which header are we under struct = [] # the structure to be returned run = struct paragraphs = paragraphs.expandtabs() paragraphs = '%s%s%s' % ('\n\n', paragraphs, '\n\n') paragraphs = delimiter.split(paragraphs) paragraphs = [ x for x in paragraphs if x.strip() ] if not paragraphs: return StructuredTextDocument() ind = [] # structure based on indention levels for paragraph in paragraphs: ind.append([indention(paragraph), paragraph]) currentindent = indention(paragraphs[0]) levels[0] = currentindent ############################################################# # updated # ############################################################# for indent,paragraph in ind : if indent == 0: level = level + 1 currentlevel = 0 currentindent = 0 levels = {0:0} struct.append(StructuredTextParagraph(paragraph, indent=indent, level=currentlevel)) elif indent > currentindent: currentlevel = currentlevel + 1 currentindent = indent levels[currentlevel] = indent run = insert(struct,level,currentlevel) run.append(StructuredTextParagraph(paragraph, indent=indent, level=currentlevel)) elif indent < currentindent: result = findlevel(levels,indent) if result > 0: currentlevel = result currentindent = indent if not level: struct.append(StructuredTextParagraph(paragraph, indent=indent, level=currentlevel)) else: run = insert(struct,level,currentlevel) run.append(StructuredTextParagraph(paragraph, indent=indent, level=currentlevel)) else: if insert(struct,level,currentlevel): run = insert(struct,level,currentlevel) else: run = struct currentindent = indent run.append(StructuredTextParagraph(paragraph, indent=indent, level=currentlevel)) return StructuredTextDocument(struct) Basic = StructuredText class StructuredTextParagraph(STDOM.Element): indent=0 def __init__(self, src, subs=None, **kw): if subs is None: subs=[] self._src=src self._subs=list(subs) self._attributes=kw.keys() for k, v in kw.items(): setattr(self, k, v) def getChildren(self, type=type, lt=type([])): src=self._src if type(src) is not lt: src=[src] return src+self._subs def getAttribute(self, name): return getattr(self, name, None) def getAttributeNode(self, name): if hasattr(self, name): return STDOM.Attr(name, getattr(self, name)) def getAttributes(self): d={} for a in self._attributes: d[a]=getattr(self, a, '') return STDOM.NamedNodeMap(d) def getSubparagraphs(self): return self._subs def setSubparagraphs(self, subs): self._subs=subs def getColorizableTexts(self): return (self._src,) def setColorizableTexts(self, src): self._src=src[0] def __repr__(self): r=[]; a=r.append a((' '*(self.indent or 0))+ ('%s(' % self.__class__.__name__) +str(self._src)+', [' ) for p in self._subs: a(`p`) a((' '*(self.indent or 0))+'])') return '\n'.join(r) """ create aliases for all above functions in the pythony way. """ def _get_Children(self, type=type, lt=type([])): return self.getChildren(type,lt) def _get_Attribute(self, name): return self.getAttribute(name) def _get_AttributeNode(self, name): return self.getAttributeNode(name) def _get_Attributes(self): return self.getAttributes() def _get_Subparagraphs(self): return self.getSubparagraphs() def _set_Subparagraphs(self, subs): return self.setSubparagraphs(subs) def _get_ColorizableTexts(self): return self.getColorizableTexts() def _set_ColorizableTexts(self, src): return self.setColorizableTexts(src) class StructuredTextDocument(StructuredTextParagraph): """ A StructuredTextDocument holds StructuredTextParagraphs as its subparagraphs. """ _attributes=() def __init__(self, subs=None, **kw): apply(StructuredTextParagraph.__init__, (self, '', subs), kw) def getChildren(self): return self._subs def getColorizableTexts(self): return () def setColorizableTexts(self, src): pass def __repr__(self): r=[]; a=r.append a('%s([' % self.__class__.__name__) for p in self._subs: a(`p`+',') a('])') return '\n'.join(r) """ create aliases for all above functions in the pythony way. """ def _get_Children(self): return self.getChildren() def _get_ColorizableTexts(self): return self.getColorizableTexts() def _set_ColorizableTexts(self, src): return self.setColorizableTexts(src)