]>
Commit | Line | Data |
---|---|---|
c12bc4de RD |
1 | import re, STDOM |
2 | from string import split, join, replace, expandtabs, strip, find | |
3 | ||
4 | ##################################################################### | |
5 | # Updated functions # | |
6 | ##################################################################### | |
7 | ||
8 | def indention(str,front = re.compile("^\s+").match): | |
9 | """ | |
10 | Convert all tabs to the appropriate number of spaces. | |
11 | Find the number of leading spaces. If none, return 0 | |
12 | """ | |
13 | ||
14 | if front(str): | |
15 | start,end = front(str).span() | |
16 | return end-start-1 | |
17 | else: | |
18 | return 0 # no leading spaces | |
19 | ||
20 | def insert(struct, top, level): | |
21 | """ | |
22 | find what will be the parant paragraph of | |
23 | a sentence and return that paragraph's | |
24 | sub-paragraphs. The new paragraph will be | |
25 | appended to those sub-paragraphs | |
26 | """ | |
27 | #print "struct", struct, top-1 | |
28 | if not top-1 in range(len(struct)): | |
ddfc587a RD |
29 | if struct: |
30 | return struct[len(struct)-1].getSubparagraphs() | |
31 | return struct | |
c12bc4de RD |
32 | run = struct[top-1] |
33 | i = 0 | |
34 | while i+1 < level: | |
35 | run = run.getSubparagraphs()[len(run.getSubparagraphs())-1] | |
36 | i = i + 1 | |
37 | #print "parent for level ", level, " was => ", run.getColorizableTexts() | |
38 | return run.getSubparagraphs() | |
39 | ||
40 | def display(struct): | |
41 | """ | |
42 | runs through the structure and prints out | |
43 | the paragraphs. If the insertion works | |
44 | correctly, display's results should mimic | |
45 | the orignal paragraphs. | |
46 | """ | |
47 | ||
48 | if struct.getColorizableTexts(): | |
49 | print join(struct.getColorizableTexts()),"\n" | |
50 | if struct.getSubparagraphs(): | |
51 | for x in struct.getSubparagraphs(): | |
52 | display(x) | |
53 | ||
54 | def display2(struct): | |
55 | """ | |
56 | runs through the structure and prints out | |
57 | the paragraphs. If the insertion works | |
58 | correctly, display's results should mimic | |
59 | the orignal paragraphs. | |
60 | """ | |
61 | ||
62 | if struct.getNodeValue(): | |
63 | print struct.getNodeValue(),"\n" | |
64 | if struct.getSubparagraphs(): | |
65 | for x in struct.getSubparagraphs(): | |
66 | display(x) | |
67 | ||
68 | def findlevel(levels,indent): | |
69 | """ | |
70 | remove all level information of levels | |
71 | with a greater level of indentation. | |
72 | Then return which level should insert this | |
73 | paragraph | |
74 | """ | |
75 | ||
76 | keys = levels.keys() | |
77 | for key in keys: | |
78 | if levels[key] > indent: | |
79 | del(levels[key]) | |
80 | keys = levels.keys() | |
81 | if not(keys): | |
82 | return 0 | |
83 | else: | |
84 | for key in keys: | |
85 | if levels[key] == indent: | |
86 | return key | |
87 | highest = 0 | |
88 | for key in keys: | |
89 | if key > highest: | |
90 | highest = key | |
91 | return highest-1 | |
92 | ||
93 | ##################################################################### | |
94 | ||
95 | # Golly, the capitalization of this function always makes me think it's a class | |
96 | def StructuredText(paragraphs, paragraph_delimiter=re.compile('\n\s*\n')): | |
97 | """ | |
98 | StructuredText accepts paragraphs, which is a list of | |
99 | lines to be parsed. StructuredText creates a structure | |
100 | which mimics the structure of the paragraphs. | |
101 | Structure => [paragraph,[sub-paragraphs]] | |
102 | """ | |
103 | ||
104 | currentlevel = 0 | |
105 | currentindent = 0 | |
106 | levels = {0:0} | |
107 | level = 0 # which header are we under | |
108 | struct = [] # the structure to be returned | |
109 | run = struct | |
110 | ||
111 | paragraphs = filter( | |
112 | strip, | |
113 | paragraph_delimiter.split(expandtabs('\n\n'+paragraphs+'\n\n')) | |
114 | ) | |
115 | ||
116 | if not paragraphs: return [] | |
117 | ||
118 | ind = [] # structure based on indention levels | |
119 | for paragraph in paragraphs: | |
120 | ind.append([indention(paragraph), paragraph]) | |
121 | ||
122 | currentindent = indention(paragraphs[0]) | |
123 | levels[0] = currentindent | |
124 | ||
125 | ############################################################# | |
126 | # updated # | |
127 | ############################################################# | |
128 | ||
129 | for indent,paragraph in ind : | |
130 | if indent == 0: | |
131 | level = level + 1 | |
132 | currentlevel = 0 | |
133 | currentindent = 0 | |
134 | levels = {0:0} | |
135 | struct.append(StructuredTextParagraph(paragraph, indent=indent, level=currentlevel)) | |
136 | elif indent > currentindent: | |
137 | currentlevel = currentlevel + 1 | |
138 | currentindent = indent | |
139 | levels[currentlevel] = indent | |
140 | run = insert(struct,level,currentlevel) | |
141 | run.append(StructuredTextParagraph(paragraph, indent=indent, level=currentlevel)) | |
142 | elif indent < currentindent: | |
143 | result = findlevel(levels,indent) | |
144 | if result > 0: | |
145 | currentlevel = result | |
146 | currentindent = indent | |
ddfc587a RD |
147 | if not level: |
148 | struct.append(StructuredTextParagraph(paragraph, indent=indent, level=currentlevel)) | |
149 | else: | |
150 | run = insert(struct,level,currentlevel) | |
151 | run.append(StructuredTextParagraph(paragraph, indent=indent, level=currentlevel)) | |
c12bc4de RD |
152 | else: |
153 | if insert(struct,level,currentlevel): | |
154 | run = insert(struct,level,currentlevel) | |
155 | else: | |
156 | run = struct | |
157 | currentindet = indent | |
158 | run.append(StructuredTextParagraph(paragraph, indent=indent, level=currentlevel)) | |
159 | ||
160 | return StructuredTextDocument(struct) | |
161 | ||
162 | Basic = StructuredText | |
163 | ||
164 | class StructuredTextParagraph(STDOM.Element): | |
165 | ||
166 | indent=0 | |
167 | ||
168 | def __init__(self, src, subs=None, **kw): | |
169 | if subs is None: subs=[] | |
170 | self._src=src | |
171 | self._subs=list(subs) | |
172 | ||
173 | self._attributes=kw.keys() | |
174 | for k, v in kw.items(): setattr(self, k, v) | |
175 | ||
176 | def getChildren(self, type=type, lt=type([])): | |
177 | src=self._src | |
178 | if type(src) is not lt: src=[src] | |
179 | return src+self._subs | |
180 | ||
181 | def getAttribute(self, name): | |
182 | return getattr(self, name, None) | |
183 | ||
184 | def getAttributeNode(self, name): | |
185 | if hasattr(self, name): | |
186 | return STDOM.Attr(name, getattr(self, name)) | |
187 | ||
188 | def getAttributes(self): | |
189 | d={} | |
190 | for a in self._attributes: | |
191 | d[a]=getattr(self, a, '') | |
192 | return STDOM.NamedNodeMap(d) | |
193 | ||
194 | def getSubparagraphs(self): | |
195 | return self._subs | |
196 | ||
197 | def setSubparagraphs(self, subs): | |
198 | self._subs=subs | |
199 | ||
200 | def getColorizableTexts(self): | |
201 | return (self._src,) | |
202 | ||
203 | def setColorizableTexts(self, src): | |
204 | self._src=src[0] | |
205 | ||
206 | def __repr__(self): | |
207 | r=[]; a=r.append | |
208 | a((' '*(self.indent or 0))+ | |
209 | ('%s(' % self.__class__.__name__) | |
210 | +str(self._src)+', [' | |
211 | ) | |
212 | for p in self._subs: a(`p`) | |
213 | a((' '*(self.indent or 0))+'])') | |
214 | return join(r,'\n') | |
215 | ||
216 | """ | |
217 | create aliases for all above functions in the pythony way. | |
218 | """ | |
219 | ||
220 | def _get_Children(self, type=type, lt=type([])): | |
221 | return self.getChildren(type,lt) | |
222 | ||
223 | def _get_Attribute(self, name): | |
224 | return self.getAttribute(name) | |
225 | ||
226 | def _get_AttributeNode(self, name): | |
227 | return self.getAttributeNode(name) | |
228 | ||
229 | def _get_Attributes(self): | |
230 | return self.getAttributes() | |
231 | ||
232 | def _get_Subparagraphs(self): | |
233 | return self.getSubparagraphs() | |
234 | ||
235 | def _set_Subparagraphs(self, subs): | |
236 | return self.setSubparagraphs(subs) | |
237 | ||
238 | def _get_ColorizableTexts(self): | |
239 | return self.getColorizableTexts() | |
240 | ||
241 | def _set_ColorizableTexts(self, src): | |
242 | return self.setColorizableTexts(src) | |
243 | ||
244 | class StructuredTextDocument(StructuredTextParagraph): | |
245 | """ | |
246 | A StructuredTextDocument holds StructuredTextParagraphs | |
247 | as its subparagraphs. | |
248 | """ | |
249 | _attributes=() | |
250 | ||
251 | def __init__(self, subs=None, **kw): | |
252 | apply(StructuredTextParagraph.__init__, | |
253 | (self, '', subs), | |
254 | kw) | |
255 | ||
256 | def getChildren(self): | |
257 | return self._subs | |
258 | ||
259 | def getColorizableTexts(self): | |
260 | return () | |
261 | ||
262 | def setColorizableTexts(self, src): | |
263 | pass | |
264 | ||
265 | def __repr__(self): | |
266 | r=[]; a=r.append | |
267 | a('%s([' % self.__class__.__name__) | |
268 | for p in self._subs: a(`p`+',') | |
269 | a('])') | |
270 | return join(r,'\n') | |
271 | ||
272 | """ | |
273 | create aliases for all above functions in the pythony way. | |
274 | """ | |
275 | ||
276 | def _get_Children(self): | |
277 | return self.getChildren() | |
278 | ||
279 | def _get_ColorizableTexts(self): | |
280 | return self.getColorizableTexts() | |
281 | ||
282 | def _set_ColorizableTexts(self, src): | |
283 | return self.setColorizableTexts(src) |