Mercurial > repos > shellac > sam_consensus_v3
comparison env/lib/python3.9/site-packages/docutils/parsers/rst/directives/body.py @ 0:4f3585e2f14b draft default tip
"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author | shellac |
---|---|
date | Mon, 22 Mar 2021 18:12:50 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4f3585e2f14b |
---|---|
1 # $Id: body.py 8347 2019-08-26 12:12:02Z milde $ | |
2 # Author: David Goodger <goodger@python.org> | |
3 # Copyright: This module has been placed in the public domain. | |
4 | |
5 """ | |
6 Directives for additional body elements. | |
7 | |
8 See `docutils.parsers.rst.directives` for API details. | |
9 """ | |
10 | |
11 __docformat__ = 'reStructuredText' | |
12 | |
13 | |
14 from docutils import nodes | |
15 from docutils.parsers.rst import Directive | |
16 from docutils.parsers.rst import directives | |
17 from docutils.parsers.rst.roles import set_classes | |
18 from docutils.utils.code_analyzer import Lexer, LexerError, NumberLines | |
19 | |
20 | |
21 class BasePseudoSection(Directive): | |
22 | |
23 required_arguments = 1 | |
24 optional_arguments = 0 | |
25 final_argument_whitespace = True | |
26 option_spec = {'class': directives.class_option, | |
27 'name': directives.unchanged} | |
28 has_content = True | |
29 | |
30 node_class = None | |
31 """Node class to be used (must be set in subclasses).""" | |
32 | |
33 def run(self): | |
34 if not (self.state_machine.match_titles | |
35 or isinstance(self.state_machine.node, nodes.sidebar)): | |
36 raise self.error('The "%s" directive may not be used within ' | |
37 'topics or body elements.' % self.name) | |
38 self.assert_has_content() | |
39 title_text = self.arguments[0] | |
40 textnodes, messages = self.state.inline_text(title_text, self.lineno) | |
41 titles = [nodes.title(title_text, '', *textnodes)] | |
42 # Sidebar uses this code. | |
43 if 'subtitle' in self.options: | |
44 textnodes, more_messages = self.state.inline_text( | |
45 self.options['subtitle'], self.lineno) | |
46 titles.append(nodes.subtitle(self.options['subtitle'], '', | |
47 *textnodes)) | |
48 messages.extend(more_messages) | |
49 text = '\n'.join(self.content) | |
50 node = self.node_class(text, *(titles + messages)) | |
51 node['classes'] += self.options.get('class', []) | |
52 self.add_name(node) | |
53 if text: | |
54 self.state.nested_parse(self.content, self.content_offset, node) | |
55 return [node] | |
56 | |
57 | |
58 class Topic(BasePseudoSection): | |
59 | |
60 node_class = nodes.topic | |
61 | |
62 | |
63 class Sidebar(BasePseudoSection): | |
64 | |
65 node_class = nodes.sidebar | |
66 | |
67 option_spec = BasePseudoSection.option_spec.copy() | |
68 option_spec['subtitle'] = directives.unchanged_required | |
69 | |
70 def run(self): | |
71 if isinstance(self.state_machine.node, nodes.sidebar): | |
72 raise self.error('The "%s" directive may not be used within a ' | |
73 'sidebar element.' % self.name) | |
74 return BasePseudoSection.run(self) | |
75 | |
76 | |
77 class LineBlock(Directive): | |
78 | |
79 option_spec = {'class': directives.class_option, | |
80 'name': directives.unchanged} | |
81 has_content = True | |
82 | |
83 def run(self): | |
84 self.assert_has_content() | |
85 block = nodes.line_block(classes=self.options.get('class', [])) | |
86 self.add_name(block) | |
87 node_list = [block] | |
88 for line_text in self.content: | |
89 text_nodes, messages = self.state.inline_text( | |
90 line_text.strip(), self.lineno + self.content_offset) | |
91 line = nodes.line(line_text, '', *text_nodes) | |
92 if line_text.strip(): | |
93 line.indent = len(line_text) - len(line_text.lstrip()) | |
94 block += line | |
95 node_list.extend(messages) | |
96 self.content_offset += 1 | |
97 self.state.nest_line_block_lines(block) | |
98 return node_list | |
99 | |
100 | |
101 class ParsedLiteral(Directive): | |
102 | |
103 option_spec = {'class': directives.class_option, | |
104 'name': directives.unchanged} | |
105 has_content = True | |
106 | |
107 def run(self): | |
108 set_classes(self.options) | |
109 self.assert_has_content() | |
110 text = '\n'.join(self.content) | |
111 text_nodes, messages = self.state.inline_text(text, self.lineno) | |
112 node = nodes.literal_block(text, '', *text_nodes, **self.options) | |
113 node.line = self.content_offset + 1 | |
114 self.add_name(node) | |
115 return [node] + messages | |
116 | |
117 | |
118 class CodeBlock(Directive): | |
119 """Parse and mark up content of a code block. | |
120 | |
121 Configuration setting: syntax_highlight | |
122 Highlight Code content with Pygments? | |
123 Possible values: ('long', 'short', 'none') | |
124 | |
125 """ | |
126 optional_arguments = 1 | |
127 option_spec = {'class': directives.class_option, | |
128 'name': directives.unchanged, | |
129 'number-lines': directives.unchanged # integer or None | |
130 } | |
131 has_content = True | |
132 | |
133 def run(self): | |
134 self.assert_has_content() | |
135 if self.arguments: | |
136 language = self.arguments[0] | |
137 else: | |
138 language = '' | |
139 set_classes(self.options) | |
140 classes = ['code'] | |
141 if language: | |
142 classes.append(language) | |
143 if 'classes' in self.options: | |
144 classes.extend(self.options['classes']) | |
145 | |
146 # set up lexical analyzer | |
147 try: | |
148 tokens = Lexer(u'\n'.join(self.content), language, | |
149 self.state.document.settings.syntax_highlight) | |
150 except LexerError as error: | |
151 raise self.warning(error) | |
152 | |
153 if 'number-lines' in self.options: | |
154 # optional argument `startline`, defaults to 1 | |
155 try: | |
156 startline = int(self.options['number-lines'] or 1) | |
157 except ValueError: | |
158 raise self.error(':number-lines: with non-integer start value') | |
159 endline = startline + len(self.content) | |
160 # add linenumber filter: | |
161 tokens = NumberLines(tokens, startline, endline) | |
162 | |
163 node = nodes.literal_block('\n'.join(self.content), classes=classes) | |
164 self.add_name(node) | |
165 # if called from "include", set the source | |
166 if 'source' in self.options: | |
167 node.attributes['source'] = self.options['source'] | |
168 # analyze content and add nodes for every token | |
169 for classes, value in tokens: | |
170 if classes: | |
171 node += nodes.inline(value, value, classes=classes) | |
172 else: | |
173 # insert as Text to decrease the verbosity of the output | |
174 node += nodes.Text(value) | |
175 | |
176 return [node] | |
177 | |
178 | |
179 class MathBlock(Directive): | |
180 | |
181 option_spec = {'class': directives.class_option, | |
182 'name': directives.unchanged} | |
183 ## TODO: Add Sphinx' ``mathbase.py`` option 'nowrap'? | |
184 # 'nowrap': directives.flag, | |
185 has_content = True | |
186 | |
187 def run(self): | |
188 set_classes(self.options) | |
189 self.assert_has_content() | |
190 # join lines, separate blocks | |
191 content = '\n'.join(self.content).split('\n\n') | |
192 _nodes = [] | |
193 for block in content: | |
194 if not block: | |
195 continue | |
196 node = nodes.math_block(self.block_text, block, **self.options) | |
197 node.line = self.content_offset + 1 | |
198 self.add_name(node) | |
199 _nodes.append(node) | |
200 return _nodes | |
201 | |
202 | |
203 class Rubric(Directive): | |
204 | |
205 required_arguments = 1 | |
206 optional_arguments = 0 | |
207 final_argument_whitespace = True | |
208 option_spec = {'class': directives.class_option, | |
209 'name': directives.unchanged} | |
210 | |
211 def run(self): | |
212 set_classes(self.options) | |
213 rubric_text = self.arguments[0] | |
214 textnodes, messages = self.state.inline_text(rubric_text, self.lineno) | |
215 rubric = nodes.rubric(rubric_text, '', *textnodes, **self.options) | |
216 self.add_name(rubric) | |
217 return [rubric] + messages | |
218 | |
219 | |
220 class BlockQuote(Directive): | |
221 | |
222 has_content = True | |
223 classes = [] | |
224 | |
225 def run(self): | |
226 self.assert_has_content() | |
227 elements = self.state.block_quote(self.content, self.content_offset) | |
228 for element in elements: | |
229 if isinstance(element, nodes.block_quote): | |
230 element['classes'] += self.classes | |
231 return elements | |
232 | |
233 | |
234 class Epigraph(BlockQuote): | |
235 | |
236 classes = ['epigraph'] | |
237 | |
238 | |
239 class Highlights(BlockQuote): | |
240 | |
241 classes = ['highlights'] | |
242 | |
243 | |
244 class PullQuote(BlockQuote): | |
245 | |
246 classes = ['pull-quote'] | |
247 | |
248 | |
249 class Compound(Directive): | |
250 | |
251 option_spec = {'class': directives.class_option, | |
252 'name': directives.unchanged} | |
253 has_content = True | |
254 | |
255 def run(self): | |
256 self.assert_has_content() | |
257 text = '\n'.join(self.content) | |
258 node = nodes.compound(text) | |
259 node['classes'] += self.options.get('class', []) | |
260 self.add_name(node) | |
261 self.state.nested_parse(self.content, self.content_offset, node) | |
262 return [node] | |
263 | |
264 | |
265 class Container(Directive): | |
266 | |
267 optional_arguments = 1 | |
268 final_argument_whitespace = True | |
269 option_spec = {'name': directives.unchanged} | |
270 has_content = True | |
271 | |
272 def run(self): | |
273 self.assert_has_content() | |
274 text = '\n'.join(self.content) | |
275 try: | |
276 if self.arguments: | |
277 classes = directives.class_option(self.arguments[0]) | |
278 else: | |
279 classes = [] | |
280 except ValueError: | |
281 raise self.error( | |
282 'Invalid class attribute value for "%s" directive: "%s".' | |
283 % (self.name, self.arguments[0])) | |
284 node = nodes.container(text) | |
285 node['classes'].extend(classes) | |
286 self.add_name(node) | |
287 self.state.nested_parse(self.content, self.content_offset, node) | |
288 return [node] |