]> git.vanrenterghem.biz Git - git.ikiwiki.info.git/commitdiff
* Rewritten rst plugin by madduck is a python program that communicates with
authorjoey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>
Mon, 15 Oct 2007 16:33:02 +0000 (16:33 +0000)
committerjoey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>
Mon, 15 Oct 2007 16:33:02 +0000 (16:33 +0000)
  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.

IkiWiki/Plugin/rst.pm [deleted file]
debian/changelog
debian/copyright
doc/plugins/rst.mdwn
doc/plugins/write/external.mdwn
doc/todo/rst_plugin_python_rewrite.mdwn
plugins/rst [new file with mode: 0755]

diff --git a/IkiWiki/Plugin/rst.pm b/IkiWiki/Plugin/rst.pm
deleted file mode 100644 (file)
index 30f5d16..0000000
+++ /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
index 760fc46f243d7f8bd361c9dede05fb0235592129..5250783cae4fbc44681b80d4d53775d628664702 100644 (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
 
index ab85fe424588757abb5922973c45eb042e1db552..2681da80746b63e1959c459bd5bdc7f0e1e4a41f 100644 (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+
index 7250e46a13b352261f79344ab3682fe82da97f26..1f8073517ad78b732125ca3eef67db895557d5be 100644 (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
index e699e43e15464f4972789b1369fcddb75e5ff07e..0abc9b0a0d791eb3448dd11664d7b065101b88b6 100644 (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).
 
index 7626f03a3bb92f970ab800b2f7e2dea437d34284..222fdb17717fb84a5acb1731e8431f9f4bce38e9 100644 (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!
diff --git a/plugins/rst b/plugins/rst
new file mode 100755 (executable)
index 0000000..abf835e
--- /dev/null
@@ -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()