1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
require 'cgi'
module Rugments
module Formatters
class HTML < Formatter
tag('html')
def initialize(
nowrap: false,
cssclass: 'highlight',
linenos: nil,
linenostart: 1,
lineanchors: false,
lineanchorsid: 'L',
anchorlinenos: false,
inline_theme: nil
)
@nowrap = nowrap
@cssclass = cssclass
@linenos = linenos
@linenostart = linenostart
@lineanchors = lineanchors
@lineanchorsid = lineanchorsid
@anchorlinenos = anchorlinenos
@inline_theme = inline_theme
end
def format(tokens)
case
when @linenos == 'table'
format_tableized(tokens)
when @linenos == 'inline'
format_untableized(tokens)
else
format_untableized(tokens)
end
end
private
def format_untableized(tokens)
data = process_tokens(tokens)
html = ''
html << "<pre class=\"#{@cssclass}\"><code>" unless @nowrap
html << create_lines(data[:code])
html << "</code></pre>\n" unless @nowrap
html
end
def format_tableized(tokens)
data = process_tokens(tokens)
html = ''
html << "<div class=\"#{@cssclass}\">\n" unless @nowrap
html << "<table><tbody>\n"
html << "<td class=\"linenos\"><pre>"
html << create_linenos(data[:numbers])
html << "</pre></td>\n"
html << "<td class=\"lines\"><pre><code>"
html << create_lines(data[:code])
html << "</code></pre></td>\n"
html << "</tbody></table>\n"
html << "</div>\n" unless @nowrap
end
def process_tokens(tokens)
num_lines = 0
last_val = ''
formatted = ''
tokens.each do |tok, val|
last_val = val
num_lines += val.scan(/\n/).size
formatted << span(tok, val)
end
numbers = (@linenostart..num_lines + @linenostart - 1).to_a
{ numbers: numbers, code: formatted }
end
def create_linenos(numbers)
if @anchorlinenos
numbers.map! do |number|
"<a href=\"##{@lineanchorsid}#{number}\">#{number}</a>"
end
end
numbers.join("\n")
end
def create_lines(formatted)
if @lineanchors
lines = formatted.split("\n")
lines = lines.each_with_index.map do |line, index|
number = index + @linenostart
if @linenos == 'inline'
"<a name=\"L#{number}\"></a>" \
"<span class=\"linenos\">#{number}</span><span id=\"#{@lineanchorsid}#{number}\" class=\"line\">#{line}</span>"
else
"<span id=\"#{@lineanchorsid}#{number}\" class=\"line\">#{line}</span>"
end
end
lines.join("\n")
else
if @linenos == 'inline'
lines = formatted.split("\n")
lines = lines.each_with_index.map do |line, index|
number = index + @linenostart
"<span class=\"linenos\">#{number}</span>#{line}"
end
lines.join("\n")
else
formatted
end
end
end
def span(tok, val)
# http://stackoverflow.com/a/1600584/2587286
val = CGI.escapeHTML(val)
if tok.shortname.empty?
val
else
if @inline_theme
theme = Theme.find(@inline_theme).new
rules = theme.style_for(tok).rendered_rules
"<span style=\"#{rules.to_a.join(';')}\">#{val}</span>"
else
"<span class=\"#{tok.shortname}\">#{val}</span>"
end
end
end
end
end
end
|