To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.
root / vendor / gems / coderay-0.9.7 / lib / coderay / encoders / html / numerization.rb @ 442:753f1380d6bc
History | View | Annotate | Download (4.12 KB)
| 1 |
module CodeRay |
|---|---|
| 2 |
module Encoders |
| 3 |
|
| 4 |
class HTML |
| 5 |
|
| 6 |
module Output |
| 7 |
|
| 8 |
def numerize *args |
| 9 |
clone.numerize!(*args) |
| 10 |
end
|
| 11 |
|
| 12 |
=begin NUMERIZABLE_WRAPPINGS = {
|
| 13 |
:table => [:div, :page, nil],
|
| 14 |
:inline => :all,
|
| 15 |
:list => [:div, :page, nil]
|
| 16 |
}
|
| 17 |
NUMERIZABLE_WRAPPINGS.default = :all
|
| 18 |
=end
|
| 19 |
def numerize! mode = :table, options = {} |
| 20 |
return self unless mode |
| 21 |
|
| 22 |
options = DEFAULT_OPTIONS.merge options
|
| 23 |
|
| 24 |
start = options[:line_number_start]
|
| 25 |
unless start.is_a? Integer |
| 26 |
raise ArgumentError, "Invalid value %p for :line_number_start; Integer expected." % start |
| 27 |
end
|
| 28 |
|
| 29 |
#allowed_wrappings = NUMERIZABLE_WRAPPINGS[mode]
|
| 30 |
#unless allowed_wrappings == :all or allowed_wrappings.include? options[:wrap]
|
| 31 |
# raise ArgumentError, "Can't numerize, :wrap must be in %p, but is %p" % [NUMERIZABLE_WRAPPINGS, options[:wrap]]
|
| 32 |
#end
|
| 33 |
|
| 34 |
bold_every = options[:bold_every]
|
| 35 |
highlight_lines = options[:highlight_lines]
|
| 36 |
bolding = |
| 37 |
if bold_every == false && highlight_lines == nil |
| 38 |
proc { |line| line.to_s }
|
| 39 |
elsif highlight_lines.is_a? Enumerable |
| 40 |
highlight_lines = highlight_lines.to_set |
| 41 |
proc do |line|
|
| 42 |
if highlight_lines.include? line
|
| 43 |
"<strong class=\"highlighted\">#{line}</strong>" # highlighted line numbers in bold |
| 44 |
else
|
| 45 |
line.to_s |
| 46 |
end
|
| 47 |
end
|
| 48 |
elsif bold_every.is_a? Integer |
| 49 |
raise ArgumentError, ":bolding can't be 0." if bold_every == 0 |
| 50 |
proc do |line|
|
| 51 |
if line % bold_every == 0 |
| 52 |
"<strong>#{line}</strong>" # every bold_every-th number in bold |
| 53 |
else
|
| 54 |
line.to_s |
| 55 |
end
|
| 56 |
end
|
| 57 |
else
|
| 58 |
raise ArgumentError, 'Invalid value %p for :bolding; false or Integer expected.' % bold_every |
| 59 |
end
|
| 60 |
|
| 61 |
case mode
|
| 62 |
when :inline |
| 63 |
max_width = (start + line_count).to_s.size |
| 64 |
line_number = start |
| 65 |
gsub!(/^/) do |
| 66 |
line_number_text = bolding.call line_number |
| 67 |
indent = ' ' * (max_width - line_number.to_s.size) # TODO: Optimize (10^x) |
| 68 |
res = "<span class=\"no\">#{indent}#{line_number_text}</span> "
|
| 69 |
line_number += 1
|
| 70 |
res |
| 71 |
end
|
| 72 |
|
| 73 |
when :table |
| 74 |
# This is really ugly.
|
| 75 |
# Because even monospace fonts seem to have different heights when bold,
|
| 76 |
# I make the newline bold, both in the code and the line numbers.
|
| 77 |
# FIXME Still not working perfect for Mr. Internet Exploder
|
| 78 |
line_numbers = (start ... start + line_count).to_a.map(&bolding).join("\n")
|
| 79 |
line_numbers << "\n" # also for Mr. MS Internet Exploder :-/ |
| 80 |
line_numbers.gsub!(/\n/) { "<tt>\n</tt>" } |
| 81 |
|
| 82 |
line_numbers_table_tpl = TABLE.apply('LINE_NUMBERS', line_numbers) |
| 83 |
gsub!("</div>\n", '</div>') |
| 84 |
gsub!("\n", "<tt>\n</tt>") |
| 85 |
wrap_in! line_numbers_table_tpl |
| 86 |
@wrapped_in = :div |
| 87 |
|
| 88 |
when :list |
| 89 |
opened_tags = [] |
| 90 |
gsub!(/^.*$\n?/) do |line| |
| 91 |
line.chomp! |
| 92 |
|
| 93 |
open = opened_tags.join |
| 94 |
line.scan(%r!<(/)?span[^>]*>?!) do |close,| |
| 95 |
if close
|
| 96 |
opened_tags.pop |
| 97 |
else
|
| 98 |
opened_tags << $&
|
| 99 |
end
|
| 100 |
end
|
| 101 |
close = '</span>' * opened_tags.size
|
| 102 |
|
| 103 |
"<li>#{open}#{line}#{close}</li>\n"
|
| 104 |
end
|
| 105 |
chomp!("\n")
|
| 106 |
wrap_in! LIST
|
| 107 |
@wrapped_in = :div |
| 108 |
|
| 109 |
else
|
| 110 |
raise ArgumentError, 'Unknown value %p for mode: expected one of %p' % |
| 111 |
[mode, [:table, :list, :inline]] |
| 112 |
end
|
| 113 |
|
| 114 |
self
|
| 115 |
end
|
| 116 |
|
| 117 |
def line_count |
| 118 |
line_count = count("\n")
|
| 119 |
position_of_last_newline = rindex(?\n)
|
| 120 |
if position_of_last_newline
|
| 121 |
after_last_newline = self[position_of_last_newline + 1 .. -1] |
| 122 |
ends_with_newline = after_last_newline[/\A(?:<\/span>)*\z/]
|
| 123 |
line_count += 1 if not ends_with_newline |
| 124 |
end
|
| 125 |
line_count |
| 126 |
end
|
| 127 |
|
| 128 |
end
|
| 129 |
|
| 130 |
end
|
| 131 |
|
| 132 |
end
|
| 133 |
end
|