| # $Id: body.py 5618 2008-07-28 08:37:32Z strank $ |
| # Author: David Goodger <[email protected]> |
| # Copyright: This module has been placed in the public domain. |
| |
| """ |
| Directives for additional body elements. |
| |
| See `docutils.parsers.rst.directives` for API details. |
| """ |
| |
| __docformat__ = 'reStructuredText' |
| |
| |
| import sys |
| from docutils import nodes |
| from docutils.parsers.rst import Directive |
| from docutils.parsers.rst import directives |
| from docutils.parsers.rst.roles import set_classes |
| |
| |
| class BasePseudoSection(Directive): |
| |
| required_arguments = 1 |
| optional_arguments = 0 |
| final_argument_whitespace = True |
| option_spec = {'class': directives.class_option} |
| has_content = True |
| |
| node_class = None |
| """Node class to be used (must be set in subclasses).""" |
| |
| def run(self): |
| if not (self.state_machine.match_titles |
| or isinstance(self.state_machine.node, nodes.sidebar)): |
| raise self.error('The "%s" directive may not be used within ' |
| 'topics or body elements.' % self.name) |
| self.assert_has_content() |
| title_text = self.arguments[0] |
| textnodes, messages = self.state.inline_text(title_text, self.lineno) |
| titles = [nodes.title(title_text, '', *textnodes)] |
| # Sidebar uses this code. |
| if 'subtitle' in self.options: |
| textnodes, more_messages = self.state.inline_text( |
| self.options['subtitle'], self.lineno) |
| titles.append(nodes.subtitle(self.options['subtitle'], '', |
| *textnodes)) |
| messages.extend(more_messages) |
| text = '\n'.join(self.content) |
| node = self.node_class(text, *(titles + messages)) |
| node['classes'] += self.options.get('class', []) |
| if text: |
| self.state.nested_parse(self.content, self.content_offset, node) |
| return [node] |
| |
| |
| class Topic(BasePseudoSection): |
| |
| node_class = nodes.topic |
| |
| |
| class Sidebar(BasePseudoSection): |
| |
| node_class = nodes.sidebar |
| |
| option_spec = BasePseudoSection.option_spec.copy() |
| option_spec['subtitle'] = directives.unchanged_required |
| |
| def run(self): |
| if isinstance(self.state_machine.node, nodes.sidebar): |
| raise self.error('The "%s" directive may not be used within a ' |
| 'sidebar element.' % self.name) |
| return BasePseudoSection.run(self) |
| |
| |
| class LineBlock(Directive): |
| |
| option_spec = {'class': directives.class_option} |
| has_content = True |
| |
| def run(self): |
| self.assert_has_content() |
| block = nodes.line_block(classes=self.options.get('class', [])) |
| node_list = [block] |
| for line_text in self.content: |
| text_nodes, messages = self.state.inline_text( |
| line_text.strip(), self.lineno + self.content_offset) |
| line = nodes.line(line_text, '', *text_nodes) |
| if line_text.strip(): |
| line.indent = len(line_text) - len(line_text.lstrip()) |
| block += line |
| node_list.extend(messages) |
| self.content_offset += 1 |
| self.state.nest_line_block_lines(block) |
| return node_list |
| |
| |
| class ParsedLiteral(Directive): |
| |
| option_spec = {'class': directives.class_option} |
| has_content = True |
| |
| def run(self): |
| set_classes(self.options) |
| self.assert_has_content() |
| text = '\n'.join(self.content) |
| text_nodes, messages = self.state.inline_text(text, self.lineno) |
| node = nodes.literal_block(text, '', *text_nodes, **self.options) |
| node.line = self.content_offset + 1 |
| return [node] + messages |
| |
| |
| class Rubric(Directive): |
| |
| required_arguments = 1 |
| optional_arguments = 0 |
| final_argument_whitespace = True |
| option_spec = {'class': directives.class_option} |
| |
| def run(self): |
| set_classes(self.options) |
| rubric_text = self.arguments[0] |
| textnodes, messages = self.state.inline_text(rubric_text, self.lineno) |
| rubric = nodes.rubric(rubric_text, '', *textnodes, **self.options) |
| return [rubric] + messages |
| |
| |
| class BlockQuote(Directive): |
| |
| has_content = True |
| classes = [] |
| |
| def run(self): |
| self.assert_has_content() |
| elements = self.state.block_quote(self.content, self.content_offset) |
| for element in elements: |
| if isinstance(element, nodes.block_quote): |
| element['classes'] += self.classes |
| return elements |
| |
| |
| class Epigraph(BlockQuote): |
| |
| classes = ['epigraph'] |
| |
| |
| class Highlights(BlockQuote): |
| |
| classes = ['highlights'] |
| |
| |
| class PullQuote(BlockQuote): |
| |
| classes = ['pull-quote'] |
| |
| |
| class Compound(Directive): |
| |
| option_spec = {'class': directives.class_option} |
| has_content = True |
| |
| def run(self): |
| self.assert_has_content() |
| text = '\n'.join(self.content) |
| node = nodes.compound(text) |
| node['classes'] += self.options.get('class', []) |
| self.state.nested_parse(self.content, self.content_offset, node) |
| return [node] |
| |
| |
| class Container(Directive): |
| |
| required_arguments = 0 |
| optional_arguments = 1 |
| final_argument_whitespace = True |
| has_content = True |
| |
| def run(self): |
| self.assert_has_content() |
| text = '\n'.join(self.content) |
| try: |
| if self.arguments: |
| classes = directives.class_option(self.arguments[0]) |
| else: |
| classes = [] |
| except ValueError: |
| raise self.error( |
| 'Invalid class attribute value for "%s" directive: "%s".' |
| % (self.name, self.arguments[0])) |
| node = nodes.container(text) |
| node['classes'].extend(classes) |
| self.state.nested_parse(self.content, self.content_offset, node) |
| return [node] |