Ignore:
Timestamp:
12 Mar 2011, 13:57:24 (14 years ago)
Author:
uli
Message:

Add helper functions to turn ReStructuredText? into HTML.

This can be nice to implement some poor-mans-editor. We can for
example define textareas in forms and render the input as
ReStructuredText? in other pages.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.sirp/trunk/src/waeup/sirp/utils/helpers.py

    r5738 r5848  
    66import shutil
    77import grok
     8from cStringIO import StringIO
     9from docutils.core import publish_string
    810from zope.component.interfaces import IFactory
    911from zope.interface import implementedBy
     
    233235        # Required by IFactory
    234236        return implementedBy(self.factory)
     237
     238def ReST2HTML_w_warnings(source_string):
     239    """Convert a reStructuredText string to HTML preserving warnings.
     240
     241    Returns a tuple ``(<HTML_CODE>, <WARNINGS>)``, both being
     242    strings. Where ``<HTML_CODE>`` is the HTML code generated from the
     243    source string, ``<WARNINGS>`` is a string containing any warning
     244    messages or ``None``.
     245   
     246    Regular multi-line ReStructuredText strings will be returned as
     247    HTML code:
     248
     249        >>> from waeup.sirp.utils.helpers import ReST2HTML
     250        >>> source = '''
     251        ... Headline
     252        ... ========
     253        ...
     254        ... - A list item
     255        ... - Another item
     256        ...
     257        ... Thanks for watching!
     258        ... '''
     259        >>> html, warnings = ReST2HTML_w_warnings(source)
     260        >>> print html
     261        <div class="document" id="headline">
     262        <h1 class="title">Headline</h1>
     263        <BLANKLINE>
     264        <ul class="simple">
     265        <li>A list item</li>
     266        <li>Another item</li>
     267        </ul>
     268        <p>Thanks for watching!</p>
     269        </div>
     270
     271    Here no warnings happened, so the `warnings` are ``None``:
     272
     273        >>> warnings is None
     274        True
     275       
     276    If warnings happen then they can be retrieved in the returned
     277    ``warnings``. We try to render an erraneous document:
     278
     279        >>> source = '''
     280        ... Headline
     281        ... ======
     282        ...
     283        ... Thanks for watching!
     284        ... '''
     285        >>> html, warnings = ReST2HTML_w_warnings(source)
     286        >>> print html
     287        <div class="document" id="headline">
     288        <h1 class="title">Headline</h1>
     289        <BLANKLINE>
     290        <p>Thanks for watching!</p>
     291        </div>
     292
     293        >>> print warnings
     294        <string>:3: (WARNING/2) Title underline too short.
     295        <BLANKLINE>
     296        Headline
     297        ======
     298        <BLANKLINE>
     299
     300    As you can see, the warnings are not displayed inline the document
     301    but can be retrieved from the returned warnings, which is a string
     302    or ``None``.
     303    """
     304    warnings = StringIO()
     305    fulldoc = publish_string(
     306        source_string, writer_name='html4css1',
     307        settings_overrides={
     308            'report_level': 0,
     309            'warning_stream': warnings,
     310            })
     311    warnings.seek(0)
     312    warning_msgs = warnings.read()
     313    if warning_msgs:
     314        # Render again, this time with no warnings inline...
     315        fulldoc =  publish_string(
     316        source_string, writer_name='html4css1',
     317        settings_overrides={
     318            'report_level': 10000,
     319            'halt_level': 10000,
     320            'warning_stream': warnings,
     321            })
     322    if warning_msgs == '':
     323        warning_msgs = None
     324    return getInnerHTMLPart(fulldoc).strip(), warning_msgs
     325
     326def ReST2HTML(source_string):
     327    """Render a string containing ReStructuredText to HTML.
     328
     329    Any warnings about too short headings, etc. are silently
     330    discarded. Use :func:`ReST2HTML_w_warnings` if you want to get any
     331    warnings.
     332
     333    A regular document will be rendered like this:
     334
     335        >>> source = '''
     336        ... Headline
     337        ... ========
     338        ...
     339        ... Thanks for watching!
     340        ... '''
     341        >>> html = ReST2HTML(source)
     342        >>> print html
     343        <div class="document" id="headline">
     344        <h1 class="title">Headline</h1>
     345        <BLANKLINE>
     346        <p>Thanks for watching!</p>
     347        </div>
     348
     349    A document with markup problems (here: the underline is too short)
     350    will look similar:
     351
     352        >>> source = '''
     353        ... Headline
     354        ... ======
     355        ...
     356        ... Thanks for watching!
     357        ... '''
     358        >>> html = ReST2HTML(source)
     359        >>> print html
     360        <div class="document" id="headline">
     361        <h1 class="title">Headline</h1>
     362        <BLANKLINE>
     363        <p>Thanks for watching!</p>
     364        </div>
     365       
     366    """
     367    html, warnings = ReST2HTML_w_warnings(source_string)
     368    return html
Note: See TracChangeset for help on using the changeset viewer.