summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>2007-10-15 16:33:02 +0000
committerjoey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>2007-10-15 16:33:02 +0000
commit65dca9f89d82cc512f1c10ac8cf70696243e650a (patch)
tree53e0c9e87da2fcd86f23a557ac2132c92b700bb6
parent68c77ef01fff197c65678f6f23a12cea66f635db (diff)
* 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.
-rw-r--r--IkiWiki/Plugin/rst.pm69
-rw-r--r--debian/changelog6
-rw-r--r--debian/copyright8
-rw-r--r--doc/plugins/rst.mdwn10
-rw-r--r--doc/plugins/write/external.mdwn6
-rw-r--r--doc/todo/rst_plugin_python_rewrite.mdwn2
-rwxr-xr-xplugins/rst97
7 files changed, 116 insertions, 82 deletions
diff --git a/IkiWiki/Plugin/rst.pm b/IkiWiki/Plugin/rst.pm
deleted file mode 100644
index 30f5d16d8..000000000
--- a/IkiWiki/Plugin/rst.pm
+++ /dev/null
@@ -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
diff --git a/debian/changelog b/debian/changelog
index 760fc46f2..5250783ca 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -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
diff --git a/debian/copyright b/debian/copyright
index ab85fe424..2681da807 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -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+
diff --git a/doc/plugins/rst.mdwn b/doc/plugins/rst.mdwn
index 7250e46a1..1f8073517 100644
--- a/doc/plugins/rst.mdwn
+++ b/doc/plugins/rst.mdwn
@@ -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
diff --git a/doc/plugins/write/external.mdwn b/doc/plugins/write/external.mdwn
index e699e43e1..0abc9b0a0 100644
--- a/doc/plugins/write/external.mdwn
+++ b/doc/plugins/write/external.mdwn
@@ -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).
diff --git a/doc/todo/rst_plugin_python_rewrite.mdwn b/doc/todo/rst_plugin_python_rewrite.mdwn
index 7626f03a3..222fdb177 100644
--- a/doc/todo/rst_plugin_python_rewrite.mdwn
+++ b/doc/todo/rst_plugin_python_rewrite.mdwn
@@ -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!
diff --git a/plugins/rst b/plugins/rst
new file mode 100755
index 000000000..abf835e2e
--- /dev/null
+++ b/plugins/rst
@@ -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()