aboutsummaryrefslogtreecommitdiff
path: root/plugins/rst
blob: abf835e2ed01e297679bda0475a83cd5d1bf4756 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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()