from docutils.core import publish_string as publish_rst_string

from xml.dom.minidom import parseString as parseXMLString

from re import search as reSearch

def replace_sequence(reg, repl, target):
    match = reSearch(reg, target)
    if not match: return None
    return target[:match.start()] + repl + target[match.end():]

def RSTtoHTML(data):
    data = unicode(data, 'utf-8', 'ignore')
    htmldata = publish_rst_string(data, writer_name='html')
    uid = str(hash(htmldata))  # so people can't screw up my ID-finding
    htmldata = htmldata.replace('<div class="document">',
                     '<div class="document" id="%s">' % uid)

    # Change the "highlight" class to "code" class for Pygments
    htmldata = htmldata.replace('<div class="highlight">', '<div class="code">')

    # Terrible workaround: minidom crashes if there are unescaped &'s, such as
    #                      in some YouTube Video includes
    reg = '&(?!(.){2,4};)'
    repl = '&amp;'
    newdata = replace_sequence(reg, repl, htmldata)
    while newdata:
        htmldata = newdata
        newdata = replace_sequence(reg, repl, htmldata)

    # Actually parse it
    doc = parseXMLString(htmldata)

    # Below be dark magics
    doc = filter(lambda x: x.getAttribute('id')==uid,
                 doc.getElementsByTagName('div'))[0]
    # Above be dark magics

    return doc.toxml()


import postmarkup
bbparser = postmarkup.create(use_pygments = postmarkup.pygments_available)
def BBtoHTML(data):
    htmldata = bbparser.render_to_html(data,
                                       auto_urls = True,
                                       paragraphs = True,
                                       )
    return htmldata

def makeUniqueKey(keylist, title = None, allow_uppercase = False):
    ''' Make a unique key given the list of other unique keys.
    Optional arg: title - build a key from this title'''
    if title:
        title = title.strip()
        chars = list(reversed(title))
        key = ''
        while chars:
            c = chars.pop()
            if c.isalnum() or c == '-':
                if allow_uppercase:
                    key += c
                else:
                    key += c.lower()
            elif c == ' ':
                key += '-'
        if key in keylist:
            i = 1
            while (key+'-'+str(i)) in keylist:
                i += 1
            key += '-' + str(i)
        return key
    nums = filter(lambda x: x.isdigit(), keylist)
    maxnum = int(max(nums))
    return str(maxnum+1)

from Cheetah import Template

def runTemplate(templatepath, keyList):
    mylist = dict(keyList)
    for k in mylist:
        if isinstance(mylist[k], unicode):
            mylist[k] = mylist[k].encode('utf-8')

    template = Template.Template(file=templatepath,
                                 searchList=keyList)
    content = template.respond()
    return content 
