Archive for August, 2007

TextPress and other lost stuff…

Some time ago I wrote a blog engine in Python to replace this wordpress installation. As you can see that never really happened although the blog software is already in a usable state (at least the basic administration and plugin interface works). One of the reasons is that i would have to port over the theme which is one of those stupid tasks i just hate, another one is that i haven’t had time to improve it any further. Another piece of software I recently discovered again is a python powered wiki called ordo which I wrote one year ago i guess. It’s a shame that those applications never where released or properly licensed. ordo lingers around in my svn repository but textpress does not.

TextPress won’t for a few reasons. One is the name, it’s obviously taken from wordpress and want to rename it before I release it, the other reason is that i don’t have the time to maintain the code right now. There are already many other projects and I don’t feel like I want to maintain too much code at the same time.

But because TextPress has some really unique features I at least want to show what it does :)

screenshot of the textpress blog

The screenshot above shows the default theme, the admin panel looks like this and this. It has a pretty interesting plugin interface. The event system was inspired by dokuwiki, the way the syntax based plugins work is IMHO unique :)

Basically what it does is lexing the post sgml markup into a DOM like structure which you can query and transform. Here for example the complete sourcecode of the pygments plugin:

from textpress.api import *
from textpress.htmlprocessor import DataNode
try:
    from pygments import highlight
    from pygments.lexers import get_lexer_by_name
    from pygments.formatters import HtmlFormatter
    have_pygments = True
except ImportError:
    have_pygments = False

class PygmentsHighlighter(object):

    def __init__(self, style):
        self.formatter = HtmlFormatter(style=style)

    def process_doc_tree(self, event):
        for node in event.data['doctree'].query('pre[@tp:lang]'):
            lexer = get_lexer_by_name(node.attributes.pop('tp:lang'))
            output = highlight(node.text, lexer, self.formatter)
            node.parent.children.replace(node, DataNode(output))

    def get_style(self, req):
        return Response(self.formatter.get_style_defs(), mimetype='text/css')

    def inject_style(self, event):
        add_link('stylesheet', url_for('pygments_support/style'), 'text/css')

def setup(app, plugin):
    if not have_pygments:
        return
    app.add_config_var('pygments_support/style', unicode, u'default')
    app.add_url_rule('/_shared/pygments_support/style.css',
                     endpoint='pygments_support/style')

    c = PygmentsHighlighter(app.cfg['pygments_support/style'])
    app.connect_event('process-doc-tree', c.process_doc_tree)
    app.connect_event('after-request-setup', c.inject_style)
    app.add_view('pygments_support/style', c.get_style)

You can see the event and doc tree system in action in the snippet above. The way the DOM is queried is inspired by jQuery ;-)

Vim File Templates

All python modules I use have the same header. Usually I copy other modules but why not load a default template into a python file in vim?

Here a small snippet that does exactly that:

function! LoadFileTemplate()
  silent! 0r ~/.vim/templates/%:e.tmpl
  syn match vimTemplateMarker "<+.++>" containedin=ALL
  hi vimTemplateMarker guifg=#67a42c guibg=#112300 gui=bold
endfunction

function! JumpToNextPlaceholder()
  let old_query = getreg('/')
  echo search("<+.++>")
  exec "norm! c/+>/e<CR>"
  call setreg('/', old_query)
endfunction

autocmd BufNewFile * :call LoadFileTemplate()
nnoremap <C-J> :call JumpToNextPlaceholder()<CR>a
inoremap <C-J> <ESC>:call JumpToNextPlaceholder()<CR>a

What it does is looking for a template called “extension.tmpl” in ~/.vim/templates. If it finds one it loads it and highlights everything between “<+" and "+>” as placeholder. Hitting Ctrl+J jumps to the next placeholder.

An example template could look like this:

# -*- coding: utf-8 -*-
"""
<+ MODULE_NAME +>

<+ DESCRIPTION +>

Licensed under the <+ LICENSE +> license, see X for more details etc.
Copyright by …
"""

If you want to load a file without a template, just hit “u” right at the beginning and the inserted template will disappear.

Jinja Updates

August 2nd, 2007

The new parser works quite well so far, in fact too well. So far all unittests pass which is something i really, really hate. Usually it means that there are unittests missing :)

The new parser supports some new stuff. For example {{ foo.0 }} is supported for easier django template transition. A regular expression literal so that the “matching” filter finally makes sense, a set literal, conditional expressions and the debugger is finally a real help.

It’s still not in the trunk because some of the changes are too big for a simple merging. If someone has really, really complex templates, try the new-parser branch and try to render the templates there. If you encounter any errors, just poke me, i’ll fix it and add a unittest :D

cogitations driven by wordpress