Merge: src/model/model_index: model index uses BKTree
[nit.git] / lib / markdown2 / 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 # Markdown wikilinks processing
16 #
17 # Enables parsing of `[[wikilinks]]` syntax.
18 module markdown_wikilinks
19
20 intrude import markdown_inline_parsing
21 intrude import markdown_block_parsing
22
23 redef class MdParser
24
25 # Enable wikilinks mode
26 var wikilinks_mode = false is writable
27
28 redef var inline_parser is lazy do
29 var parser = super
30 parser.wikilinks_mode = wikilinks_mode
31 return parser
32 end
33 end
34
35 redef class MdInlineParser
36
37 # Enable wikilinks mode
38 private var wikilinks_mode = false
39
40 redef fun parse_wikilink do
41 if not wikilinks_mode then return false
42
43 # do we have two opening bracket?
44 var last_bracket = self.last_bracket
45 if last_bracket == null then return false
46 var first_bracket = last_bracket.prev
47 if first_bracket == null then return false
48
49 # was the first bracket an image?
50 if first_bracket.is_image then return false
51
52 # do we have two closing brackets?
53 if index >= input.length or input.chars[index] != ']' then return false
54
55 advance 1 # skip last bracket
56 var start_index = first_bracket.index + 2
57 var end_index = index - 2
58
59 # create wikilink node
60 var content = input.substring(start_index, end_index - start_index)
61 var parts = content.split("|")
62 var title = if parts.length > 1 then parts.first.trim else null
63 var link = parts.last.trim
64
65 var wikilink = new MdWikilink(
66 new MdLocation(
67 first_bracket.node.location.line_start,
68 first_bracket.node.location.column_start - 1,
69 line,
70 column - 1),
71 link, title)
72
73 var node = last_bracket.node.next
74 var in_link = false
75 while node != null do
76 var next = node.next
77 if not in_link then
78 if node isa MdText and node.literal.has("|") then
79 var buf = new Buffer
80 for c in node.literal.chars do
81 if c == '|' then
82 in_link = true
83 break
84 end
85 buf.add c
86 end
87 node.literal = buf.write_to_string.r_trim
88 end
89 wikilink.append_child(node)
90 else
91 node.unlink
92 end
93 node = next
94 end
95
96 append_node(wikilink)
97
98 # Process delimiters such as emphasis inside a link/image
99 process_delimiters(last_bracket.prev_delimiter)
100 merge_child_text_nodes(wikilink)
101
102 # remove brackets
103 first_bracket.node.unlink
104 last_bracket.node.unlink
105
106 return true
107 end
108 end
109
110 # A Wikilink node
111 class MdWikilink
112 super MdNode
113
114 # Wikilink link
115 var link: String is writable
116
117 # Wikilink title
118 var title: nullable String = null is optional, writable
119 end