]> scripts.mit.edu Git - www/ikiwiki.git/blob - doc/todo/Resolve_native_reStructuredText_links_to_ikiwiki_pages.mdwn
about default-role
[www/ikiwiki.git] / doc / todo / Resolve_native_reStructuredText_links_to_ikiwiki_pages.mdwn
1 _NB! this page has been refactored, hopefully it is clearer now_  
2 _I propose putting discussion posts somewhere in the vincity of
3 the secttion Individual reStructuredText Issues_
4
5 **Goal**
6
7 To be able to use rst as a first-class markup language in ikiwiki. I think
8 most believe this is almost impossible (ikiwiki is built around markdown).
9
10 **Design**
11
12 **WikiLinks**, first and foremost, are needed for a wiki. rST already allows
13 specifying absolue and relative URL links, and relative links can be used to
14 tie together wiki of rst documents.
15
16 1. Below are links to a small, working implementation for resolving
17    undefined rST references using ikiwiki's mechanism. This is **Proposal 1**
18    for rst WikiLinks.
19
20 2. Looking over at rST-using systems such as trac and MoinMoin; I think it
21    would be wiser to implement wikilinks by the `:role:` mechanism, together
22    with allowing a custom URL scheme to point to wiki links. This is
23    **Proposal 2**.
24
25         This is a simple wiki page, with :wiki:`WikiLinks` and other_ links
26         
27         .. _other: wiki:wikilink
28
29         We can get rid of the role part as well for WikiLinks::
30         
31             .. default-role:: wiki
32         
33         Enables `WikiLinks` but does not impact references such as ``other``
34         This can be made the default for ikiwiki.
35
36 Benefits of using a `:role:` and a `wiki: page/subpage` URL scheme are
37 following:
38
39 1. rST documents taken out of the context (the wiki) will not fail as bad as
40    if they have lots of Proposal-1 links: They look just the same as valid
41    references, and you have to edit them all.
42    In contrast, should the `:wiki:` role disappear, one line is enough
43    to redefined it and silence all the warnings for the document:
44
45         .. role:: wiki (title)
46
47 *Implementation* there is no implementation of Proposal 2 but it should be
48 doable; adding a local role is trivial. Rewriting `wiki:` links could be
49 done in the format phase(?).
50
51 Now **Directives**: As it is now, ikiwiki goes though (roughly):
52 filter, preprocess, htmlize, format as major stages of content
53 transformation. rST has major problems to work with any HTML that enters the
54 picture before it.
55
56 1. Formatting rST in `htmlize` (as is done now): Raw html can be escaped by
57    raw blocks:
58
59         .. raw:: html
60         
61                 \[[!inline and do stuff]]
62
63    (This can be simplified to alias the above as `.. ikiwiki::`)
64    This escape method works, if ikwiki can be persuaded to maintain the
65    indent when inserting html, so that it stays inside the raw block.
66
67 2. Formatting rST in `filter` (idea)
68    1. rST does not have to see any HTML (raw not needed)
69    2. rST directives can alias ikiwiki syntax:
70      
71         ..ikiwiki:: inline pages= ...
72
73    3. Using rST directives as ikiwiki directives can be complicated;
74       but rST directives allow a direct line (after :: on first line),
75       an option list, and a content block.
76
77
78 **Discussion**
79
80 I guess you (or someone) has been through this before and knows why it
81 simply won't work. But I hoped there was something original in the above;
82 and I know there are wiki installations where rST works. --ulrik
83
84 **Individual reStructuredText Issues**
85
86 * We resolve rST links without definition, we don't help resolving defined
87   relative links, so we don't support specifying link name and target
88   separately.
89
90 > I found out this is possible by using rST subsitutions. So to do [[Version history...|releases]]
91 > you would use:
92
93 > `|releases|_`  
94 > `.. |releases| replace:: Version history...`  
95 > Which does not seem to have an inline equivalent. Using non-resolved links there is the alternative:
96 >
97 > ``Version history <releases/>`_`. --ulrik [kaizer.se]
98
99 **A first implementation: Resolving unmatched links**
100
101 I have a working minimal implementation letting the rst renderer resolve
102 undefined native rST links to ikiwiki pages. I have posted it as one patch at:
103
104 Preview commit: http://github.com/engla/ikiwiki/commit/486fd79e520da1d462f00f40e7a90ab07e9c6fdf  
105 Repository: git://github.com/engla/ikiwiki.git  
106
107 Design issues of the patch:
108
109 The page is rST-parsed once in 'scan' and once in 'htmlize' (the first to generate backlinks). Can the parse output be safely reused?
110
111 > The page content fed to htmlize may be different than that fed to scan,
112 > as directives can change the content. If you cached the input and output
113 > at scan time, you could reuse the cached data at htmlize time for inputs
114 > that are the same -- but that could be a very big cache! --[[Joey]] 
115
116 >> I would propose using a simple heuristic: If you see \[[ anywhere on the
117 >> page, don't cache it. It would be an effective cache for pure-rst wikis
118 >> (without any ikiwiki directives or wikilinks).
119 >> However, I think that if the cache does not work for a big load, it should
120 >> not work at all; small loads are small so they don't matter. --ulrik
121
122 Patch follows:
123
124 ----
125 <pre>
126         From 486fd79e520da1d462f00f40e7a90ab07e9c6fdf Mon Sep 17 00:00:00 2001
127         From: Ulrik Sverdrup <ulrik.sverdrup@gmail.com>
128         Date: Thu, 17 Sep 2009 15:18:50 +0200
129         Subject: [PATCH] rst: Resolve native reStructuredText links to ikiwiki pages
130
131         Links in rST use syntax `Like This`_ or OneWordLink_, and are
132         generally used for relative or absolue links, with an auxiliary
133         definition:
134
135         .. _`Like This`: http://ikiwiki.info
136         .. _OneWordLink: relative
137
138         We can hook into docutils to resolve unresolved links so that rST
139         links without definition can be resolved to wiki pages. This enables
140         WikiLink_ to link to [[WikiLink]] (if no .. _WikiLink is specified).
141
142         Comparing to Ikiwiki's wikilinks
143
144         [[blogging|blog]] specifies a link to the page blog, with the name
145         blogging. In rST we should use blogging_
146
147         .. _blogging: blog
148
149         *However*, note that this patch does not hook into this. What we
150         resolve in this patch is finding the appropriate "_blogging" if it is
151         not found, not resolving the address 'blog'.
152         ---
153          plugins/rst |   46 +++++++++++++++++++++++++++++++++++++++++-----
154          1 files changed, 41 insertions(+), 5 deletions(-)
155
156         diff --git a/plugins/rst b/plugins/rst
157         index a2d07eb..a74baa8 100755
158         --- a/plugins/rst
159         +++ b/plugins/rst
160         @@ -6,22 +6,58 @@
161          # based a little bit on rst.pm by Sergio Talens-Oliag, but only a little bit. :)
162          #
163          # Copyright © martin f. krafft <madduck@madduck.net>
164         +# Copyright © Ulrik Sverdrup <ulrik.sverdrup@gmail.com>, 2009
165         +#
166          # Released under the terms of the GNU GPL version 2
167          #
168         +
169          __name__ = 'rst'
170          __description__ = 'xml-rpc-based ikiwiki plugin to process RST files'
171         -__version__ = '0.3'
172         +__version__ = '0.3+'
173          __author__ = 'martin f. krafft <madduck@madduck.net>'
174          __copyright__ = 'Copyright © ' + __author__
175          __licence__ = 'GPLv2'
176          
177          from docutils.core import publish_parts;
178         +from docutils.writers import html4css1
179          from proxy import IkiWikiProcedureProxy
180          
181         -def rst2html(proxy, *kwargs):
182         -    # FIXME arguments should be treated as a hash, the order could change
183         -    # at any time and break this.
184         -    parts = publish_parts(kwargs[3], writer_name='html',
185         +class IkiwikiWriter(html4css1.Writer):
186         +    def resolve_node(self, node):
187         +        refname = node.get('refname', None)
188         +        if not refname:
189         +            return False
190         +
191         +        bestlink = self.proxy.rpc('bestlink', self.page, refname)
192         +
193         +        node.resolved = 1
194         +        node['class'] = 'wiki'
195         +        del node['refname']
196         +
197         +        if not bestlink:
198         +            rel_url = "#"
199         +        else:
200         +            rel_url = self.proxy.rpc('urlto', bestlink, self.page)
201         +            self.proxy.rpc('add_link', self.page, bestlink)
202         +        node['refuri'] = rel_url
203         +        self.proxy.rpc('debug', "Emitting link %s => %s" % (refname, rel_url))
204         +        return True
205         +
206         +    resolve_node.priority = 1
207         +
208         +    def __init__(self, proxy, page):
209         +        html4css1.Writer.__init__(self)
210         +        self.proxy = proxy
211         +        self.page = page
212         +        self.unknown_reference_resolvers = (self.resolve_node, )
213         +
214         +def rst2html(proxy, *args):
215         +    # args is a list paired by key, value, so we turn it into a dict
216         +    kwargs = dict((k, v) for k, v in zip(*[iter(args)]*2))
217         +    page = kwargs['page']
218         +
219         +    parts = publish_parts(kwargs['content'],
220         +                          writer=IkiwikiWriter(proxy, page),
221                                    settings_overrides = { 'halt_level': 6
222                                                         , 'file_insertion_enabled': 0
223                                                         , 'raw_enabled': 1
224         -- 
225         1.6.4
226
227 </pre>
228 ----