1 | # Author: David Goodger |
---|
2 | # Contact: goodger@python.org |
---|
3 | # Revision: $Revision: 3963 $ |
---|
4 | # Date: $Date: 2005-10-28 18:12:56 +0200 (Fri, 28 Oct 2005) $ |
---|
5 | # Copyright: This module has been placed in the public domain. |
---|
6 | |
---|
7 | """ |
---|
8 | Directives for additional body elements. |
---|
9 | |
---|
10 | See `docutils.parsers.rst.directives` for API details. |
---|
11 | """ |
---|
12 | |
---|
13 | __docformat__ = 'reStructuredText' |
---|
14 | |
---|
15 | |
---|
16 | import sys |
---|
17 | from docutils import nodes |
---|
18 | from docutils.parsers.rst import directives |
---|
19 | from docutils.parsers.rst.roles import set_classes |
---|
20 | |
---|
21 | |
---|
22 | def topic(name, arguments, options, content, lineno, |
---|
23 | content_offset, block_text, state, state_machine, |
---|
24 | node_class=nodes.topic): |
---|
25 | if not (state_machine.match_titles |
---|
26 | or isinstance(state_machine.node, nodes.sidebar)): |
---|
27 | error = state_machine.reporter.error( |
---|
28 | 'The "%s" directive may not be used within topics ' |
---|
29 | 'or body elements.' % name, |
---|
30 | nodes.literal_block(block_text, block_text), line=lineno) |
---|
31 | return [error] |
---|
32 | if not content: |
---|
33 | warning = state_machine.reporter.warning( |
---|
34 | 'Content block expected for the "%s" directive; none found.' |
---|
35 | % name, nodes.literal_block(block_text, block_text), |
---|
36 | line=lineno) |
---|
37 | return [warning] |
---|
38 | title_text = arguments[0] |
---|
39 | textnodes, messages = state.inline_text(title_text, lineno) |
---|
40 | titles = [nodes.title(title_text, '', *textnodes)] |
---|
41 | # sidebar uses this code |
---|
42 | if options.has_key('subtitle'): |
---|
43 | textnodes, more_messages = state.inline_text(options['subtitle'], |
---|
44 | lineno) |
---|
45 | titles.append(nodes.subtitle(options['subtitle'], '', *textnodes)) |
---|
46 | messages.extend(more_messages) |
---|
47 | text = '\n'.join(content) |
---|
48 | node = node_class(text, *(titles + messages)) |
---|
49 | node['classes'] += options.get('class', []) |
---|
50 | if text: |
---|
51 | state.nested_parse(content, content_offset, node) |
---|
52 | return [node] |
---|
53 | |
---|
54 | topic.arguments = (1, 0, 1) |
---|
55 | topic.options = {'class': directives.class_option} |
---|
56 | topic.content = 1 |
---|
57 | |
---|
58 | def sidebar(name, arguments, options, content, lineno, |
---|
59 | content_offset, block_text, state, state_machine): |
---|
60 | if isinstance(state_machine.node, nodes.sidebar): |
---|
61 | error = state_machine.reporter.error( |
---|
62 | 'The "%s" directive may not be used within a sidebar element.' |
---|
63 | % name, nodes.literal_block(block_text, block_text), line=lineno) |
---|
64 | return [error] |
---|
65 | return topic(name, arguments, options, content, lineno, |
---|
66 | content_offset, block_text, state, state_machine, |
---|
67 | node_class=nodes.sidebar) |
---|
68 | |
---|
69 | sidebar.arguments = (1, 0, 1) |
---|
70 | sidebar.options = {'subtitle': directives.unchanged_required, |
---|
71 | 'class': directives.class_option} |
---|
72 | sidebar.content = 1 |
---|
73 | |
---|
74 | def line_block(name, arguments, options, content, lineno, |
---|
75 | content_offset, block_text, state, state_machine): |
---|
76 | if not content: |
---|
77 | warning = state_machine.reporter.warning( |
---|
78 | 'Content block expected for the "%s" directive; none found.' |
---|
79 | % name, nodes.literal_block(block_text, block_text), line=lineno) |
---|
80 | return [warning] |
---|
81 | block = nodes.line_block(classes=options.get('class', [])) |
---|
82 | node_list = [block] |
---|
83 | for line_text in content: |
---|
84 | text_nodes, messages = state.inline_text(line_text.strip(), |
---|
85 | lineno + content_offset) |
---|
86 | line = nodes.line(line_text, '', *text_nodes) |
---|
87 | if line_text.strip(): |
---|
88 | line.indent = len(line_text) - len(line_text.lstrip()) |
---|
89 | block += line |
---|
90 | node_list.extend(messages) |
---|
91 | content_offset += 1 |
---|
92 | state.nest_line_block_lines(block) |
---|
93 | return node_list |
---|
94 | |
---|
95 | line_block.options = {'class': directives.class_option} |
---|
96 | line_block.content = 1 |
---|
97 | |
---|
98 | def parsed_literal(name, arguments, options, content, lineno, |
---|
99 | content_offset, block_text, state, state_machine): |
---|
100 | set_classes(options) |
---|
101 | return block(name, arguments, options, content, lineno, |
---|
102 | content_offset, block_text, state, state_machine, |
---|
103 | node_class=nodes.literal_block) |
---|
104 | |
---|
105 | parsed_literal.options = {'class': directives.class_option} |
---|
106 | parsed_literal.content = 1 |
---|
107 | |
---|
108 | def block(name, arguments, options, content, lineno, |
---|
109 | content_offset, block_text, state, state_machine, node_class): |
---|
110 | if not content: |
---|
111 | warning = state_machine.reporter.warning( |
---|
112 | 'Content block expected for the "%s" directive; none found.' |
---|
113 | % name, nodes.literal_block(block_text, block_text), line=lineno) |
---|
114 | return [warning] |
---|
115 | text = '\n'.join(content) |
---|
116 | text_nodes, messages = state.inline_text(text, lineno) |
---|
117 | node = node_class(text, '', *text_nodes, **options) |
---|
118 | node.line = content_offset + 1 |
---|
119 | return [node] + messages |
---|
120 | |
---|
121 | def rubric(name, arguments, options, content, lineno, |
---|
122 | content_offset, block_text, state, state_machine): |
---|
123 | rubric_text = arguments[0] |
---|
124 | textnodes, messages = state.inline_text(rubric_text, lineno) |
---|
125 | rubric = nodes.rubric(rubric_text, '', *textnodes, **options) |
---|
126 | return [rubric] + messages |
---|
127 | |
---|
128 | rubric.arguments = (1, 0, 1) |
---|
129 | rubric.options = {'class': directives.class_option} |
---|
130 | |
---|
131 | def epigraph(name, arguments, options, content, lineno, |
---|
132 | content_offset, block_text, state, state_machine): |
---|
133 | block_quote, messages = state.block_quote(content, content_offset) |
---|
134 | block_quote['classes'].append('epigraph') |
---|
135 | return [block_quote] + messages |
---|
136 | |
---|
137 | epigraph.content = 1 |
---|
138 | |
---|
139 | def highlights(name, arguments, options, content, lineno, |
---|
140 | content_offset, block_text, state, state_machine): |
---|
141 | block_quote, messages = state.block_quote(content, content_offset) |
---|
142 | block_quote['classes'].append('highlights') |
---|
143 | return [block_quote] + messages |
---|
144 | |
---|
145 | highlights.content = 1 |
---|
146 | |
---|
147 | def pull_quote(name, arguments, options, content, lineno, |
---|
148 | content_offset, block_text, state, state_machine): |
---|
149 | block_quote, messages = state.block_quote(content, content_offset) |
---|
150 | block_quote['classes'].append('pull-quote') |
---|
151 | return [block_quote] + messages |
---|
152 | |
---|
153 | pull_quote.content = 1 |
---|
154 | |
---|
155 | def compound(name, arguments, options, content, lineno, |
---|
156 | content_offset, block_text, state, state_machine): |
---|
157 | text = '\n'.join(content) |
---|
158 | if not text: |
---|
159 | error = state_machine.reporter.error( |
---|
160 | 'The "%s" directive is empty; content required.' % name, |
---|
161 | nodes.literal_block(block_text, block_text), line=lineno) |
---|
162 | return [error] |
---|
163 | node = nodes.compound(text) |
---|
164 | node['classes'] += options.get('class', []) |
---|
165 | state.nested_parse(content, content_offset, node) |
---|
166 | return [node] |
---|
167 | |
---|
168 | compound.options = {'class': directives.class_option} |
---|
169 | compound.content = 1 |
---|
170 | |
---|
171 | def container(name, arguments, options, content, lineno, |
---|
172 | content_offset, block_text, state, state_machine): |
---|
173 | text = '\n'.join(content) |
---|
174 | if not text: |
---|
175 | error = state_machine.reporter.error( |
---|
176 | 'The "%s" directive is empty; content required.' % name, |
---|
177 | nodes.literal_block(block_text, block_text), line=lineno) |
---|
178 | return [error] |
---|
179 | try: |
---|
180 | if arguments: |
---|
181 | classes = directives.class_option(arguments[0]) |
---|
182 | else: |
---|
183 | classes = [] |
---|
184 | except ValueError: |
---|
185 | error = state_machine.reporter.error( |
---|
186 | 'Invalid class attribute value for "%s" directive: "%s".' |
---|
187 | % (name, arguments[0]), |
---|
188 | nodes.literal_block(block_text, block_text), line=lineno) |
---|
189 | return [error] |
---|
190 | node = nodes.container(text) |
---|
191 | node['classes'].extend(classes) |
---|
192 | state.nested_parse(content, content_offset, node) |
---|
193 | return [node] |
---|
194 | |
---|
195 | container.arguments = (0, 1, 1) |
---|
196 | container.content = 1 |
---|