"""
MoinMoin section parser
=======================

The parser is used to treat content as a page within a page. The section
have a header and a body, using the same format as moin regular
page. Only some of the headers are supported of course.

supported headers
-----------------
#format - any moin parser name
#class - any class name. The rendered class will be section-value
#language - any language known to moin

Bugs
----

'pragma section-number' is not supported as enabling this in the section
cause section number to display in the page. To fix this request state
or maybe formatter state should be saved before rendering the section
and then resotored.

Other headers are ignored.


@copyright: 2005 by Nir Soffer <nirs@freeshell.org>
@license: GNU GPL, see COPYING for details.
"""

import re
from MoinMoin import wikiutil, i18n

# This module is not part of MoinMoin currently, need to install this
from MoinMoin.util.header import Header


class SectionHeader(Header):
    """ Customization for sections headers """
    def set_class(self, value):
        """ Save multiple values for class """
        try:
            self._headers['class'].append(value)
        except KeyError:
            self._headers['class'] = [value]


class SectionParser:

    # One can use inline:sidebar.section to insert a section from an
    # attachment.
    extensions = ['.section']
    
    # allow caching
    caching = 1
    Dependencies = []

    baseClass = 'section'
    
    def __init__(self, text, request, **keywords):
        self.text = text
        self.request = request
        self.keyswords = keywords

    def format(self, formatter):
        """ Formatter the text inside classed div """
        self.formatter = formatter
        usingDefaultFormatter = self.request.page.default_formatter
        self.header = SectionHeader(self.request, self.text)
        savedLanguage = self.request.content_lang
        self.request.setContentLanguage(self.sectionLanguage())
        if usingDefaultFormatter:
            self.request.write(self.section(1, **self.attributes()))       
        Parser = self.importParser(self.sectionFormat())
        parser = Parser(self.text[self.header.length():], self.request)
        parser.format(formatter)        
        if usingDefaultFormatter:
            self.request.write(self.section(0))        
        self.request.setContentLanguage(savedLanguage)

    # ------------------------------------------------------------------
    # Private

    def section(self, on, **attributes):
        """ The missing section method in the formatter """
        tag = 'div'
        if on:
            return self.formatter.open(tag, attr=attributes)
        return self.formatter.close(tag)

    def attributes(self):
        """ Create attribute dict
        
        Currently use only #class header, override to customize. we can
        add here #style for direct css control in page.
        """
        return {'class': self.sectionClass()}

    def sectionClass(self):
        """ Return class list starting with base class """
        classes = [self.baseClass] + self.header.get('class', [])
        return ' '.join(classes)

    def sectionFormat(self):
        format = self.header.get('format', 'wiki')
        if format == 'section':
            format = 'wiki'
        return format

    def sectionLanguage(self):
        language = self.header.get('language',
                                   self.request.content_lang)
        return language
    
    # This stuff is also needed by SlideShow, so it should not be part
    # of action or parser code. Seems that this should be part of
    # wikiutil, or maybe in some plugin module.

    def importParser(self, name):
        Parser = wikiutil.importPlugin(self.request.cfg, 'parser', name,
                                       'Parser')
        if Parser is None:
            return self.defaultParser()
        return Parser

    def defaultParser(self):
        from MoinMoin.parser.plain import Parser
        return Parser


Parser = SectionParser