Logo Search packages:      
Sourcecode: zine version File versions  Download package

parsers.py

# -*- coding: utf-8 -*-
"""
    zine.parsers
    ~~~~~~~~~~~~

    This module holds the base parser informations and the dict of
    default parsers.

    :copyright: (c) 2009 by the Zine Team, see AUTHORS for more details.
    :license: BSD, see LICENSE for more details.
"""
from werkzeug import escape

from zine.i18n import lazy_gettext
from zine.application import iter_listeners, get_application
from zine.utils.zeml import parse_html, parse_zeml, sanitize, Element, \
     RootElement
from zine.utils.xml import replace_entities


def parse(input_data, parser=None, reason='unknown'):
    """Generate a doc tree out of the data provided.  If we are not in unbound
    mode the `process-doc-tree` event is sent so that plugins can modify
    the tree in place. The reason is useful for plugins to find out if they
    want to render it or now. For example a normal blog post would have the
    reason 'post-body' or 'post-intro', an isolated page from a plugin maybe
    'page' etc.
    """
    input_data = u'\n'.join(input_data.splitlines())
    app = get_application()
    if parser is None:
        try:
            parser = app.parsers[app.cfg['default_parser']]
        except KeyError:
            # the plugin that provided the default parser is not
            # longer available.  reset the config value to the builtin
            # parser and parse afterwards.
            t = app.cfg.edit()
            t.revert_to_default('default_parser')
            t.commit()
            parser = app.parsers[app.cfg['default_parser']]
    else:
        try:
            parser = app.parsers[parser]
        except KeyError:
            raise ValueError('parser %r does not exist' % (parser,))

    tree = parser.parse(input_data, reason)

    #! allow plugins to alter the doctree.
    for callback in iter_listeners('process-doc-tree'):
        item = callback(tree, input_data, reason)
        if item is not None:
            tree = item

    return tree


00059 class BaseParser(object):
    """Baseclass for all kinds of parsers."""

    #: the localized name of the parser.
    name = None

    def __init__(self, app):
        self.app = app

00068     def parse(self, input_data, reason):
        """Return a ZEML tree."""


00072 class ZEMLParser(BaseParser):
    """The parser for the ZEML Markup language."""

    name = lazy_gettext('Zine-Markup')

00077     def parse(self, input_data, reason):
        rv = parse_zeml(input_data, self.app.zeml_element_handlers)
        if reason == 'comment':
            rv = sanitize(rv)
        return rv


00084 class HTMLParser(BaseParser):
    """A parser that understands plain old HTML."""

    name = lazy_gettext('HTML')

00089     def parse(self, input_data, reason):
        rv = parse_html(input_data)
        if reason == 'comment':
            rv = sanitize(rv)
        return rv


00096 class PlainTextParser(BaseParser):
    """Parses simple text into a ZEML tree by utilizing pottymouth."""

    name = lazy_gettext('Text')

00101     def _to_text(self, token):
        """Convert a token to normal text."""
        return replace_entities(unicode(token))

00105     def _to_zeml(self, node):
        """Convert a potty-mouth node into a ZEML tree."""
        from zine._ext.pottymouth import Token
        def convert(node, is_root):
            if is_root:
                result = RootElement()
            else:
                result = Element(node.name)
            if node._attributes:
                result.attributes.update(node._attributes)
            for item in node:
                if isinstance(item, (str, unicode, Token)):
                    text = self._to_text(item)
                    if result.children:
                        result.children[-1].tail += text
                    else:
                        result.text += text
                else:
                    result.children.append(convert(item, False))
            return result
        return convert(node, True)

00127     def parse(self, input_data, reason):
        from zine._ext.pottymouth import PottyMouth
        parser = PottyMouth(emdash=False, ellipsis=False, smart_quotes=False,
                            youtube=False, image=False, italic=False)
        node = parser.parse(input_data)
        return self._to_zeml(node)


all_parsers = {
    'zeml':             ZEMLParser,
    'html':             HTMLParser,
    'text':             PlainTextParser
}

Generated by  Doxygen 1.6.0   Back to index