# Textile: a Vellum plugin
# Implements a subset of Dean Allen's Textile web text generator

import vellum.hooks

import sys,re
html = []
false = 0; true = not false

# block level
rHeader = re.compile(r'\s*h(?P<h>[1-6]).\s+')
rBlockquote = re.compile(r'\s*bq.\s+')
rUL = re.compile(r'\s*\*\s+')
rOL = re.compile(r'\s*#\s+')

# inline
rEM = re.compile(r'\b_([^ \t\n\r\f\v_]+)_\b')
rStrong = re.compile(r'\*([^ \t\n\r\f\v*]+)\*')
rCite = re.compile(r'\?\?([^ \t\n\r\f\v?]+)\?\?')

# pure HTML
rJustHTML = re.compile('^(<[^>]+>)+$')

def parseText(entry,form):
    if not form.has_key("textile"): return
    txt = entry.body
    ls = txt.splitlines()

    # inFoo flags
    inOL = false; inUL = false

    html = []

    for l in ls:
        # Inline
        ll = rEM.sub(r'<em>\1</em>',l)
        ll = rStrong.sub(r'<strong>\1</strong>',ll)
        ll = rCite.sub(r'<cite>\1</cite>',ll)
        
        # Block modifiers
        isHead = rHeader.match(ll)
        isBlockquote = rBlockquote.match(ll)
        isUL = rUL.match(ll)
        isOL = rOL.match(ll)
        isJustHTML = rJustHTML.match(ll)

        # Check for list terminations
        if inUL and not isUL:
            html.append('</ul>')
            inUL = false
        if inOL and not isOL:
            html.append('</ol>')
            inOL = false

        if isHead:
            h = isHead.group("h")
            html.append('<h%s>%s</h%s>' % (h,ll[len(isHead.group(0)):],h))
        elif isBlockquote:
            html.append('<blockquote>%s</blockquote>' % (ll[len(isBlockquote.group(0)):]))
        elif isUL:
            if not inUL:
                html.append('<ul>')
                inUL = true
            html.append('<li>%s</li>' % (ll[len(isUL.group(0)):]))
        elif isOL:
            if not inOL:
                html.append('<ol>')
                inOL = true
            html.append('<li>%s</li>' % (ll[len(isOL.group(0)):]))
        else:
            if l.strip() and not isJustHTML:
                html.append('<p>%s</p>' % ll)

    # Check again for list terminations
    if inUL:
        html.append('</ul>')
        inUL = false
    if inOL:
        html.append('</ol>')
        inOL = false

    entry.body = '\n'.join(html)

vellum.hooks.register_hook("entry-new-save",parseText)

def printDetails():
    print '''<div class="plugin">
    <h2>Textile</h2>
    <h3>Block modifiers</h3>
    <p>Header: <strong>h<em>n</em>. </strong></p>
    <p>Blockquote: <strong>bq. </strong></p>
    <p>Numeric list: <strong># </strong></p>
    <p>Bulleted list: <strong>* </strong></p>
    <p><input type="checkbox" name="textile"> Enable Textile parsing?</p>
    </div>
    '''

vellum.hooks.register_hook("entry-new-print",printDetails)
