Merge: Apply serialization in calculator, a_star, more_collections, Couple and Container
[nit.git] / lib / markdown / decorators.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at
5 #
6 # http://www.apache.org/licenses/LICENSE-2.0
7 #
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
13
14 # Decorators for `markdown` parsing.
15 module decorators
16
17 import markdown
18
19 # `Decorator` that outputs markdown.
20 class MdDecorator
21 super Decorator
22
23 redef var headlines = new ArrayMap[String, HeadLine]
24
25 redef fun add_ruler(v, block) do v.add "***\n"
26
27 redef fun add_headline(v, block) do
28 # save headline
29 var txt = block.block.first_line.value
30 var id = strip_id(txt)
31 var lvl = block.depth
32 headlines[id] = new HeadLine(id, txt, lvl)
33 v.add "{"#" * lvl} "
34 v.emit_in block
35 v.addn
36 end
37
38 redef fun add_paragraph(v, block) do
39 v.emit_in block
40 v.addn
41 end
42
43 redef fun add_code(v, block) do
44 if block isa BlockFence and block.meta != null then
45 v.add "~~~{block.meta.to_s}"
46 else
47 v.add "~~~"
48 end
49 v.addn
50 v.emit_in block
51 v.add "~~~"
52 v.addn
53 end
54
55 redef fun add_blockquote(v, block) do
56 v.add "> "
57 v.emit_in block
58 v.addn
59 end
60
61 redef fun add_unorderedlist(v, block) do
62 in_unorderedlist = true
63 v.emit_in block
64 in_unorderedlist = false
65 end
66 private var in_unorderedlist = false
67
68 redef fun add_orderedlist(v, block) do
69 in_orderedlist = true
70 current_li = 0
71 v.emit_in block
72 in_unorderedlist = false
73 end
74 private var in_orderedlist = false
75 private var current_li = 0
76
77 redef fun add_listitem(v, block) do
78 if in_unorderedlist then
79 v.add "* "
80 else if in_orderedlist then
81 current_li += 1
82 v.add "{current_li} "
83 end
84 v.emit_in block
85 v.addn
86 end
87
88 redef fun add_em(v, text) do
89 v.add "*"
90 v.add text
91 v.add "*"
92 end
93
94 redef fun add_strong(v, text) do
95 v.add "**"
96 v.add text
97 v.add "**"
98 end
99
100 redef fun add_strike(v, text) do
101 v.add "~~"
102 v.add text
103 v.add "~~"
104 end
105
106 redef fun add_image(v, link, name, comment) do
107 v.add "!["
108 v.add name
109 v.add "]("
110 append_value(v, link)
111 if comment != null and not comment.is_empty then
112 v.add " "
113 append_value(v, comment)
114 end
115 v.add ")"
116 end
117
118 redef fun add_link(v, link, name, comment) do
119 v.add "["
120 v.add name
121 v.add "]("
122 append_value(v, link)
123 if comment != null and not comment.is_empty then
124 v.add " "
125 append_value(v, comment)
126 end
127 v.add ")"
128 end
129
130 redef fun add_abbr(v, name, comment) do
131 v.add "<abbr title=\""
132 append_value(v, comment)
133 v.add "\">"
134 v.emit_text(name)
135 v.add "</abbr>"
136 end
137
138 redef fun add_span_code(v, text, from, to) do
139 v.add "`"
140 append_code(v, text, from, to)
141 v.add "`"
142 end
143
144 redef fun add_line_break(v) do
145 v.add "\n"
146 end
147
148 redef fun append_value(v, text) do for c in text do escape_char(v, c)
149
150 redef fun escape_char(v, c) do v.addc(c)
151
152 redef fun append_code(v, buffer, from, to) do
153 for i in [from..to[ do
154 v.addc buffer[i]
155 end
156 end
157
158 redef fun strip_id(txt) do
159 # strip id
160 var b = new FlatBuffer
161 for c in txt do
162 if c == ' ' then
163 b.add '_'
164 else
165 if not c.is_letter and
166 not c.is_digit and
167 not allowed_id_chars.has(c) then continue
168 b.add c
169 end
170 end
171 var res = b.to_s
172 var key = res
173 # check for multiple id definitions
174 if headlines.has_key(key) then
175 var i = 1
176 key = "{res}_{i}"
177 while headlines.has_key(key) do
178 i += 1
179 key = "{res}_{i}"
180 end
181 end
182 return key
183 end
184
185 private var allowed_id_chars: Array[Char] = ['-', '_', ':', '.']
186 end