__init__.py @ ea6a7cfcacd8

Merged celdredge/hgext.markdown into default
author Constantine Linnick <theaspect@gmail.com>
date Tue, 08 Oct 2013 00:31:38 +0700
parents 5a8c3dda25ee 61b435d17646
children 25433f9f53f3
import os
import sys

# markdown import is in extsetup function
import logging, mimetypes, codecs
from mercurial import extensions, encoding, util
from mercurial.hgweb import webcommands, webutil, common
from mercurial.hgweb.common import ErrorResponse, HTTP_OK, HTTP_FORBIDDEN, HTTP_NOT_FOUND
import mdx_urlrebase

logging.basicConfig()

def preview_markdown(web, req, tmpl):
    f = req.form.get('node', [''])[0]
    path = req.form.get('file', [''])[0]
    if path:
        f = f + '/' + path

    if not f:
        f = find_working_copy_readme(web.repo.root)

    parts = os.path.splitext(f)

    try:
        text = codecs.open(web.repo.root + "/" + f, "rb", "utf-8").read()
    except IOError:
        raise ErrorResponse(HTTP_NOT_FOUND, 'path not found: ' + f)

    if not parts[-1] == '.markdown' and not parts[-1] == '.md':
        return preview_sendraw(web, req, f, text)

    base_url = tmpl.defaults['url'] + 'preview/'
    base_raw_url = tmpl.defaults['url'] + 'preview/'

    def rebase(proc, e, attr):
        uri = e.get(attr, '')
        if '://' in uri or uri.startswith('/') or uri.startswith('#'):
            return
        base = base_url
        if attr == 'src':
            base = base_raw_url
        e.set(attr, proc.rebase(base, uri))

    ext = mdx_urlrebase.UrlRebaseExtension(configs=[('rebase', rebase)])
    md = Markdown(
            extensions=[ext, 'wikilinks','toc','headerid','attr_list'],
            extension_configs={
                'wikilinks' : [('base_url', ""), ('end_url', parts[-1])]})
    html = md.convert(text).encode("utf-8")

    args = {'file':f,
            'readmefilename':parts[0].split('/')[-1],
            'path':webutil.up(f),
            'readme':html,
            'rev':'tip',
            'node':''}

    return tmpl("markdown",    **args)

def preview_sendraw(web, req, path, data):
    guessmime = web.configbool('web', 'guessmime', False)

    if util.binary(data):
        mt = 'application/binary'
    else:
        mt = 'text/plain'

    if guessmime:
        mt = mimetypes.guess_type(path)[0]
        if mt is None:
            mt = binary(text) and 'application/binary' or 'text/plain'
    if mt.startswith('text/'):
        mt += '; charset="%s"' % encoding.encoding

    mt += '; Content-length="%s"' % len(data)
    req.respond(HTTP_OK, mt, path, data)
    return data

def file_markdown(orig, web, req, tmpl):
    f = req.form.get('file', [''])[0]
    parts = os.path.splitext(f)

    if 'file' not in req.form:
        return webcommands.manifest(web, req, tmpl)

    if not parts[-1] == '.markdown' and not parts[-1] == '.md':
        return orig(web, req, tmpl)

    try:
        fctx = webutil.filectx(web.repo, req)
        changeid = fctx.hex()[0:12]
        text = fctx.data().decode("utf-8")
    except LookupError, inst:
        try:
            return webcommands.manifest(web, req, tmpl)
        except ErrorResponse:
            raise inst

    if util.binary(text):
        return webcommands.rawfile(web, req, tmpl)

    relative_path = os.path.split(f)[0]
    base_url = tmpl.defaults['url'] + 'file/' + changeid + "/" + relative_path
    base_raw_url = tmpl.defaults['url'] + 'rawfile/' + changeid + "/" + relative_path

    def rebase(proc, e, attr):
        uri = e.get(attr, '')
        if '://' in uri or uri.startswith('/') or uri.startswith('#'):
            return
        base = base_url
        if attr == 'src':
            base = base_raw_url
        e.set(attr, proc.rebase(base, uri))

    ext = mdx_urlrebase.UrlRebaseExtension(configs=[('rebase', rebase)])
    md = Markdown(
            extensions=[ext, 'wikilinks','toc','headerid','attr_list'],
            extension_configs={
                'wikilinks' : [('base_url', ""), ('end_url', parts[-1])]})
    html = md.convert(text).encode("utf-8")

    args = {'file':f,
            'readmefilename':parts[0].split('/')[-1],
            'path':webutil.up(f),
            'readme':html}

    args.update({'rev':fctx.rev(),
            'node':fctx.hex(),
            'author':fctx.user(),
            'date':fctx.date(),
            'desc':fctx.description(),
            'branch':webutil.nodebranchnodefault(fctx),
            'parent':webutil.parents(fctx),
            'child':webutil.children(fctx)})

    return tmpl("markdown",    **args)

def summary_markdown(orig, web, req, tmpl):
    """
    Decorates the default summary view by adding 'readme' and 'readmefile' content
    to the template.
    """

    changeid = web.config('web', 'markdown.changeid', 'tip')
    text = None

    cctx = web.repo[changeid]
    changeid = cctx.hex()[0:12]
    for filename in cctx:
        if filename.lower() == 'readme.md' or filename.lower() == 'readme.markdown':
            fctx = cctx.filectx(filename)
            text = fctx.data().decode("utf-8")
            filesuffix = '.' + filename.split('.')[-1]
            readmefile = filename
            break

    if text:
        ext = os.path.splitext(readmefile)[1]
        base_url = tmpl.defaults['url'] + 'file/' + changeid + "/"
        base_raw_url = tmpl.defaults['url'] + 'rawfile/' + changeid + "/"

        def rebase(proc, e, attr):
            uri = e.get(attr, '')
            if '://' in uri or uri.startswith('/') or uri.startswith('#'):
                return
            base = base_url
            if attr == 'src':
                base = base_raw_url
            e.set(attr, proc.rebase(base, uri))

        ext = mdx_urlrebase.UrlRebaseExtension(configs=[('rebase', rebase)])
        md = Markdown(
            extensions=[ext, 'wikilinks','toc','headerid','attr_list'],
            extension_configs={
                'wikilinks' : [('base_url', base_url), ('end_url', filesuffix)]})
        readme = md.convert(text).encode("utf-8")
    else:
        readmefile = "ReadMe"
        readme = "Add ReadMe.md or ReadMe.markdown to this repository to display it here."

    tmpl.defaults['readmefilename'] = readmefile
    tmpl.defaults['readme'] = readme

    return orig(web, req, tmpl)

def find_working_copy_readme(dir):
    for filename in os.listdir(dir):
        if filename.lower() == 'readme.md' or filename.lower() == 'readme.markdown':
            return filename

def extsetup(ui):
    extensions.wrapfunction(webcommands, 'file', file_markdown)
    extensions.wrapfunction(webcommands, 'summary', summary_markdown)
    webcommands.preview = preview_markdown
    webcommands.__all__.append('preview')

    try:
        from markdown import Markdown
    except ImportError:
        dir = os.path.dirname(os.path.realpath(__file__))
        md = ui.config("web", "markdown.egg", "Markdown-2.3.1")
        ui.debug("Markdown not found search for egg in local dir %s for %s.zip\n" % (dir, md))
        sys.path.append(os.path.join(dir, "%s.zip\%s" % (md, md)))
        try:
            from markdown import Markdown
        except ImportError:
            ui.error("Unable to locate markdown in path %s" % sys.path)
    global Markdown