root/trunk/pylucid_project/PyLucid/tools/content_processors.py

Revision 1842, 5.8 KB (checked in by JensDiemer, 12 months ago)

creole markup:

  • use all existing macros
  • disable verbosity
  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Rev LastChangedDate
Line 
1# -*- coding: utf-8 -*-
2
3"""
4    PyLucid content processors
5    ~~~~~~~~~~~~~~~~~~~~~~~~~~
6
7    Tools around content:
8
9    - apply a markup to a content
10    - render a django template
11    - redirect warnings
12
13    Last commit info:
14    ~~~~~~~~~
15    $LastChangedDate$
16    $Rev$
17    $Author$
18
19    :copyleft: 2007-2008 by the PyLucid team, see AUTHORS for more details.
20    :license: GNU GPL v3 or above, see LICENSE for more details
21"""
22
23import re
24
25if __name__ == "__main__":
26    # For doctest only
27    import os
28    os.environ["DJANGO_SETTINGS_MODULE"] = "PyLucid.settings"
29
30from django.conf import settings
31from django.template import Template, Context
32from django.utils.safestring import mark_safe
33from django.utils.encoding import smart_str, force_unicode
34
35from PyLucid.system.response import SimpleStringIO
36
37# use the undocumented django function to add the "lucidTag" to the tag library.
38# see ./PyLucid/defaulttags/__init__.py
39from django.template import add_to_builtins
40add_to_builtins('PyLucid.template_addons')
41
42#______________________________________________________________________________
43# MARKUP
44
45BLOCK_RE = re.compile("\n{2,}")
46
47LINK_RE = re.compile(
48    r'''(?<!=")(?P<url>(http|ftp|svn|irc)://(?P<title>[^\s\<]+))(?uimx)'''
49)
50
51def fallback_markup(content):
52    """
53    A simplest markup, build only paragraphs.
54    >>> fallback_markup("line one\\nline two\\n\\nnext block")
55    '<p>line one<br />\\nline two</p>\\n\\n<p>next block</p>'
56
57    >>> fallback_markup("url: http://pylucid.org END")
58    '<p>url: <a href="http://pylucid.org">pylucid.org</a> END</p>'
59    """
60    content = content.replace("\r\n", "\n").replace("\r","\n")
61    blocks = BLOCK_RE.split(content)
62    blocks = [line.replace("\n", "<br />\n") for line in blocks]
63    content = "<p>" + "</p>\n\n<p>".join(blocks) + "</p>"
64    content = LINK_RE.sub(r'<a href="\g<url>">\g<title></a>', content)
65    return content
66
67def apply_tinytextile(content, context):
68    """ tinyTextile markup """
69    from PyLucid.system.markups.tinyTextile import TinyTextileParser
70    out_obj = SimpleStringIO()
71    markup_parser = TinyTextileParser(out_obj, context)
72    markup_parser.parse(content)
73    return out_obj.getvalue()
74
75
76def apply_textile(content, page_msg):
77    """ Original textile markup """
78    try:
79        import textile
80    except ImportError:
81        page_msg(
82            "Markup error: The Python textile library isn't installed."
83            " Download: http://cheeseshop.python.org/pypi/textile"
84        )
85        return fallback_markup(content)
86    else:
87        return force_unicode(textile.textile(
88            smart_str(content),
89            encoding=settings.DEFAULT_CHARSET,
90            output=settings.DEFAULT_CHARSET
91        ))
92
93def apply_markdown(content, page_msg):
94    """ Markdown markup """
95    try:
96        import markdown
97    except ImportError:
98        page_msg(
99            "Markup error: The Python markdown library isn't installed."
100            " Download: http://sourceforge.net/projects/python-markdown/"
101        )
102        return fallback_markup(content)
103    else:
104        # unicode support only in markdown v1.7 or above.
105        # version_info exist only in markdown v1.6.2rc-2 or above.
106        if getattr(markdown, "version_info", None) < (1,7):
107            return force_unicode(markdown.markdown(smart_str(content)))
108        else:
109            return markdown.markdown(content)
110
111
112def apply_restructuretext(content, page_msg):
113    try:
114        from docutils.core import publish_parts
115    except ImportError:
116        page_msg(
117            "Markup error: The Python docutils library isn't installed."
118            " Download: http://docutils.sourceforge.net/"
119        )
120        return fallback_markup(content)
121    else:
122        docutils_settings = getattr(
123            settings, "RESTRUCTUREDTEXT_FILTER_SETTINGS", {}
124        )
125        parts = publish_parts(
126            source=content, writer_name="html4css1",
127            settings_overrides=docutils_settings
128        )
129        return parts["fragment"]
130
131
132
133def apply_creole(content):
134    """
135    Use python-creole:
136    http://code.google.com/p/python-creole/
137   
138    We used verbose=1 for inser error information (e.g. not existing macro)
139    into the generated page
140    """
141    from PyLucid.system.markups import PyLucid_creole_macros
142    from PyLucid.system.markups.creole import Parser
143    from PyLucid.system.markups.creole.creole2html import HtmlEmitter
144   
145    # Create document tree from creole markup
146    document = Parser(content).parse()
147   
148    # Build html code from document tree
149    return HtmlEmitter(document, macros=PyLucid_creole_macros, verbose=0).emit()
150
151from PyLucid.models import Page
152
153
154
155def apply_markup(content, context, markup_no):
156    """
157    Apply to the content the given markup.
158    Makrups IDs defined in
159        ./PyLucid/models.py
160    """
161    request  = context["request"]
162    page_msg = request.page_msg
163
164    if markup_no == Page.MARKUP_TINYTEXTILE: # PyLucid's TinyTextile
165        content = apply_tinytextile(content, context)
166       
167    elif markup_no == Page.MARKUP_TEXTILE: # Textile (original)
168        content = apply_textile(content, page_msg)
169       
170    elif markup_no == Page.MARKUP_MARKDOWN:
171        content = apply_markdown(content, page_msg)
172       
173    elif markup_no == Page.MARKUP_REST:
174        content = apply_restructuretext(content, page_msg)
175       
176    elif markup_no == Page.MARKUP_CREOLE:
177        content = apply_creole(content)
178
179    return mark_safe(content) # turn djngo auto-escaping off
180
181
182#______________________________________________________________________________
183
184
185def render_string_template(content, context, autoescape=True):
186    """
187    Render a template.
188    """
189    context2 = Context(context, autoescape)
190    template = Template(content)
191    html = template.render(context2)
192    return html
193
194
195
196if __name__ == "__main__":
197    import doctest
198    doctest.testmod(
199#        verbose=True
200        verbose=False
201    )
202    print "DocTest end."
Note: See TracBrowser for help on using the browser.