ikiwiki/doc/todo/Resolve_native_reStructured...

222 lines
8.0 KiB
Markdown

_NB! this page has been refactored, hopefully it is clearer now_
_I propose putting discussion posts somewhere in the vincity of
the secttion Individual reStructuredText Issues_
**Goal**
To be able to use rst as a first-class markup language in ikiwiki. I think
most believe this is almost impossible (ikiwiki is built around markdown).
**Design**
**WikiLinks**, first and foremost, are needed for a wiki. rST already allows
specifying absolue and relative URL links, and relative links can be used to
tie together wiki of rst documents.
1. Below are links to a small, working implementation for resolving
undefined rST references using ikiwiki's mechanism. This is **Proposal 1**
for rst WikiLinks.
2. Looking over at rST-using systems such as trac and MoinMoin; I think it
would be wiser to implement wikilinks by the `:role:` mechanism, together
with allowing a custom URL scheme to point to wiki links. This is
**Proposal 2**.
This is a simple wiki page, with :wiki:`WikiLinks` and other_ links
.. _other: wiki:wikilink
Benefits of using a `:role:` and a `wiki: page/subpage` URL scheme are
following:
1. rST documents taken out of the context (the wiki) will not fail as bad as
if they have lots of Proposal-1 links: They look just the same as valid
references, and you have to edit them all.
In contrast, should the `:wiki:` role disappear, one line is enough
to redefined it and silence all the warnings for the document:
.. role:: wiki (title)
*Implementation* there is no implementation of Proposal 2 but it should be
doable; adding a local role is trivial. Rewriting `wiki:` links could be
done in the format phase(?).
Now **Directives**: As it is now, ikiwiki goes though (roughly):
filter, preprocess, htmlize, format as major stages of content
transformation. rST has major problems to work with any HTML that enters the
picture before it.
1. Formatting rST in `htmlize` (as is done now): Raw html can be escaped by
raw blocks:
.. raw:: html
\[[!inline and do stuff]]
(This can be simplified to alias the above as `.. ikiwiki::`)
This escape method works, if ikwiki can be persuaded to maintain the
indent when inserting html, so that it stays inside the raw block.
2. Formatting rST in `filter` (idea)
1. rST does not have to see any HTML (raw not needed)
2. rST directives can alias ikiwiki syntax:
..ikiwiki:: inline pages= ...
3. Using rST directives as ikiwiki directives can be complicated;
but rST directives allow a direct line (after :: on first line),
an option list, and a content block.
**Discussion**
I guess you (or someone) has been through this before and knows why it
simply won't work. But I hoped there was something original in the above;
and I know there are wiki installations where rST works. --ulrik
**Individual reStructuredText Issues**
* We resolve rST links without definition, we don't help resolving defined
relative links, so we don't support specifying link name and target
separately.
> I found out this is possible by using rST subsitutions. So to do [[Version history...|releases]]
> you would use:
>
> `|releases|_`
> `.. |releases| replace:: Version history...`
> Which does not seem to have an inline equivalent. Using non-resolved links there is the alternative:
>
> ``Version history <releases/>`_`. --ulrik [kaizer.se]
**A first implementation: Resolving unmatched links**
I have a working minimal implementation letting the rst renderer resolve
undefined native rST links to ikiwiki pages. I have posted it as one patch at:
Preview commit: http://github.com/engla/ikiwiki/commit/486fd79e520da1d462f00f40e7a90ab07e9c6fdf
Repository: git://github.com/engla/ikiwiki.git
Design issues of the patch:
The page is rST-parsed once in 'scan' and once in 'htmlize' (the first to generate backlinks). Can the parse output be safely reused?
> The page content fed to htmlize may be different than that fed to scan,
> as directives can change the content. If you cached the input and output
> at scan time, you could reuse the cached data at htmlize time for inputs
> that are the same -- but that could be a very big cache! --[[Joey]]
>> I would propose using a simple heuristic: If you see \[[ anywhere on the
>> page, don't cache it. It would be an effective cache for pure-rst wikis
>> (without any ikiwiki directives or wikilinks).
>> However, I think that if the cache does not work for a big load, it should
>> not work at all; small loads are small so they don't matter. --ulrik
Patch follows:
----
<pre>
From 486fd79e520da1d462f00f40e7a90ab07e9c6fdf Mon Sep 17 00:00:00 2001
From: Ulrik Sverdrup <ulrik.sverdrup@gmail.com>
Date: Thu, 17 Sep 2009 15:18:50 +0200
Subject: [PATCH] rst: Resolve native reStructuredText links to ikiwiki pages
Links in rST use syntax `Like This`_ or OneWordLink_, and are
generally used for relative or absolue links, with an auxiliary
definition:
.. _`Like This`: http://ikiwiki.info
.. _OneWordLink: relative
We can hook into docutils to resolve unresolved links so that rST
links without definition can be resolved to wiki pages. This enables
WikiLink_ to link to [[WikiLink]] (if no .. _WikiLink is specified).
Comparing to Ikiwiki's wikilinks
[[blogging|blog]] specifies a link to the page blog, with the name
blogging. In rST we should use blogging_
.. _blogging: blog
*However*, note that this patch does not hook into this. What we
resolve in this patch is finding the appropriate "_blogging" if it is
not found, not resolving the address 'blog'.
---
plugins/rst | 46 +++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 41 insertions(+), 5 deletions(-)
diff --git a/plugins/rst b/plugins/rst
index a2d07eb..a74baa8 100755
--- a/plugins/rst
+++ b/plugins/rst
@@ -6,22 +6,58 @@
# based a little bit on rst.pm by Sergio Talens-Oliag, but only a little bit. :)
#
# Copyright © martin f. krafft <madduck@madduck.net>
+# Copyright © Ulrik Sverdrup <ulrik.sverdrup@gmail.com>, 2009
+#
# Released under the terms of the GNU GPL version 2
#
+
__name__ = 'rst'
__description__ = 'xml-rpc-based ikiwiki plugin to process RST files'
-__version__ = '0.3'
+__version__ = '0.3+'
__author__ = 'martin f. krafft <madduck@madduck.net>'
__copyright__ = 'Copyright © ' + __author__
__licence__ = 'GPLv2'
from docutils.core import publish_parts;
+from docutils.writers import html4css1
from proxy import IkiWikiProcedureProxy
-def rst2html(proxy, *kwargs):
- # FIXME arguments should be treated as a hash, the order could change
- # at any time and break this.
- parts = publish_parts(kwargs[3], writer_name='html',
+class IkiwikiWriter(html4css1.Writer):
+ def resolve_node(self, node):
+ refname = node.get('refname', None)
+ if not refname:
+ return False
+
+ bestlink = self.proxy.rpc('bestlink', self.page, refname)
+
+ node.resolved = 1
+ node['class'] = 'wiki'
+ del node['refname']
+
+ if not bestlink:
+ rel_url = "#"
+ else:
+ rel_url = self.proxy.rpc('urlto', bestlink, self.page)
+ self.proxy.rpc('add_link', self.page, bestlink)
+ node['refuri'] = rel_url
+ self.proxy.rpc('debug', "Emitting link %s => %s" % (refname, rel_url))
+ return True
+
+ resolve_node.priority = 1
+
+ def __init__(self, proxy, page):
+ html4css1.Writer.__init__(self)
+ self.proxy = proxy
+ self.page = page
+ self.unknown_reference_resolvers = (self.resolve_node, )
+
+def rst2html(proxy, *args):
+ # args is a list paired by key, value, so we turn it into a dict
+ kwargs = dict((k, v) for k, v in zip(*[iter(args)]*2))
+ page = kwargs['page']
+
+ parts = publish_parts(kwargs['content'],
+ writer=IkiwikiWriter(proxy, page),
settings_overrides = { 'halt_level': 6
, 'file_insertion_enabled': 0
, 'raw_enabled': 1
--
1.6.4
</pre>
----