# -*- coding: iso-8859-1 -*-
"""
    MoinMoin - YAML (yaml.org) Parser

    @copyright: 2008 MoinMoin:ThomasWaldmann
    @license: GNU GPL, see COPYING for details.
"""
# Notes:
#
# yaml could maybe used like the wiki parser, calling the formatter to render
# an output page.
#
# groups/dicts/lists - once stored into the cache, can be used by a backend
#
# defining navi_bar or sidebar with yaml?
#
# entering any sort of structured data, displaying it by some renderer action/macro
#  including metadata as long we have no new storage backend
#  indexing metadata with xapian

Dependencies = []

from MoinMoin import caching

class Parser:
    """
        Parse YAML source and write data to cache.
	Rendering supports different modes:
	* no output (if you just want the data in the cache)
	* showing YAML src
        * pprint cache content
    """

    extensions = '.yaml'
    Dependencies = Dependencies

    def __init__(self, raw, request, **kw):
        self.raw = raw
        self.request = request
        self.mode = kw.get('format_args', 'raw').strip()

    def _load_data(self, pagename):
        cache = caching.CacheEntry(self.request, 'yaml', pagename, scope='wiki', use_pickle=True)
        try:
            raw, data = cache.content()
        except:
            raw = data = None
        if raw != self.raw:
            try:
                import yaml
            except ImportError, err:
                return None, str(err)
            try:
                data = yaml.safe_load_all(self.raw)
                data = list(data)  # get rid of generator
                cache.update((self.raw, data))
            except yaml.parser.ParserError, err:
                return None, str(err)
        return data, None

    def format(self, formatter):
        """ Send the text. """
        request = self.request
        output = []
	error_msg = ''
        pagename = formatter.page.page_name
        data, error_msg = self._load_data(pagename)
	if error_msg:
            self.mode = 'raw'

        if self.mode == 'raw':
            output.append(formatter.preformatted(1))
            if error_msg:
                output.append(formatter.text(error_msg + '\n'))
            output.append(formatter.text(self.raw.expandtabs()))
            output.append(formatter.preformatted(0))

        elif self.mode == 'pprint':
            import pprint, StringIO
            output.append(formatter.preformatted(1))
            if error_msg:
                output.append(formatter.text(error_msg))
            outstream = StringIO.StringIO()
            pprint.pprint(data, stream=outstream)
            output.append(formatter.text("yaml cache content pretty-printed:\n"))
            output.append(formatter.text(outstream.getvalue()))
            output.append(formatter.preformatted(0))

        elif self.mode == 'group':
            output.append(formatter.bullet_list(1))
            for item in data[0]:
                output.append(formatter.listitem(1))
                output.append(formatter.text(unicode(item)))
                output.append(formatter.listitem(0))
            output.append(formatter.bullet_list(0))

        elif self.mode == 'dict':
            output.append(formatter.definition_list(1))
            for key, value in data[0].items():
                output.append(formatter.definition_term(1))
                output.append(formatter.text(unicode(key)))
                output.append(formatter.definition_term(0))
                output.append(formatter.definition_desc(1))
                output.append(formatter.text(unicode(value)))
                output.append(formatter.definition_desc(0))
            output.append(formatter.definition_list(0))

        request.write(u''.join(output))

