* Rewritten rst plugin by madduck is a python program that communicates with

ikiwiki via XML RPC. This should be much faster than the old plugin that
  had to fork python for every rst page render. Note that if you use
  the rst plugin, you now need to have the RPC::XML perl module installed.
master
joey 2007-10-15 16:33:02 +00:00
parent 68c77ef01f
commit 65dca9f89d
7 changed files with 116 additions and 82 deletions

View File

@ -1,69 +0,0 @@
#!/usr/bin/perl
# Very simple reStructuredText processor.
#
# This plugin calls python and requires python-docutils to transform the text
# into html.
#
# Its main problem is that it does not support ikiwiki's WikiLinks nor
# Preprocessor Directives.
#
# Probably Wikilinks and Preprocessor Directives should support a list of
# extensions to process (i.e. the linkify function could be transformed into
# reStructuredText instead of HTML using a hook on rst.py instead of the
# current linkify function)
#
# by Sergio Talens-Oliag <sto@debian.org>
package IkiWiki::Plugin::rst;
use warnings;
use strict;
use IkiWiki 2.00;
use IPC::Open2;
# Simple python script, maybe it should be implemented using an external script.
# The settings_overrides are given to avoid potential security risks when
# reading external files or if raw html is included on rst pages.
my $pyCmnd = "
from docutils.core import publish_string;
from sys import stdin;
html = publish_string(stdin.read(), writer_name='html',
settings_overrides = { 'halt_level': 6,
'file_insertion_enabled': 0,
'raw_enabled': 1 }
);
print html[html.find('<body>')+6:html.find('</body>')].strip();
";
sub import { #{{{
hook(type => "htmlize", id => "rst", call => \&htmlize);
} # }}}
sub htmlize (@) { #{{{
my %params=@_;
my $content=$params{content};
my $pid;
my $sigpipe=0;
$SIG{PIPE}=sub { $sigpipe=1 };
$pid=open2(*IN, *OUT, "python", "-c", $pyCmnd);
# open2 doesn't respect "use open ':utf8'"
binmode (IN, ':utf8');
binmode (OUT, ':utf8');
print OUT $content;
close OUT;
local $/ = undef;
my $ret=<IN>;
close IN;
waitpid $pid, 0;
return $content if $sigpipe;
$SIG{PIPE}="DEFAULT";
return $ret;
} # }}}
1

6
debian/changelog vendored
View File

@ -17,8 +17,12 @@ ikiwiki (2.10) UNRELEASED; urgency=low
* Add a "createlink" class attribute to the span for wikilinks pointing
to not-yet-existing pages. I don't have a useful style defined for that
though.
* Rewritten rst plugin by madduck is a python program that communicates with
ikiwiki via XML RPC. This should be much faster than the old plugin that
had to fork python for every rst page render. Note that if you use
the rst plugin, you now need to have the RPC::XML perl module installed.
-- Joey Hess <joeyh@debian.org> Sat, 13 Oct 2007 19:05:42 -0400
-- Joey Hess <joeyh@debian.org> Mon, 15 Oct 2007 12:20:15 -0400
ikiwiki (2.9) unstable; urgency=low

8
debian/copyright vendored
View File

