markdown :: HTMLDecorator :: defaultinit
# `Decorator` that outputs HTML.
class HTMLDecorator
super Decorator
redef var headlines = new ArrayMap[String, HeadLine]
redef fun add_ruler(v, block) do v.add "<hr/>\n"
redef fun add_headline(v, block) do
# save headline
var line = block.block.first_line
if line == null then return
var txt = line.value
var id = strip_id(txt)
var lvl = block.depth
headlines[id] = new HeadLine(id, txt, lvl)
# output it
v.add "<h{lvl} id=\"{id}\">"
v.emit_in block
v.add "</h{lvl}>\n"
end
redef fun add_paragraph(v, block) do
v.add "<p>"
v.emit_in block
v.add "</p>\n"
end
redef fun add_code(v, block) do
var meta = block.meta
if meta != null then
v.add "<pre class=\""
append_value(v, meta)
v.add "\"><code>"
else
v.add "<pre><code>"
end
v.emit_in block
v.add "</code></pre>\n"
end
redef fun add_blockquote(v, block) do
v.add "<blockquote>\n"
v.emit_in block
v.add "</blockquote>\n"
end
redef fun add_unorderedlist(v, block) do
v.add "<ul>\n"
v.emit_in block
v.add "</ul>\n"
end
redef fun add_orderedlist(v, block) do
v.add "<ol>\n"
v.emit_in block
v.add "</ol>\n"
end
redef fun add_listitem(v, block) do
v.add "<li>"
v.emit_in block
v.add "</li>\n"
end
redef fun add_em(v, text) do
v.add "<em>"
v.add text
v.add "</em>"
end
redef fun add_strong(v, text) do
v.add "<strong>"
v.add text
v.add "</strong>"
end
redef fun add_strike(v, text) do
v.add "<del>"
v.add text
v.add "</del>"
end
redef fun add_image(v, link, name, comment) do
v.add "<img src=\""
append_value(v, link)
v.add "\" alt=\""
append_value(v, name)
v.add "\""
if comment != null and not comment.is_empty then
v.add " title=\""
append_value(v, comment)
v.add "\""
end
v.add "/>"
end
redef fun add_link(v, link, name, comment) do
v.add "<a href=\""
append_value(v, link)
v.add "\""
if comment != null and not comment.is_empty then
v.add " title=\""
append_value(v, comment)
v.add "\""
end
v.add ">"
v.emit_text(name)
v.add "</a>"
end
redef fun add_abbr(v, name, comment) do
v.add "<abbr title=\""
append_value(v, comment)
v.add "\">"
v.emit_text(name)
v.add "</abbr>"
end
redef fun add_span_code(v, text, from, to) do
v.add "<code>"
append_code(v, text, from, to)
v.add "</code>"
end
redef fun add_line_break(v) do
v.add "<br/>"
end
redef fun append_value(v, text) do for c in text do escape_char(v, c)
redef fun escape_char(v, c) do
if c == '&' then
v.add "&"
else if c == '<' then
v.add "<"
else if c == '>' then
v.add ">"
else if c == '"' then
v.add """
else if c == '\'' then
v.add "'"
else
v.addc c
end
end
redef fun append_code(v, buffer, from, to) do
for i in [from..to[ do
var c = buffer[i]
if c == '&' then
v.add "&"
else if c == '<' then
v.add "<"
else if c == '>' then
v.add ">"
else
v.addc c
end
end
end
redef fun strip_id(txt) do
# strip id
var b = new FlatBuffer
for c in txt do
if c == ' ' then
b.add '_'
else
if not c.is_letter and
not c.is_digit and
not allowed_id_chars.has(c) then continue
b.add c
end
end
var res = b.to_s
var key = res
# check for multiple id definitions
if headlines.has_key(key) then
var i = 1
key = "{res}_{i}"
while headlines.has_key(key) do
i += 1
key = "{res}_{i}"
end
end
return key
end
private var allowed_id_chars: Array[Char] = ['-', '_', ':', '.']
end
lib/markdown/markdown.nit:729,1--919,3