Merge: doc: fixed some typos and other misc. corrections
[nit.git] / lib / markdown / decorators.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 # Decorators for `markdown` parsing.
16 module decorators
17
18 import markdown
19
20 # `Decorator` that outputs markdown.
21 class MdDecorator
22 super Decorator
23
24 redef var headlines = new ArrayMap[String, HeadLine]
25
26 redef fun add_ruler(v, block) do v.add "***\n"
27
28 redef fun add_headline(v, block) do
29 # save headline
30 var txt = block.block.first_line.as(not null).value
31 var id = strip_id(txt)
32 var lvl = block.depth
33 headlines[id] = new HeadLine(id, txt, lvl)
34 v.add "{"#" * lvl} "
35 v.emit_in block
36 v.addn
37 end
38
39 redef fun add_paragraph(v, block) do
40 v.emit_in block
41 v.addn
42 end
43
44 redef fun add_code(v, block) do
45 if block isa BlockFence and block.meta != null then
46 v.add "~~~{block.meta.as(not null).to_s}"
47 else
48 v.add "~~~"
49 end
50 v.addn
51 v.emit_in block
52 v.add "~~~"
53 v.addn
54 end
55
56 redef fun add_blockquote(v, block) do
57 v.add "> "
58 v.emit_in block
59 v.addn
60 end
61
62 redef fun add_unorderedlist(v, block) do
63 in_unorderedlist = true
64 v.emit_in block
65 in_unorderedlist = false
66 end
67 private var in_unorderedlist = false
68
69 redef fun add_orderedlist(v, block) do
70 in_orderedlist = true
71 current_li = 0
72 v.emit_in block
73 in_orderedlist = false
74 end
75 private var in_orderedlist = false
76 private var current_li = 0
77
78 redef fun add_listitem(v, block) do
79 if in_unorderedlist then
80 v.add "* "
81 else if in_orderedlist then
82 current_li += 1
83 v.add "{current_li} "
84 end
85 v.emit_in block
86 v.addn
87 end
88
89 redef fun add_em(v, text) do
90 v.add "*"
91 v.add text
92 v.add "*"
93 end
94
95 redef fun add_strong(v, text) do
96 v.add "**"
97 v.add text
98 v.add "**"
99 end
100
101 redef fun add_strike(v, text) do
102 v.add "~~"
103 v.add text
104 v.add "~~"
105 end
106
107 redef fun add_image(v, link, name, comment) do
108 v.add "!["
109 v.add name
110 v.add "]("
111 append_value(v, link)
112 if comment != null and not comment.is_empty then
113 v.add " "
114 append_value(v, comment)
115 end
116 v.add ")"
117 end
118
119 redef fun add_link(v, link, name, comment) do
120 v.add "["
121 v.add name
122 v.add "]("
123 append_value(v, link)
124 if comment != null and not comment.is_empty then
125 v.add " "
126 append_value(v, comment)
127 end
128 v.add ")"
129 end
130
131 redef fun add_abbr(v, name, comment) do
132 v.add "<abbr title=\""
133 append_value(v, comment)
134 v.add "\">"
135 v.emit_text(name)
136 v.add "</abbr>"
137 end
138
139 redef fun add_span_code(v, text, from, to) do
140 v.add "`"
141 append_code(v, text, from, to)
142 v.add "`"
143 end
144
145 redef fun add_line_break(v) do
146 v.add "\n"
147 end
148
149 redef fun append_value(v, text) do for c in text do escape_char(v, c)
150
151 redef fun escape_char(v, c) do v.addc(c)
152
153 redef fun append_code(v, buffer, from, to) do
154 for i in [from..to[ do
155 v.addc buffer[i]
156 end
157 end
158
159 redef fun strip_id(txt) do
160 # strip id
161 var b = new FlatBuffer
162 for c in txt do
163 if c == ' ' then
164 b.add '_'
165 else
166 if not c.is_letter and
167 not c.is_digit and
168 not allowed_id_chars.has(c) then continue
169 b.add c
170 end
171 end
172 var res = b.to_s
173 var key = res
174 # check for multiple id definitions
175 if headlines.has_key(key) then
176 var i = 1
177 key = "{res}_{i}"
178 while headlines.has_key(key) do
179 i += 1
180 key = "{res}_{i}"
181 end
182 end
183 return key
184 end
185
186 private var allowed_id_chars: Array[Char] = ['-', '_', ':', '.']
187 end
188
189 # Decorator for span elements.
190 #
191 # InlineDecorator does not decorate things like paragraphs or headers.
192 class InlineDecorator
193 super HTMLDecorator
194
195 redef fun add_paragraph(v, block) do v.emit_in block
196 redef fun add_headline(v, block) do v.emit_in block
197
198 redef fun add_code(v, block) do
199 v.add "<code>"
200 v.emit_in block
201 v.add "</code>"
202 end
203 end