# Author: David Goodger
# Contact: goodger@python.org
# Revision: $Revision: 3963 $
# Date: $Date: 2005-10-28 18:12:56 +0200 (Fri, 28 Oct 2005) $
# 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 directives
from docutils.parsers.rst.roles import set_classes

              
def topic(name, arguments, options, content, lineno,
          content_offset, block_text, state, state_machine,
          node_class=nodes.topic):
    if not (state_machine.match_titles
            or isinstance(state_machine.node, nodes.sidebar)):
        error = state_machine.reporter.error(
              'The "%s" directive may not be used within topics '
              'or body elements.' % name,
              nodes.literal_block(block_text, block_text), line=lineno)
        return [error]
    if not content:
        warning = state_machine.reporter.warning(
            'Content block expected for the "%s" directive; none found.'
            % name, nodes.literal_block(block_text, block_text),
            line=lineno)
        return [warning]
    title_text = arguments[0]
    textnodes, messages = state.inline_text(title_text, lineno)
    titles = [nodes.title(title_text, '', *textnodes)]
    # sidebar uses this code
    if options.has_key('subtitle'):
        textnodes, more_messages = state.inline_text(options['subtitle'],
                                                     lineno)
        titles.append(nodes.subtitle(options['subtitle'], '', *textnodes))
        messages.extend(more_messages)
    text = '\n'.join(content)
    node = node_class(text, *(titles + messages))
    node['classes'] += options.get('class', [])
    if text:
        state.nested_parse(content, content_offset, node)
    return [node]

topic.arguments = (1, 0, 1)
topic.options = {'class': directives.class_option}
topic.content = 1

def sidebar(name, arguments, options, content, lineno,
            content_offset, block_text, state, state_machine):
    if isinstance(state_machine.node, nodes.sidebar):
        error = state_machine.reporter.error(
              'The "%s" directive may not be used within a sidebar element.'
              % name, nodes.literal_block(block_text, block_text), line=lineno)
        return [error]
    return topic(name, arguments, options, content, lineno,
                 content_offset, block_text, state, state_machine,
                 node_class=nodes.sidebar)

sidebar.arguments = (1, 0, 1)
sidebar.options = {'subtitle': directives.unchanged_required,
                   'class': directives.class_option}
sidebar.content = 1

def line_block(name, arguments, options, content, lineno,
               content_offset, block_text, state, state_machine):
    if not content:
        warning = state_machine.reporter.warning(
            'Content block expected for the "%s" directive; none found.'
            % name, nodes.literal_block(block_text, block_text), line=lineno)
        return [warning]
    block = nodes.line_block(classes=options.get('class', []))
    node_list = [block]
    for line_text in content:
        text_nodes, messages = state.inline_text(line_text.strip(),
                                                 lineno + 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)
        content_offset += 1
    state.nest_line_block_lines(block)
    return node_list

line_block.options = {'class': directives.class_option}
line_block.content = 1

def parsed_literal(name, arguments, options, content, lineno,
                   content_offset, block_text, state, state_machine):
    set_classes(options)
    return block(name, arguments, options, content, lineno,
                 content_offset, block_text, state, state_machine,
                 node_class=nodes.literal_block)

parsed_literal.options = {'class': directives.class_option}
parsed_literal.content = 1

def block(name, arguments, options, content, lineno,
          content_offset, block_text, state, state_machine, node_class):
    if not content:
        warning = state_machine.reporter.warning(
            'Content block expected for the "%s" directive; none found.'
            % name, nodes.literal_block(block_text, block_text), line=lineno)
        return [warning]
    text = '\n'.join(content)
    text_nodes, messages = state.inline_text(text, lineno)
    node = node_class(text, '', *text_nodes, **options)
    node.line = content_offset + 1
    return [node] + messages

def rubric(name, arguments, options, content, lineno,
             content_offset, block_text, state, state_machine):
    rubric_text = arguments[0]
    textnodes, messages = state.inline_text(rubric_text, lineno)
    rubric = nodes.rubric(rubric_text, '', *textnodes, **options)
    return [rubric] + messages

rubric.arguments = (1, 0, 1)
rubric.options = {'class': directives.class_option}

def epigraph(name, arguments, options, content, lineno,
             content_offset, block_text, state, state_machine):
    block_quote, messages = state.block_quote(content, content_offset)
    block_quote['classes'].append('epigraph')
    return [block_quote] + messages

epigraph.content = 1

def highlights(name, arguments, options, content, lineno,
             content_offset, block_text, state, state_machine):
    block_quote, messages = state.block_quote(content, content_offset)
    block_quote['classes'].append('highlights')
    return [block_quote] + messages

highlights.content = 1

def pull_quote(name, arguments, options, content, lineno,
             content_offset, block_text, state, state_machine):
    block_quote, messages = state.block_quote(content, content_offset)
    block_quote['classes'].append('pull-quote')
    return [block_quote] + messages

pull_quote.content = 1

def compound(name, arguments, options, content, lineno,
             content_offset, block_text, state, state_machine):
    text = '\n'.join(content)
    if not text:
        error = state_machine.reporter.error(
            'The "%s" directive is empty; content required.' % name,
            nodes.literal_block(block_text, block_text), line=lineno)
        return [error]
    node = nodes.compound(text)
    node['classes'] += options.get('class', [])
    state.nested_parse(content, content_offset, node)
    return [node]

compound.options = {'class': directives.class_option}
compound.content = 1

def container(name, arguments, options, content, lineno,
              content_offset, block_text, state, state_machine):
    text = '\n'.join(content)
    if not text:
        error = state_machine.reporter.error(
            'The "%s" directive is empty; content required.' % name,
            nodes.literal_block(block_text, block_text), line=lineno)
        return [error]
    try:
        if arguments:
            classes = directives.class_option(arguments[0])
        else:
            classes = []
    except ValueError:
        error = state_machine.reporter.error(
            'Invalid class attribute value for "%s" directive: "%s".'
            % (name, arguments[0]),
            nodes.literal_block(block_text, block_text), line=lineno)
        return [error]
    node = nodes.container(text)
    node['classes'].extend(classes)
    state.nested_parse(content, content_offset, node)
    return [node]

container.arguments = (0, 1, 1)
container.content = 1
