-
Notifications
You must be signed in to change notification settings - Fork 1
/
mdx_semanticwikilinks.py
154 lines (107 loc) · 4.45 KB
/
mdx_semanticwikilinks.py
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#! /usr/bin/env python
'''
SemanticWikiLinks Extension for Python-Markdown
===============================================
Adds support for semantic (wiki)links (RDFa).
Converts links of style `[[rel :: target | label ]]`, where `rel` and `label`
are optional.
Customizable with `make_link` option as to what the actual element is.
Usage
-----
>>> text = "Some text with a [[WikiLink]]."
>>> html = markdown.markdown(text, ['semanticwikilinks'])
>>> print(html)
<p>Some text with a <a href="WikiLink">WikiLink</a>.</p>
>>> text = "[[http://activearchives.org/]], [[#id|anchor]], [[../index.html|a relative link]], [[/|an absolute link]], [[/index.html|another absolute link]]"
>>> html = markdown.markdown(text, ['semanticwikilinks'])
>>> print(html)
<p><a href="http://activearchives.org/">http://activearchives.org/</a>, <a href="#id">anchor</a>, <a href="../index.html">a relative link</a>, <a href="/">an absolute link</a>, <a href="/index.html">another absolute link</a></p>
Define a custom URL builder:
>>> def make_rdfa(md, rel, target, label):
... # `md` is the Markdown instance
... elt = etree.Element("span")
... elt.set("property", rel)
... elt.set("value", target)
... elt.text = label or target
... return elt
>>> md = markdown.Markdown(extensions=['semanticwikilinks'],
... extension_configs={'semanticwikilinks' : [('make_link', make_rdfa)]})
>>> html = md.convert('[[ Speaker :: Sherry Turkle | Second Self ]]')
>>> print(html)
<p><span property="aa:Speaker" value="Sherry Turkle">Second Self</span></p>
Change the default namespace (which is "aa"):
>>> md = markdown.Markdown(extensions=['semanticwikilinks'],
... extension_configs={'semanticwikilinks' : [('namespace', 'mynamespace')]})
>>> html = md.convert('[[ Speaker :: Sherry Turkle | Second Self ]]')
>>> print(html)
<p><a href="Sherry Turkle" rel="mynamespace:Speaker">Second Self</a></p>
To do
-----
- An optional function to wikify names? (It is already possible to achieve
this with the custom `make_link` function).
Dependencies
------------
* [Markdown 2.0+](http://www.freewisdom.org/projects/python-markdown/)
Copyright
---------
2011, 2012 [The active archives contributors](http://activearchives.org/)
2011, 2012 [Michael Murtaugh](http://automatist.org/)
2011, 2012 [Alexandre Leray](http://stdin.fr/)
All rights reserved.
This software is released under the modified BSD License.
See LICENSE.md for details.
'''
import markdown
try: from markdown import etree
except ImportError: from markdown.util import etree
import re
__version__ = "1.1.1"
WIKILINK_RE = r"""
\[\[\s*
(?:((?P<namespace>\w+):)?(?P<rel>[^\]#]+?) \s* ::)? \s*
(?P<target>.+?) \s*
(?:\| \s* (?P<label>.+?) \s*)?
\]\](?!\])
""".strip()
def make_link(md, rel, target, label):
a = etree.Element('a')
a.set('href', target)
if rel:
a.set('rel', rel)
a.text = label or target
return a
class SemanticWikiLinkExtension(markdown.Extension):
def __init__(self, configs):
self.config = {
'make_link': [make_link, 'Callback to convert link parts into an HTML/etree element'],
'namespace': ['aa', 'Default namespace']
}
# Override defaults with user settings
for key, value in configs:
self.setConfig(key, value)
def extendMarkdown(self, md, md_globals):
self.md = md
# append to end of inline patterns
ext = SemanticWikiLinkPattern(self.config, md)
md.inlinePatterns.add('semanticwikilink', ext, "<not_strong")
class SemanticWikiLinkPattern(markdown.inlinepatterns.Pattern):
def __init__(self, config, md=None):
markdown.inlinepatterns.Pattern.__init__(self, '', md)
self.compiled_re = re.compile("^(.*?)%s(.*?)$" % WIKILINK_RE, re.DOTALL | re.X)
self.config = config
def getCompiledRegExp(self):
return self.compiled_re
def handleMatch(self, m):
""" Returns etree """
d = m.groupdict()
fn = self.config['make_link'][0]
namespace = d.get("namespace") or self.config['namespace'][0]
rel = d.get("rel")
if rel:
rel = "%s:%s" % (namespace, d.get("rel"))
return fn(self.markdown, rel, d.get("target"), d.get("label"))
def makeExtension(configs={}):
return SemanticWikiLinkExtension(configs=configs)
if __name__ == "__main__":
import doctest
doctest.testmod()