@ -58,10 +58,6 @@ Files: topography.pm
Copyright: © 2006 Recai Oktaş <roktas@debian.org>
License: GPL-2+
Files: rst.pm
Copyright: © 2006 Sergio Talens-Oliag <sto@debian.org>
License: GPL-2+
Files: map.pm
Copyright: © 2006 Alessandro Dotti Contra
License: GPL-2+
@ -78,6 +74,10 @@ Files: polygen.pm, pagestats.pm
Copyright: © 2006 Enrico Zini
License: GPL-2+
Files: plugins/rst
Copyright: © martin f. krafft <madduck@madduck.net>
License: GPL-2
Files: doc/logo/*
Copyright: © 2006 Recai Oktaş <roktas@debian.org>
License: GPL-2+

View File

@ -1,11 +1,10 @@
[[template id=plugin name=rst author="Sergio Talens-Oliag"]]
[[template id=plugin name=rst author="martin f. krafft"]]
[[tag type/format]]
[[tag type/slow]]
This plugin lets ikwiki convert files with names ending in ".rst" to html.
It uses the [reStructuredText](http://docutils.sourceforge.net/rst.html)
markup syntax. You need to have the python-docutils module installed to use
it.
markup syntax. You need to have [[cpan RPC::XML]], python and the
python-docutils module installed to use it.
Note that this plugin does not interoperate very well with the rest of
ikiwiki. Limitations include:
@ -13,9 +12,6 @@ ikiwiki. Limitations include:
* There are issues with inserting raw html into documents, as ikiwiki
does with [[WikiLinks|WikiLink]] and many
[[PreprocessorDirectives|PreprocessorDirective]].
* It's slow; it forks a copy of python for each page. While there is a
perl version of the reStructuredText processor, it is not being kept in
sync with the standard version, so is not used.
So while you may find this useful for importing old files into your wiki,
using this as your main markup language in ikiwiki isn't recommended at

View File

@ -8,6 +8,10 @@ written in perl, but is intended to be an example of how to write an
external plugin in your favorite programming language. Wow us at how much
easier you can do the same thing in your favorite language. ;-)
There's now a second external plugin, the [[rst]] plugin, written in
python. (Could someone convert it into a python library that can be used by
other plugins?)
[[toc ]]
## How external plugins use XML RPC
@ -87,7 +91,7 @@ to 1.
Since XML RPC can't pass around references to objects, it can't be used
with functions that take or return such references. That means you can't
use XML RPC for `cgi` or `formbuilder` hooks (which are passed CGI and
100% use XML RPC for `cgi` or `formbuilder` hooks (which are passed CGI and
FormBuilder perl objects), or use it to call `template()` (which returns a
perl HTML::Template object).

View File

@ -3,3 +3,5 @@ rendered. Now that ikiwiki supports plugins written in
[[other_languages|plugins/write/external]], it would be excellent if someone
could rewrite the rst plugin as a pure python external plugin. It would
then run nice and quick.
[[done]], thanks to madduck!

97
plugins/rst 100755
View File

@ -0,0 +1,97 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# rstproc — xml-rpc-based ikiwiki plugin to process RST files
#
# TODO: the top of this file should be converted to a python library for
# ikiwiki plugins
#
# based a little bit on rst.pm by Sergio Talens-Oliag, but only a little bit. :)
#
# Copyright © martin f. krafft <madduck@madduck.net>
# Released under the terms of the GNU GPL version 2
__name__ = 'rstproc'
__description__ = 'xml-rpc-based ikiwiki plugin to process RST files'
__version__ = '0.2'
__author__ = 'martin f. krafft <madduck@madduck.net>'
__copyright__ = 'Copyright © ' + __author__
__licence__ = 'GPLv2'
from docutils.core import publish_string;
import posix
import select
import sys
import xmlrpclib
import xml.parsers.expat
from SimpleXMLRPCServer import SimpleXMLRPCDispatcher
def write(s):
# no comment
sys.stdout.write(s)
sys.stdout.flush()
def debug(s):
print >>sys.stderr, __name__ + ':DEBUG:' + s
sys.stderr.flush()
def rpc_read(processor):
acc = ''
ret = None
while True:
line = sys.stdin.readline()
if line is None: continue
if len(line) == 0: sys.exit(posix.EX_OK)
# debug('read line: ' + line)
acc += line
try:
ret = processor(acc)
# debug('processed: ' + acc)
# debug('got back: ' + ret.__class__.__name__)
return ret
except xml.parsers.expat.ExpatError:
# debug('request invalid or incomplete: ' + acc)
pass
return None
def rpc_call(cmd, **kwargs):
call = xmlrpclib.dumps(sum(kwargs.items(), ()), cmd)
write(call + '\n')
resp = rpc_read(lambda resp: resp)
class SimpleStdinOutXMLRPCHandler(SimpleXMLRPCDispatcher):
def __init__(self):
SimpleXMLRPCDispatcher.__init__(self)
def process_request(self, req):
write(self._marshaled_dispatch(req))
def handle_request(self):
def processor(req):
self.process_request(req)
while True:
ret = rpc_read(processor)
if ret is not None: return ret
def rst2html(*kwargs):
# FIXME arguments should be treated as a hash, the order could change
# at any time and break this.
html = publish_string(kwargs[3], writer_name='html',
settings_overrides = { 'halt_level': 6
, 'file_insertion_enabled': 0
, 'raw_enabled': 1
})
content = html.split('<div class="document">', 1)[1]
content = content.split('</div>\n</body>')[:-1][0].strip()
# debug('content = ' + content)
return content
def importme():
rpc_call('hook', type='htmlize', id='rst', call='rst2html')
handler = SimpleStdinOutXMLRPCHandler()
handler.register_function(importme, name='import')
handler.register_function(rst2html)
while True:
handler.handle_request()