Change internal links rendering using python-creole
سؤال
My goal is to create a locally-browsable clone of the bitbucket's wiki browser. Pages are written using creole syntax.
I'm using python-creole to render the files into html. It works relatively fine, but there is a difference between the way python-creole and bitbucket render internal links.
On the Bitbucket site, an internal link with spaces like [[system programming]]
will render to something like <a href="/wiki/system_programming">system programming</a>
(spaces are replaced by _
) while using python-creole this will render to <a href="system programming">system programming</a>
.
Can I tweak python-creole into replacing spaces by _ and how?
المحلول 2
I think I have found a quite dirty way to do this. Looking to creole source-code, the code which turns links to html is here:
def link_emit(self, node):
target = node.content
if node.children:
inside = self.emit_children(node)
else:
inside = self.html_escape(target)
return '<a href="%s">%s</a>' % (
self.attr_escape(target), inside)
In a python shell I have tried the following code:
>>> import creole
>>> from creole.creole2html import emitter
>>> def new_emitter(self, node):
... return 'blah'
>>> emitter.HtmlEmitter.link_emit = new_emitter
>>> creole.creole2html(u"[[link]]")
u'<p>blah</p>'
The exact code to replace spaces by '_' is left as an exercice to the reader...
I'm still looking for a more correct way to do this in "the official way".
نصائح أخرى
Ascobol's answer works, but it is cleaner to use class inheritance.
This is an (slightly changed) extract from a wiki-application I am making. It changes the output from links and tables. If you want to see which methods you can override, you can look at the source-code of python-creole.
class WikiLinkHtmlEmitter(HtmlEmitter):
def link_emit(self, node):
target = node.content
if node.children:
inside = self.emit_children(node)
else:
inside = self.html_escape(target)
m = self.link_rules.addr_re.match(target)
if m:
if m.group('extern_addr'):
return u'<a href="%s">%s</a>' % (
self.attr_escape(target), inside)
elif m.group('inter_wiki'):
raise NotImplementedError
if re.match(r'^\S+@\S+$', target):
target = 'mailto:%s' % target
return u'<a href="%s">%s</a>' % (
self.attr_escape(target), inside)
target = target.lower()
target = slugify(target)
target = '/wiki/' + target
return u'<a href="%s" class="%s">%s</a>' % (
self.attr_escape(target), classes, inside)
def table_emit(self, node):
return u'''
<table class="table table-bordered table-striped">
\n%s
</table>\n''' % self.emit_children(node)
def creole_markup(value):
document = Parser(value).parse()
return mark_safe(WikiLinkHtmlEmitter(document).emit())