##// END OF EJS Templates
minirst: report pruned container types
Martin Geisler -
r10444:e99e0e07 default
parent child Browse files
Show More
@@ -1,354 +1,361 b''
1 1 # minirst.py - minimal reStructuredText parser
2 2 #
3 3 # Copyright 2009, 2010 Matt Mackall <mpm@selenic.com> and others
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 """simplified reStructuredText parser.
9 9
10 10 This parser knows just enough about reStructuredText to parse the
11 11 Mercurial docstrings.
12 12
13 13 It cheats in a major way: nested blocks are not really nested. They
14 14 are just indented blocks that look like they are nested. This relies
15 15 on the user to keep the right indentation for the blocks.
16 16
17 17 It only supports a small subset of reStructuredText:
18 18
19 19 - sections
20 20
21 21 - paragraphs
22 22
23 23 - literal blocks
24 24
25 25 - definition lists
26 26
27 27 - bullet lists (items must start with '-')
28 28
29 29 - enumerated lists (no autonumbering)
30 30
31 31 - field lists (colons cannot be escaped)
32 32
33 33 - option lists (supports only long options without arguments)
34 34
35 35 - inline literals (no other inline markup is not recognized)
36 36 """
37 37
38 38 import re, sys, textwrap
39 39
40 40
41 41 def findblocks(text):
42 42 """Find continuous blocks of lines in text.
43 43
44 44 Returns a list of dictionaries representing the blocks. Each block
45 45 has an 'indent' field and a 'lines' field.
46 46 """
47 47 blocks = [[]]
48 48 lines = text.splitlines()
49 49 for line in lines:
50 50 if line.strip():
51 51 blocks[-1].append(line)
52 52 elif blocks[-1]:
53 53 blocks.append([])
54 54 if not blocks[-1]:
55 55 del blocks[-1]
56 56
57 57 for i, block in enumerate(blocks):
58 58 indent = min((len(l) - len(l.lstrip())) for l in block)
59 59 blocks[i] = dict(indent=indent, lines=[l[indent:] for l in block])
60 60 return blocks
61 61
62 62
63 63 def findliteralblocks(blocks):
64 64 """Finds literal blocks and adds a 'type' field to the blocks.
65 65
66 66 Literal blocks are given the type 'literal', all other blocks are
67 67 given type the 'paragraph'.
68 68 """
69 69 i = 0
70 70 while i < len(blocks):
71 71 # Searching for a block that looks like this:
72 72 #
73 73 # +------------------------------+
74 74 # | paragraph |
75 75 # | (ends with "::") |
76 76 # +------------------------------+
77 77 # +---------------------------+
78 78 # | indented literal block |
79 79 # +---------------------------+
80 80 blocks[i]['type'] = 'paragraph'
81 81 if blocks[i]['lines'][-1].endswith('::') and i + 1 < len(blocks):
82 82 indent = blocks[i]['indent']
83 83 adjustment = blocks[i + 1]['indent'] - indent
84 84
85 85 if blocks[i]['lines'] == ['::']:
86 86 # Expanded form: remove block
87 87 del blocks[i]
88 88 i -= 1
89 89 elif blocks[i]['lines'][-1].endswith(' ::'):
90 90 # Partially minimized form: remove space and both
91 91 # colons.
92 92 blocks[i]['lines'][-1] = blocks[i]['lines'][-1][:-3]
93 93 else:
94 94 # Fully minimized form: remove just one colon.
95 95 blocks[i]['lines'][-1] = blocks[i]['lines'][-1][:-1]
96 96
97 97 # List items are formatted with a hanging indent. We must
98 98 # correct for this here while we still have the original
99 99 # information on the indentation of the subsequent literal
100 100 # blocks available.
101 101 m = _bulletre.match(blocks[i]['lines'][0])
102 102 if m:
103 103 indent += m.end()
104 104 adjustment -= m.end()
105 105
106 106 # Mark the following indented blocks.
107 107 while i + 1 < len(blocks) and blocks[i + 1]['indent'] > indent:
108 108 blocks[i + 1]['type'] = 'literal'
109 109 blocks[i + 1]['indent'] -= adjustment
110 110 i += 1
111 111 i += 1
112 112 return blocks
113 113
114 114 _bulletre = re.compile(r'(-|[0-9A-Za-z]+\.|\(?[0-9A-Za-z]+\)) ')
115 115 _optionre = re.compile(r'^(--[a-z-]+)((?:[ =][a-zA-Z][\w-]*)? +)(.*)$')
116 116 _fieldre = re.compile(r':(?![: ])([^:]*)(?<! ):[ ]+(.*)')
117 117 _definitionre = re.compile(r'[^ ]')
118 118
119 119 def splitparagraphs(blocks):
120 120 """Split paragraphs into lists."""
121 121 # Tuples with (list type, item regexp, single line items?). Order
122 122 # matters: definition lists has the least specific regexp and must
123 123 # come last.
124 124 listtypes = [('bullet', _bulletre, True),
125 125 ('option', _optionre, True),
126 126 ('field', _fieldre, True),
127 127 ('definition', _definitionre, False)]
128 128
129 129 def match(lines, i, itemre, singleline):
130 130 """Does itemre match an item at line i?
131 131
132 132 A list item can be followed by an idented line or another list
133 133 item (but only if singleline is True).
134 134 """
135 135 line1 = lines[i]
136 136 line2 = i + 1 < len(lines) and lines[i + 1] or ''
137 137 if not itemre.match(line1):
138 138 return False
139 139 if singleline:
140 140 return line2 == '' or line2[0] == ' ' or itemre.match(line2)
141 141 else:
142 142 return line2.startswith(' ')
143 143
144 144 i = 0
145 145 while i < len(blocks):
146 146 if blocks[i]['type'] == 'paragraph':
147 147 lines = blocks[i]['lines']
148 148 for type, itemre, singleline in listtypes:
149 149 if match(lines, 0, itemre, singleline):
150 150 items = []
151 151 for j, line in enumerate(lines):
152 152 if match(lines, j, itemre, singleline):
153 153 items.append(dict(type=type, lines=[],
154 154 indent=blocks[i]['indent']))
155 155 items[-1]['lines'].append(line)
156 156 blocks[i:i + 1] = items
157 157 break
158 158 i += 1
159 159 return blocks
160 160
161 161
162 162 _fieldwidth = 12
163 163
164 164 def updatefieldlists(blocks):
165 165 """Find key and maximum key width for field lists."""
166 166 i = 0
167 167 while i < len(blocks):
168 168 if blocks[i]['type'] != 'field':
169 169 i += 1
170 170 continue
171 171
172 172 keywidth = 0
173 173 j = i
174 174 while j < len(blocks) and blocks[j]['type'] == 'field':
175 175 m = _fieldre.match(blocks[j]['lines'][0])
176 176 key, rest = m.groups()
177 177 blocks[j]['lines'][0] = rest
178 178 blocks[j]['key'] = key
179 179 keywidth = max(keywidth, len(key))
180 180 j += 1
181 181
182 182 for block in blocks[i:j]:
183 183 block['keywidth'] = keywidth
184 184 i = j + 1
185 185
186 186 return blocks
187 187
188 188
189 189 def prunecontainers(blocks, keep):
190 190 """Prune unwanted containers.
191 191
192 192 The blocks must have a 'type' field, i.e., they should have been
193 193 run through findliteralblocks first.
194 194 """
195 pruned = []
195 196 i = 0
196 197 while i + 1 < len(blocks):
197 198 # Searching for a block that looks like this:
198 199 #
199 200 # +-------+---------------------------+
200 201 # | ".. container ::" type |
201 202 # +---+ |
202 203 # | blocks |
203 204 # +-------------------------------+
204 205 if (blocks[i]['type'] == 'paragraph' and
205 206 blocks[i]['lines'][0].startswith('.. container::')):
206 207 indent = blocks[i]['indent']
207 208 adjustment = blocks[i + 1]['indent'] - indent
208 209 containertype = blocks[i]['lines'][0][15:]
209 210 prune = containertype not in keep
211 if prune:
212 pruned.append(containertype)
210 213
211 214 # Always delete "..container:: type" block
212 215 del blocks[i]
213 216 j = i
214 217 while j < len(blocks) and blocks[j]['indent'] > indent:
215 218 if prune:
216 219 del blocks[j]
217 220 i -= 1 # adjust outer index
218 221 else:
219 222 blocks[j]['indent'] -= adjustment
220 223 j += 1
221 224 i += 1
222 return blocks
225 return blocks, pruned
223 226
224 227
225 228 def findsections(blocks):
226 229 """Finds sections.
227 230
228 231 The blocks must have a 'type' field, i.e., they should have been
229 232 run through findliteralblocks first.
230 233 """
231 234 for block in blocks:
232 235 # Searching for a block that looks like this:
233 236 #
234 237 # +------------------------------+
235 238 # | Section title |
236 239 # | ------------- |
237 240 # +------------------------------+
238 241 if (block['type'] == 'paragraph' and
239 242 len(block['lines']) == 2 and
240 243 block['lines'][1] == '-' * len(block['lines'][0])):
241 244 block['type'] = 'section'
242 245 return blocks
243 246
244 247
245 248 def inlineliterals(blocks):
246 249 for b in blocks:
247 250 if b['type'] == 'paragraph':
248 251 b['lines'] = [l.replace('``', '"') for l in b['lines']]
249 252 return blocks
250 253
251 254
252 255 def addmargins(blocks):
253 256 """Adds empty blocks for vertical spacing.
254 257
255 258 This groups bullets, options, and definitions together with no vertical
256 259 space between them, and adds an empty block between all other blocks.
257 260 """
258 261 i = 1
259 262 while i < len(blocks):
260 263 if (blocks[i]['type'] == blocks[i - 1]['type'] and
261 264 blocks[i]['type'] in ('bullet', 'option', 'field', 'definition')):
262 265 i += 1
263 266 else:
264 267 blocks.insert(i, dict(lines=[''], indent=0, type='margin'))
265 268 i += 2
266 269 return blocks
267 270
268 271
269 272 def formatblock(block, width):
270 273 """Format a block according to width."""
271 274 if width <= 0:
272 275 width = 78
273 276 indent = ' ' * block['indent']
274 277 if block['type'] == 'margin':
275 278 return ''
276 279 if block['type'] == 'literal':
277 280 indent += ' '
278 281 return indent + ('\n' + indent).join(block['lines'])
279 282 if block['type'] == 'section':
280 283 return indent + ('\n' + indent).join(block['lines'])
281 284 if block['type'] == 'definition':
282 285 term = indent + block['lines'][0]
283 286 hang = len(block['lines'][-1]) - len(block['lines'][-1].lstrip())
284 287 defindent = indent + hang * ' '
285 288 text = ' '.join(map(str.strip, block['lines'][1:]))
286 289 return "%s\n%s" % (term, textwrap.fill(text, width=width,
287 290 initial_indent=defindent,
288 291 subsequent_indent=defindent))
289 292 initindent = subindent = indent
290 293 if block['type'] == 'bullet':
291 294 m = _bulletre.match(block['lines'][0])
292 295 subindent = indent + m.end() * ' '
293 296 elif block['type'] == 'field':
294 297 keywidth = block['keywidth']
295 298 key = block['key']
296 299
297 300 subindent = indent + _fieldwidth * ' '
298 301 if len(key) + 2 > _fieldwidth:
299 302 # key too large, use full line width
300 303 key = key.ljust(width)
301 304 elif keywidth + 2 < _fieldwidth:
302 305 # all keys are small, add only two spaces
303 306 key = key.ljust(keywidth + 2)
304 307 subindent = indent + (keywidth + 2) * ' '
305 308 else:
306 309 # mixed sizes, use fieldwidth for this one
307 310 key = key.ljust(_fieldwidth)
308 311 block['lines'][0] = key + block['lines'][0]
309 312 elif block['type'] == 'option':
310 313 m = _optionre.match(block['lines'][0])
311 314 option, arg, rest = m.groups()
312 315 subindent = indent + (len(option) + len(arg)) * ' '
313 316
314 317 text = ' '.join(map(str.strip, block['lines']))
315 318 return textwrap.fill(text, width=width,
316 319 initial_indent=initindent,
317 320 subsequent_indent=subindent)
318 321
319 322
320 def format(text, width, indent=0, keep=[]):
323 def format(text, width, indent=0, keep=None):
321 324 """Parse and format the text according to width."""
322 325 blocks = findblocks(text)
323 326 for b in blocks:
324 327 b['indent'] += indent
325 328 blocks = findliteralblocks(blocks)
326 blocks = prunecontainers(blocks, keep)
329 blocks, pruned = prunecontainers(blocks, keep or [])
327 330 blocks = inlineliterals(blocks)
328 331 blocks = splitparagraphs(blocks)
329 332 blocks = updatefieldlists(blocks)
330 333 blocks = findsections(blocks)
331 334 blocks = addmargins(blocks)
332 return '\n'.join(formatblock(b, width) for b in blocks)
335 text = '\n'.join(formatblock(b, width) for b in blocks)
336 if keep is None:
337 return text
338 else:
339 return text, pruned
333 340
334 341
335 342 if __name__ == "__main__":
336 343 from pprint import pprint
337 344
338 345 def debug(func, *args):
339 346 blocks = func(*args)
340 347 print "*** after %s:" % func.__name__
341 348 pprint(blocks)
342 349 print
343 350 return blocks
344 351
345 352 text = open(sys.argv[1]).read()
346 353 blocks = debug(findblocks, text)
347 354 blocks = debug(findliteralblocks, blocks)
348 355 blocks = debug(prunecontainers, blocks, sys.argv[2:])
349 356 blocks = debug(inlineliterals, blocks)
350 357 blocks = debug(splitparagraphs, blocks)
351 358 blocks = debug(updatefieldlists, blocks)
352 359 blocks = debug(findsections, blocks)
353 360 blocks = debug(addmargins, blocks)
354 361 print '\n'.join(formatblock(b, 30) for b in blocks)
@@ -1,167 +1,174 b''
1 1 #!/usr/bin/env python
2 2
3 from pprint import pprint
3 4 from mercurial import minirst
4 5
5 6 def debugformat(title, text, width, **kwargs):
6 7 print "%s formatted to fit within %d characters:" % (title, width)
7 8 print "-" * 70
8 print minirst.format(text, width, **kwargs)
9 formatted = minirst.format(text, width, **kwargs)
10 if type(formatted) == tuple:
11 print formatted[0]
12 print "-" * 70
13 pprint(formatted[1])
14 else:
15 print formatted
9 16 print "-" * 70
10 17 print
11 18
12 19 paragraphs = """
13 20 This is some text in the first paragraph.
14 21
15 22 A small indented paragraph.
16 23 It is followed by some lines
17 24 containing random whitespace.
18 25 \n \n \nThe third and final paragraph.
19 26 """
20 27
21 28 debugformat('paragraphs', paragraphs, 60)
22 29 debugformat('paragraphs', paragraphs, 30)
23 30
24 31
25 32 definitions = """
26 33 A Term
27 34 Definition. The indented
28 35 lines make up the definition.
29 36 Another Term
30 37 Another definition. The final line in the
31 38 definition determines the indentation, so
32 39 this will be indented with four spaces.
33 40
34 41 A Nested/Indented Term
35 42 Definition.
36 43 """
37 44
38 45 debugformat('definitions', definitions, 60)
39 46 debugformat('definitions', definitions, 30)
40 47
41 48
42 49 literals = r"""
43 50 The fully minimized form is the most
44 51 convenient form::
45 52
46 53 Hello
47 54 literal
48 55 world
49 56
50 57 In the partially minimized form a paragraph
51 58 simply ends with space-double-colon. ::
52 59
53 60 ////////////////////////////////////////
54 61 long un-wrapped line in a literal block
55 62 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
56 63
57 64 ::
58 65
59 66 This literal block is started with '::',
60 67 the so-called expanded form. The paragraph
61 68 with '::' disappears in the final output.
62 69 """
63 70
64 71 debugformat('literals', literals, 60)
65 72 debugformat('literals', literals, 30)
66 73
67 74
68 75 lists = """
69 76 - This is the first list item.
70 77
71 78 Second paragraph in the first list item.
72 79
73 80 - List items need not be separated
74 81 by a blank line.
75 82 - And will be rendered without
76 83 one in any case.
77 84
78 85 We can have indented lists:
79 86
80 87 - This is an indented list item
81 88
82 89 - Another indented list item::
83 90
84 91 - A literal block in the middle
85 92 of an indented list.
86 93
87 94 (The above is not a list item since we are in the literal block.)
88 95
89 96 ::
90 97
91 98 Literal block with no indentation (apart from
92 99 the two spaces added to all literal blocks).
93 100
94 101 1. This is an enumerated list (first item).
95 102 2. Continuing with the second item.
96 103
97 104 (1) foo
98 105 (2) bar
99 106
100 107 1) Another
101 108 2) List
102 109 """
103 110
104 111 debugformat('lists', lists, 60)
105 112 debugformat('lists', lists, 30)
106 113
107 114
108 115 options = """
109 116 There is support for simple option lists,
110 117 but only with long options:
111 118
112 119 --all Output all.
113 120 --both Output both (this description is
114 121 quite long).
115 122 --long Output all day long.
116 123
117 124 --par This option has two paragraphs in its description.
118 125 This is the first.
119 126
120 127 This is the second. Blank lines may be omitted between
121 128 options (as above) or left in (as here).
122 129
123 130 The next paragraph looks like an option list, but lacks the two-space
124 131 marker after the option. It is treated as a normal paragraph:
125 132
126 133 --foo bar baz
127 134 """
128 135
129 136 debugformat('options', options, 60)
130 137 debugformat('options', options, 30)
131 138
132 139
133 140 fields = """
134 141 :a: First item.
135 142 :ab: Second item. Indentation and wrapping
136 143 is handled automatically.
137 144
138 145 Next list:
139 146
140 147 :small: The larger key below triggers full indentation here.
141 148 :much too large: This key is big enough to get its own line.
142 149 """
143 150
144 151 debugformat('fields', fields, 60)
145 152 debugformat('fields', fields, 30)
146 153
147 154 containers = """
148 155 Normal output.
149 156
150 157 .. container:: debug
151 158
152 159 Initial debug output.
153 160
154 161 .. container:: verbose
155 162
156 163 Verbose output.
157 164
158 165 .. container:: debug
159 166
160 167 Debug output.
161 168 """
162 169
163 170 debugformat('containers (normal)', containers, 60)
164 171 debugformat('containers (verbose)', containers, 60, keep=['verbose'])
165 172 debugformat('containers (debug)', containers, 60, keep=['debug'])
166 173 debugformat('containers (verbose debug)', containers, 60,
167 174 keep=['verbose', 'debug'])
@@ -1,278 +1,284 b''
1 1 paragraphs formatted to fit within 60 characters:
2 2 ----------------------------------------------------------------------
3 3 This is some text in the first paragraph.
4 4
5 5 A small indented paragraph. It is followed by some lines
6 6 containing random whitespace.
7 7
8 8 The third and final paragraph.
9 9 ----------------------------------------------------------------------
10 10
11 11 paragraphs formatted to fit within 30 characters:
12 12 ----------------------------------------------------------------------
13 13 This is some text in the first
14 14 paragraph.
15 15
16 16 A small indented paragraph.
17 17 It is followed by some lines
18 18 containing random
19 19 whitespace.
20 20
21 21 The third and final paragraph.
22 22 ----------------------------------------------------------------------
23 23
24 24 definitions formatted to fit within 60 characters:
25 25 ----------------------------------------------------------------------
26 26 A Term
27 27 Definition. The indented lines make up the definition.
28 28 Another Term
29 29 Another definition. The final line in the definition
30 30 determines the indentation, so this will be indented
31 31 with four spaces.
32 32 A Nested/Indented Term
33 33 Definition.
34 34 ----------------------------------------------------------------------
35 35
36 36 definitions formatted to fit within 30 characters:
37 37 ----------------------------------------------------------------------
38 38 A Term
39 39 Definition. The indented
40 40 lines make up the
41 41 definition.
42 42 Another Term
43 43 Another definition. The
44 44 final line in the
45 45 definition determines the
46 46 indentation, so this will
47 47 be indented with four
48 48 spaces.
49 49 A Nested/Indented Term
50 50 Definition.
51 51 ----------------------------------------------------------------------
52 52
53 53 literals formatted to fit within 60 characters:
54 54 ----------------------------------------------------------------------
55 55 The fully minimized form is the most convenient form:
56 56
57 57 Hello
58 58 literal
59 59 world
60 60
61 61 In the partially minimized form a paragraph simply ends with
62 62 space-double-colon.
63 63
64 64 ////////////////////////////////////////
65 65 long un-wrapped line in a literal block
66 66 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
67 67
68 68 This literal block is started with '::',
69 69 the so-called expanded form. The paragraph
70 70 with '::' disappears in the final output.
71 71 ----------------------------------------------------------------------
72 72
73 73 literals formatted to fit within 30 characters:
74 74 ----------------------------------------------------------------------
75 75 The fully minimized form is
76 76 the most convenient form:
77 77
78 78 Hello
79 79 literal
80 80 world
81 81
82 82 In the partially minimized
83 83 form a paragraph simply ends
84 84 with space-double-colon.
85 85
86 86 ////////////////////////////////////////
87 87 long un-wrapped line in a literal block
88 88 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
89 89
90 90 This literal block is started with '::',
91 91 the so-called expanded form. The paragraph
92 92 with '::' disappears in the final output.
93 93 ----------------------------------------------------------------------
94 94
95 95 lists formatted to fit within 60 characters:
96 96 ----------------------------------------------------------------------
97 97 - This is the first list item.
98 98
99 99 Second paragraph in the first list item.
100 100
101 101 - List items need not be separated by a blank line.
102 102 - And will be rendered without one in any case.
103 103
104 104 We can have indented lists:
105 105
106 106 - This is an indented list item
107 107 - Another indented list item:
108 108
109 109 - A literal block in the middle
110 110 of an indented list.
111 111
112 112 (The above is not a list item since we are in the literal block.)
113 113
114 114 Literal block with no indentation (apart from
115 115 the two spaces added to all literal blocks).
116 116
117 117 1. This is an enumerated list (first item).
118 118 2. Continuing with the second item.
119 119 (1) foo
120 120 (2) bar
121 121 1) Another
122 122 2) List
123 123 ----------------------------------------------------------------------
124 124
125 125 lists formatted to fit within 30 characters:
126 126 ----------------------------------------------------------------------
127 127 - This is the first list item.
128 128
129 129 Second paragraph in the
130 130 first list item.
131 131
132 132 - List items need not be
133 133 separated by a blank line.
134 134 - And will be rendered without
135 135 one in any case.
136 136
137 137 We can have indented lists:
138 138
139 139 - This is an indented list
140 140 item
141 141 - Another indented list
142 142 item:
143 143
144 144 - A literal block in the middle
145 145 of an indented list.
146 146
147 147 (The above is not a list item since we are in the literal block.)
148 148
149 149 Literal block with no indentation (apart from
150 150 the two spaces added to all literal blocks).
151 151
152 152 1. This is an enumerated list
153 153 (first item).
154 154 2. Continuing with the second
155 155 item.
156 156 (1) foo
157 157 (2) bar
158 158 1) Another
159 159 2) List
160 160 ----------------------------------------------------------------------
161 161
162 162 options formatted to fit within 60 characters:
163 163 ----------------------------------------------------------------------
164 164 There is support for simple option lists, but only with long
165 165 options:
166 166
167 167 --all Output all.
168 168 --both Output both (this description is quite long).
169 169 --long Output all day long.
170 170 --par This option has two paragraphs in its
171 171 description. This is the first.
172 172
173 173 This is the second. Blank lines may be omitted
174 174 between options (as above) or left in (as here).
175 175
176 176 The next paragraph looks like an option list, but lacks the
177 177 two-space marker after the option. It is treated as a normal
178 178 paragraph:
179 179
180 180 --foo bar baz
181 181 ----------------------------------------------------------------------
182 182
183 183 options formatted to fit within 30 characters:
184 184 ----------------------------------------------------------------------
185 185 There is support for simple
186 186 option lists, but only with
187 187 long options:
188 188
189 189 --all Output all.
190 190 --both Output both (this
191 191 description is
192 192 quite long).
193 193 --long Output all day
194 194 long.
195 195 --par This option has two
196 196 paragraphs in its
197 197 description. This
198 198 is the first.
199 199
200 200 This is the second.
201 201 Blank lines may be
202 202 omitted between
203 203 options (as above)
204 204 or left in (as
205 205 here).
206 206
207 207 The next paragraph looks like
208 208 an option list, but lacks the
209 209 two-space marker after the
210 210 option. It is treated as a
211 211 normal paragraph:
212 212
213 213 --foo bar baz
214 214 ----------------------------------------------------------------------
215 215
216 216 fields formatted to fit within 60 characters:
217 217 ----------------------------------------------------------------------
218 218 a First item.
219 219 ab Second item. Indentation and wrapping is handled
220 220 automatically.
221 221
222 222 Next list:
223 223
224 224 small The larger key below triggers full indentation
225 225 here.
226 226 much too large
227 227 This key is big enough to get its own line.
228 228 ----------------------------------------------------------------------
229 229
230 230 fields formatted to fit within 30 characters:
231 231 ----------------------------------------------------------------------
232 232 a First item.
233 233 ab Second item. Indentation
234 234 and wrapping is handled
235 235 automatically.
236 236
237 237 Next list:
238 238
239 239 small The larger key
240 240 below triggers
241 241 full indentation
242 242 here.
243 243 much too large
244 244 This key is big
245 245 enough to get its
246 246 own line.
247 247 ----------------------------------------------------------------------
248 248
249 249 containers (normal) formatted to fit within 60 characters:
250 250 ----------------------------------------------------------------------
251 251 Normal output.
252 252 ----------------------------------------------------------------------
253 253
254 254 containers (verbose) formatted to fit within 60 characters:
255 255 ----------------------------------------------------------------------
256 256 Normal output.
257 257
258 258 Verbose output.
259 259 ----------------------------------------------------------------------
260 ['debug', 'debug']
261 ----------------------------------------------------------------------
260 262
261 263 containers (debug) formatted to fit within 60 characters:
262 264 ----------------------------------------------------------------------
263 265 Normal output.
264 266
265 267 Initial debug output.
266 268 ----------------------------------------------------------------------
269 ['verbose']
270 ----------------------------------------------------------------------
267 271
268 272 containers (verbose debug) formatted to fit within 60 characters:
269 273 ----------------------------------------------------------------------
270 274 Normal output.
271 275
272 276 Initial debug output.
273 277
274 278 Verbose output.
275 279
276 280 Debug output.
277 281 ----------------------------------------------------------------------
282 []
283 ----------------------------------------------------------------------
278 284
General Comments 0
You need to be logged in to leave comments. Login now