comparison mercurial/minirst.py @ 9293:e48a48b754d3

minirst: parse field lists
author Martin Geisler <mg@lazybytes.net>
date Sun, 02 Aug 2009 23:38:07 +0200
parents 01e580143423
children 4c3fb45123e5
comparison
equal deleted inserted replaced
9292:01e580143423 9293:e48a48b754d3
19 - paragraphs 19 - paragraphs
20 20
21 - definition lists (must use ' ' to indent definitions) 21 - definition lists (must use ' ' to indent definitions)
22 22
23 - lists (items must start with '-') 23 - lists (items must start with '-')
24
25 - field lists (colons cannot be escaped)
24 26
25 - literal blocks 27 - literal blocks
26 28
27 - option lists (supports only long options without arguments) 29 - option lists (supports only long options without arguments)
28 30
186 i += len(options) - 1 188 i += len(options) - 1
187 i += 1 189 i += 1
188 return blocks 190 return blocks
189 191
190 192
193 _fieldre = re.compile(r':(?![: ])([^:]*)(?<! ):( +)(.*)')
194 def findfieldlists(blocks):
195 """Finds fields lists.
196
197 The blocks must have a 'type' field, i.e., they should have been
198 run through findliteralblocks first.
199 """
200 i = 0
201 while i < len(blocks):
202 # Searching for a paragraph that looks like this:
203 #
204 #
205 # +--------------------+----------------------+
206 # | ":" field name ":" | field body |
207 # +-------+------------+ |
208 # | (body elements)+ |
209 # +-----------------------------------+
210 if (blocks[i]['type'] == 'paragraph' and
211 _fieldre.match(blocks[i]['lines'][0])):
212 indent = blocks[i]['indent']
213 fields = []
214 for line in blocks[i]['lines']:
215 m = _fieldre.match(line)
216 if m:
217 key, spaces, rest = m.groups()
218 width = 2 + len(key) + len(spaces)
219 fields.append(dict(type='field', lines=[],
220 indent=indent, width=width))
221 # Turn ":foo: bar" into "foo bar".
222 line = '%s %s%s' % (key, spaces, rest)
223 fields[-1]['lines'].append(line)
224 blocks[i:i+1] = fields
225 i += len(fields) - 1
226 i += 1
227 return blocks
228
229
191 def finddefinitionlists(blocks): 230 def finddefinitionlists(blocks):
192 """Finds definition lists. 231 """Finds definition lists.
193 232
194 The blocks must have a 'type' field, i.e., they should have been 233 The blocks must have a 'type' field, i.e., they should have been
195 run through findliteralblocks first. 234 run through findliteralblocks first.
228 space between them, and adds an empty block between all other blocks. 267 space between them, and adds an empty block between all other blocks.
229 """ 268 """
230 i = 1 269 i = 1
231 while i < len(blocks): 270 while i < len(blocks):
232 if (blocks[i]['type'] == blocks[i-1]['type'] and 271 if (blocks[i]['type'] == blocks[i-1]['type'] and
233 blocks[i]['type'] in ('bullet', 'option', 'definition')): 272 blocks[i]['type'] in ('bullet', 'option', 'field', 'definition')):
234 i += 1 273 i += 1
235 else: 274 else:
236 blocks.insert(i, dict(lines=[''], indent=0, type='margin')) 275 blocks.insert(i, dict(lines=[''], indent=0, type='margin'))
237 i += 2 276 i += 2
238 return blocks 277 return blocks
259 initindent = subindent = indent 298 initindent = subindent = indent
260 text = ' '.join(map(str.strip, block['lines'])) 299 text = ' '.join(map(str.strip, block['lines']))
261 if block['type'] == 'bullet': 300 if block['type'] == 'bullet':
262 initindent = indent + '- ' 301 initindent = indent + '- '
263 subindent = indent + ' ' 302 subindent = indent + ' '
264 elif block['type'] == 'option': 303 elif block['type'] in ('option', 'field'):
265 subindent = indent + block['width'] * ' ' 304 subindent = indent + block['width'] * ' '
266 305
267 return textwrap.fill(text, width=width, 306 return textwrap.fill(text, width=width,
268 initial_indent=initindent, 307 initial_indent=initindent,
269 subsequent_indent=subindent) 308 subsequent_indent=subindent)
274 blocks = findblocks(text) 313 blocks = findblocks(text)
275 blocks = findliteralblocks(blocks) 314 blocks = findliteralblocks(blocks)
276 blocks = findsections(blocks) 315 blocks = findsections(blocks)
277 blocks = findbulletlists(blocks) 316 blocks = findbulletlists(blocks)
278 blocks = findoptionlists(blocks) 317 blocks = findoptionlists(blocks)
318 blocks = findfieldlists(blocks)
279 blocks = finddefinitionlists(blocks) 319 blocks = finddefinitionlists(blocks)
280 blocks = addmargins(blocks) 320 blocks = addmargins(blocks)
281 return '\n'.join(formatblock(b, width) for b in blocks) 321 return '\n'.join(formatblock(b, width) for b in blocks)
282 322
283 323
295 blocks = debug(findblocks, text) 335 blocks = debug(findblocks, text)
296 blocks = debug(findliteralblocks, blocks) 336 blocks = debug(findliteralblocks, blocks)
297 blocks = debug(findsections, blocks) 337 blocks = debug(findsections, blocks)
298 blocks = debug(findbulletlists, blocks) 338 blocks = debug(findbulletlists, blocks)
299 blocks = debug(findoptionlists, blocks) 339 blocks = debug(findoptionlists, blocks)
340 blocks = debug(findfieldlists, blocks)
300 blocks = debug(finddefinitionlists, blocks) 341 blocks = debug(finddefinitionlists, blocks)
301 blocks = debug(addmargins, blocks) 342 blocks = debug(addmargins, blocks)
302 print '\n'.join(formatblock(b, 30) for b in blocks) 343 print '\n'.join(formatblock(b, 30) for b in blocks)