lib/markdown: merge processor and emitter
[nit.git] / lib / markdown / wikilinks.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Wikilinks handling.
16 #
17 # Wikilinks are on the form `[[link]]`.
18 # They can also contain a custom title with the syntax `[[title|link]]`.
19 #
20 # By importing this module, you enable the `MarkdownProcessor` to recognize
21 # `TokenWikiLink` but nothing will happen until you define a
22 # `Decorator::add_wikilink` customized to your applciation domain.
23 module wikilinks
24
25 intrude import markdown
26
27 # `MarkdownProcessor` is now able to parse wikilinks.
28 redef class MarkdownProcessor
29
30 redef fun token_at(text, pos) do
31 var token = super
32 if not token isa TokenLink then return token
33 if pos + 1 < text.length then
34 var c = text[pos + 1]
35 if c == '[' then return new TokenWikiLink(token.location, pos, c)
36 end
37 return token
38 end
39 end
40
41 redef class Decorator
42
43 # Renders a `[[wikilink]]` item.
44 fun add_wikilink(v: PROCESSOR, token: TokenWikiLink) do
45 if token.name != null then
46 v.add "[[{token.name.as(not null).to_s}|{token.link.as(not null).to_s}]]"
47 else
48 v.add "[[{token.link.as(not null).to_s}]]"
49 end
50 end
51 end
52
53 # A NitiWiki link token.
54 #
55 # Something of the form `[[foo]]`.
56 #
57 # Allowed formats:
58 #
59 # * `[[Wikilink]]`
60 # * `[[Wikilink/Bar]]`
61 # * `[[Wikilink#foo]]`
62 # * `[[Wikilink/Bar#foo]]`
63 # * `[[title|Wikilink]]`
64 # * `[[title|Wikilink/Bar]]`
65 # * `[[title|Wikilink/Bar#foo]]`
66 class TokenWikiLink
67 super TokenLink
68
69 redef fun emit_hyper(v) do
70 v.decorator.add_wikilink(v, self)
71 end
72
73 redef fun check_link(v, out, start, token) do
74 var md = v.current_text
75 if md == null then return -1
76 var pos = start + 2
77 var tmp = new FlatBuffer
78 pos = md.read_md_link_id(tmp, pos)
79 if pos < start then return -1
80 var name = tmp.write_to_string
81 if name.has("|") then
82 var parts = name.split_once_on("|")
83 self.name = parts.first
84 self.link = parts[1]
85 else
86 self.name = null
87 self.link = name
88 end
89 pos += 1
90 pos = md.skip_spaces(pos)
91 if pos < start then return -1
92 return pos
93 end
94 end