~widelands-dev/widelands-website/trunk

« back to all changes in this revision

Viewing changes to markdownextensions/semanticwikilinks/mdx_semanticwikilinks.py

  • Committer: franku
  • Date: 2017-01-26 14:30:55 UTC
  • mto: This revision was merged to the branch mainline in revision 451.
  • Revision ID: somal@arcor.de-20170126143055-id4ruduntyeqzd0j
Added semanticwikilinks extension to markdown and make it work

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#! /usr/bin/env python
 
2
 
 
3
 
 
4
'''
 
5
SemanticWikiLinks Extension for Python-Markdown
 
6
===============================================
 
7
 
 
8
Adds support for semantic (wiki)links (RDFa).
 
9
 
 
10
Converts links of style `[[rel :: target | label ]]`, where `rel` and `label`
 
11
are optional.
 
12
 
 
13
Customizable with `make_link` option as to what the actual element is.
 
14
 
 
15
 
 
16
Usage
 
17
-----
 
18
 
 
19
    >>> text = "Some text with a [[WikiLink]]."
 
20
    >>> html = markdown.markdown(text, ['semanticwikilinks'])
 
21
    >>> print(html)
 
22
    <p>Some text with a <a href="WikiLink">WikiLink</a>.</p>
 
23
 
 
24
    >>> text = "[[http://activearchives.org/]], [[#id|anchor]], [[../index.html|a relative link]], [[/|an absolute link]], [[/index.html|another absolute link]]"
 
25
    >>> html = markdown.markdown(text, ['semanticwikilinks'])
 
26
    >>> print(html)
 
27
    <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>
 
28
 
 
29
Define a custom URL builder:
 
30
 
 
31
    >>> from markdown.util import etree
 
32
    >>> def make_rdfa(md, rel, target, label):
 
33
    ...     # `md` is the Markdown instance
 
34
    ...     elt = etree.Element("span")
 
35
    ...     elt.set("property", rel)
 
36
    ...     elt.set("value", target)
 
37
    ...     elt.text = label or target
 
38
    ...     return elt
 
39
 
 
40
    >>> md = markdown.Markdown(extensions=['semanticwikilinks'],
 
41
    ...         extension_configs={'semanticwikilinks' : [('make_link', make_rdfa)]})
 
42
    >>> html = md.convert('[[ Speaker :: Sherry Turkle | Second Self ]]')
 
43
    >>> print(html)
 
44
    <p><span property="aa:Speaker" value="Sherry Turkle">Second Self</span></p>
 
45
 
 
46
Change the default namespace (which is "aa"):
 
47
 
 
48
    >>> md = markdown.Markdown(extensions=['semanticwikilinks'],
 
49
    ...         extension_configs={'semanticwikilinks' : [('namespace', 'mynamespace')]})
 
50
    >>> html = md.convert('[[ Speaker :: Sherry Turkle | Second Self ]]')
 
51
    >>> print(html)
 
52
    <p><a href="Sherry Turkle" rel="mynamespace:Speaker">Second Self</a></p>
 
53
 
 
54
To do
 
55
-----
 
56
 
 
57
- An optional function to wikify names? (It is already possible to achieve
 
58
this with the custom `make_link` function).
 
59
 
 
60
 
 
61
Dependencies
 
62
------------
 
63
 
 
64
* [Markdown 2.0+](http://www.freewisdom.org/projects/python-markdown/)
 
65
 
 
66
 
 
67
Copyright
 
68
---------
 
69
 
 
70
2011, 2012 [The active archives contributors](http://activearchives.org/)
 
71
2011, 2012 [Michael Murtaugh](http://automatist.org/)
 
72
2011, 2012 [Alexandre Leray](http://stdin.fr/)
 
73
 
 
74
All rights reserved.
 
75
 
 
76
This software is released under the modified BSD License. 
 
77
See LICENSE.md for details.
 
78
'''
 
79
 
 
80
 
 
81
import markdown
 
82
try: from markdown import etree
 
83
except ImportError: from markdown.util import etree
 
84
import re
 
85
 
 
86
 
 
87
__version__ = "1.1.1"
 
88
 
 
89
 
 
90
WIKILINK_RE = r"""
 
91
\[\[\s*
 
92
    (?:((?P<namespace>\w+):)?(?P<rel>[^\]#]+?) \s* ::)? \s*
 
93
    (?P<target>.+?) \s*
 
94
    (?:\| \s* (?P<label>.+?) \s*)?
 
95
\]\](?!\])
 
96
""".strip()
 
97
 
 
98
 
 
99
def make_link(md, rel, target, label):
 
100
    a = etree.Element('a')
 
101
    a.set('href', target)
 
102
    if rel:
 
103
        a.set('rel', rel)
 
104
    a.text = label or target
 
105
    return a
 
106
 
 
107
def make_wikilink(md, rel, target, label):
 
108
    # Turns a link from Syntax [[ Page Name | linktext ]]
 
109
    a = etree.Element('a')
 
110
    a.set('href', '/wiki/' + target)
 
111
    a.set('class', 'wikilink')
 
112
    if rel:
 
113
        pass
 
114
    a.text = label
 
115
    return a
 
116
 
 
117
class SemanticWikiLinkExtension(markdown.Extension):
 
118
    def __init__(self, *args, **kwargs):
 
119
        self.config = {
 
120
            'make_link': [make_wikilink, 'Callback to convert link parts into an HTML/etree element'],
 
121
            'namespace': ['aa', 'Default namespace'],
 
122
        }
 
123
        super(SemanticWikiLinkExtension, self).__init__(*args, **kwargs)
 
124
 
 
125
    def extendMarkdown(self, md, md_globals):
 
126
        self.md = md
 
127
 
 
128
        # append to end of inline patterns
 
129
        ext = SemanticWikiLinkPattern(self.config, md)
 
130
        md.inlinePatterns.add('semanticwikilink', ext, "<not_strong")
 
131
 
 
132
 
 
133
class SemanticWikiLinkPattern(markdown.inlinepatterns.Pattern):
 
134
    def __init__(self, config, md=None):
 
135
        markdown.inlinepatterns.Pattern.__init__(self, '', md)
 
136
        self.compiled_re = re.compile("^(.*?)%s(.*?)$" % WIKILINK_RE, re.DOTALL | re.X)
 
137
        self.config = config
 
138
 
 
139
    def getCompiledRegExp(self):
 
140
        return self.compiled_re
 
141
 
 
142
    def handleMatch(self, m):
 
143
        """ Returns etree """
 
144
        d = m.groupdict()
 
145
        fn = self.config['make_link'][0]
 
146
        namespace = d.get("namespace") or self.config['namespace'][0]
 
147
        rel = d.get("rel")
 
148
 
 
149
        if rel:
 
150
            rel = "%s:%s" % (namespace, d.get("rel"))
 
151
 
 
152
        return fn(self.markdown, rel, d.get("target"), d.get("label"))
 
153
 
 
154
 
 
155
def makeExtension(*args, **kwargs):
 
156
    return SemanticWikiLinkExtension(*args, **kwargs)
 
157
 
 
158
 
 
159
if __name__ == "__main__":
 
160
    import doctest
 
161
    doctest.testmod()