25
standard_include_path = os.path.join(os.path.dirname(states.__file__),
24
28
def include(name, arguments, options, content, lineno,
25
29
content_offset, block_text, state, state_machine):
26
30
"""Include a reST file as part of the content of this reST file."""
31
if not state.document.settings.file_insertion_enabled:
32
warning = state_machine.reporter.warning(
33
'"%s" directive disabled.' % name,
34
nodes.literal_block(block_text, block_text), line=lineno)
27
36
source = state_machine.input_lines.source(
28
37
lineno - state_machine.input_offset - 1)
29
38
source_dir = os.path.dirname(os.path.abspath(source))
30
path = ''.join(arguments[0].splitlines())
31
if path.find(' ') != -1:
32
error = state_machine.reporter.error(
33
'"%s" directive path contains whitespace.' % name,
34
nodes.literal_block(block_text, block_text), line=lineno)
39
path = directives.path(arguments[0])
40
if path.startswith('<') and path.endswith('>'):
41
path = os.path.join(standard_include_path, path[1:-1])
36
42
path = os.path.normpath(os.path.join(source_dir, path))
37
43
path = utils.relative_path(None, path)
44
encoding = options.get('encoding', state.document.settings.input_encoding)
46
state.document.settings.record_dependencies.add(path)
39
47
include_file = io.FileInput(
40
source_path=path, encoding=state.document.settings.input_encoding,
48
source_path=path, encoding=encoding,
49
error_handler=state.document.settings.input_encoding_error_handler,
41
50
handle_io_errors=None)
42
51
except IOError, error:
43
52
severe = state_machine.reporter.severe(
45
54
% (name, error.__class__.__name__, error),
46
55
nodes.literal_block(block_text, block_text), line=lineno)
48
include_text = include_file.read()
58
include_text = include_file.read()
59
except UnicodeError, error:
60
severe = state_machine.reporter.severe(
61
'Problem with "%s" directive:\n%s: %s'
62
% (name, error.__class__.__name__, error),
63
nodes.literal_block(block_text, block_text), line=lineno)
49
65
if options.has_key('literal'):
50
66
literal_block = nodes.literal_block(include_text, include_text,
70
87
Content may be included inline (content section of directive) or
71
88
imported from a file or url.
73
attributes = {'format': arguments[0]}
90
if ( not state.document.settings.raw_enabled
91
or (not state.document.settings.file_insertion_enabled
92
and (options.has_key('file') or options.has_key('url'))) ):
93
warning = state_machine.reporter.warning(
94
'"%s" directive disabled.' % name,
95
nodes.literal_block(block_text, block_text), line=lineno)
97
attributes = {'format': ' '.join(arguments[0].lower().split())}
98
encoding = options.get('encoding', state.document.settings.input_encoding)
75
100
if options.has_key('file') or options.has_key('url'):
76
101
error = state_machine.reporter.error(
91
116
path = os.path.normpath(os.path.join(source_dir, options['file']))
92
117
path = utils.relative_path(None, path)
119
state.document.settings.record_dependencies.add(path)
120
raw_file = io.FileInput(
121
source_path=path, encoding=encoding,
122
error_handler=state.document.settings.input_encoding_error_handler,
123
handle_io_errors=None)
95
124
except IOError, error:
96
125
severe = state_machine.reporter.severe(
97
126
'Problems with "%s" directive path:\n%s.' % (name, error),
98
127
nodes.literal_block(block_text, block_text), line=lineno)
100
text = raw_file.read()
130
text = raw_file.read()
131
except UnicodeError, error:
132
severe = state_machine.reporter.severe(
133
'Problem with "%s" directive:\n%s: %s'
134
% (name, error.__class__.__name__, error),
135
nodes.literal_block(block_text, block_text), line=lineno)
102
137
attributes['source'] = path
103
138
elif options.has_key('url'):
108
143
'"urllib2" module).' % name,
109
144
nodes.literal_block(block_text, block_text), line=lineno)
146
source = options['url']
112
raw_file = urllib2.urlopen(options['url'])
148
raw_text = urllib2.urlopen(source).read()
113
149
except (urllib2.URLError, IOError, OSError), error:
114
150
severe = state_machine.reporter.severe(
115
151
'Problems with "%s" directive URL "%s":\n%s.'
116
152
% (name, options['url'], error),
117
153
nodes.literal_block(block_text, block_text), line=lineno)
119
text = raw_file.read()
121
attributes['source'] = options['file']
155
raw_file = io.StringInput(
156
source=raw_text, source_path=source, encoding=encoding,
157
error_handler=state.document.settings.input_encoding_error_handler)
159
text = raw_file.read()
160
except UnicodeError, error:
161
severe = state_machine.reporter.severe(
162
'Problem with "%s" directive:\n%s: %s'
163
% (name, error.__class__.__name__, error),
164
nodes.literal_block(block_text, block_text), line=lineno)
166
attributes['source'] = source
123
168
error = state_machine.reporter.warning(
124
169
'The "%s" directive requires content; none supplied.' % (name),
167
212
replace.content = 1
169
214
def unicode_directive(name, arguments, options, content, lineno,
170
content_offset, block_text, state, state_machine):
215
content_offset, block_text, state, state_machine):
172
217
Convert Unicode character codes (numbers) to characters. Codes may be
173
218
decimal numbers, hexadecimal numbers (prefixed by ``0x``, ``x``, ``\x``,
181
226
'substitution definition.' % (name),
182
227
nodes.literal_block(block_text, block_text), line=lineno)
229
substitution_definition = state_machine.node
230
if options.has_key('trim'):
231
substitution_definition.attributes['ltrim'] = 1
232
substitution_definition.attributes['rtrim'] = 1
233
if options.has_key('ltrim'):
234
substitution_definition.attributes['ltrim'] = 1
235
if options.has_key('rtrim'):
236
substitution_definition.attributes['rtrim'] = 1
184
237
codes = unicode_comment_pattern.split(arguments[0])[0].split()
185
238
element = nodes.Element()
186
239
for code in codes:
189
element += nodes.Text(unichr(int(code)))
191
match = unicode_pattern.match(code)
193
value = match.group(1) or match.group(2)
194
element += nodes.Text(unichr(int(value, 16)))
196
element += nodes.Text(code)
197
except (ValueError, OverflowError), err:
241
decoded = directives.unicode_code(code)
242
except ValueError, err:
198
243
error = state_machine.reporter.error(
199
244
'Invalid character code: %s\n%s: %s'
200
245
% (code, err.__class__.__name__, err),
201
246
nodes.literal_block(block_text, block_text), line=lineno)
248
element += nodes.Text(decoded)
203
249
return element.children
205
251
unicode_directive.arguments = (1, 0, 1)
206
unicode_pattern = re.compile(
207
r'(?:0x|x|\\x|U\+?|\\u)([0-9a-f]+)$|&#x([0-9a-f]+);$', re.IGNORECASE)
208
unicode_comment_pattern = re.compile(r'( |\n|^).. ')
252
unicode_directive.options = {'trim': directives.flag,
253
'ltrim': directives.flag,
254
'rtrim': directives.flag}
255
unicode_comment_pattern = re.compile(r'( |\n|^)\.\. ')
211
257
def class_directive(name, arguments, options, content, lineno,
212
258
content_offset, block_text, state, state_machine):
214
class_value = nodes.make_id(arguments[0])
260
Set a "class" attribute on the directive content or the next element.
261
When applied to the next element, a "pending" element is inserted, and a
262
transform does the work later.
265
class_value = directives.class_option(arguments[0])
267
error = state_machine.reporter.error(
268
'Invalid class attribute value for "%s" directive: "%s".'
269
% (name, arguments[0]),
270
nodes.literal_block(block_text, block_text), line=lineno)
274
container = nodes.Element()
275
state.nested_parse(content, content_offset, container)
276
for node in container:
277
node['classes'].extend(class_value)
278
node_list.extend(container.children)
216
280
pending = nodes.pending(misc.ClassAttribute,
217
281
{'class': class_value, 'directive': name},
219
283
state_machine.document.note_pending(pending)
222
error = state_machine.reporter.error(
223
'Invalid class attribute value for "%s" directive: "%s".'
224
% (name, arguments[0]),
225
nodes.literal_block(block_text, block_text), line=lineno)
284
node_list.append(pending)
228
class_directive.arguments = (1, 0, 0)
287
class_directive.arguments = (1, 0, 1)
229
288
class_directive.content = 1
231
290
role_arg_pat = re.compile(r'(%s)\s*(\(\s*(%s)\s*\)\s*)?$'
348
def default_role(name, arguments, options, content, lineno,
349
content_offset, block_text, state, state_machine):
350
"""Set the default interpreted text role."""
352
if roles._roles.has_key(''):
353
# restore the "default" default role
356
role_name = arguments[0]
357
role, messages = roles.role(
358
role_name, state_machine.language, lineno, state.reporter)
360
error = state.reporter.error(
361
'Unknown interpreted text role "%s".' % role_name,
362
nodes.literal_block(block_text, block_text), line=lineno)
363
return messages + [error]
364
roles._roles[''] = role
365
# @@@ should this be local to the document, not the parser?
368
default_role.arguments = (0, 1, 0)
370
def title(name, arguments, options, content, lineno,
371
content_offset, block_text, state, state_machine):
372
state_machine.document['title'] = arguments[0]
375
title.arguments = (1, 0, 1)
377
def date(name, arguments, options, content, lineno,
378
content_offset, block_text, state, state_machine):
379
if not isinstance(state, states.SubstitutionDef):
380
error = state_machine.reporter.error(
381
'Invalid context: the "%s" directive can only be used within a '
382
'substitution definition.' % (name),
383
nodes.literal_block(block_text, block_text), line=lineno)
385
format = '\n'.join(content) or '%Y-%m-%d'
386
text = time.strftime(format)
387
return [nodes.Text(text)]
289
391
def directive_test_function(name, arguments, options, content, lineno,
290
392
content_offset, block_text, state, state_machine):
291
393
"""This directive is useful only for testing purposes."""