comparison vendor/gems/coderay-1.0.0/lib/coderay/encoders/html/numbering.rb @ 909:cbb26bc654de redmine-1.3

Update to Redmine 1.3-stable branch (Redmine SVN rev 8964)
author Chris Cannam
date Fri, 24 Feb 2012 19:09:32 +0000
parents
children
comparison
equal deleted inserted replaced
908:c6c2cbd0afee 909:cbb26bc654de
1 module CodeRay
2 module Encoders
3
4 class HTML
5
6 module Numbering # :nodoc:
7
8 def self.number! output, mode = :table, options = {}
9 return self unless mode
10
11 options = DEFAULT_OPTIONS.merge options
12
13 start = options[:line_number_start]
14 unless start.is_a? Integer
15 raise ArgumentError, "Invalid value %p for :line_number_start; Integer expected." % start
16 end
17
18 anchor_prefix = options[:line_number_anchors]
19 anchor_prefix = 'line' if anchor_prefix == true
20 anchor_prefix = anchor_prefix.to_s[/\w+/] if anchor_prefix
21 anchoring =
22 if anchor_prefix
23 proc do |line|
24 line = line.to_s
25 anchor = anchor_prefix + line
26 "<a href=\"##{anchor}\" name=\"#{anchor}\">#{line}</a>"
27 end
28 else
29 proc { |line| line.to_s } # :to_s.to_proc in Ruby 1.8.7+
30 end
31
32 bold_every = options[:bold_every]
33 highlight_lines = options[:highlight_lines]
34 bolding =
35 if bold_every == false && highlight_lines == nil
36 anchoring
37 elsif highlight_lines.is_a? Enumerable
38 highlight_lines = highlight_lines.to_set
39 proc do |line|
40 if highlight_lines.include? line
41 "<strong class=\"highlighted\">#{anchoring[line]}</strong>" # highlighted line numbers in bold
42 else
43 anchoring[line]
44 end
45 end
46 elsif bold_every.is_a? Integer
47 raise ArgumentError, ":bolding can't be 0." if bold_every == 0
48 proc do |line|
49 if line % bold_every == 0
50 "<strong>#{anchoring[line]}</strong>" # every bold_every-th number in bold
51 else
52 anchoring[line]
53 end
54 end
55 else
56 raise ArgumentError, 'Invalid value %p for :bolding; false or Integer expected.' % bold_every
57 end
58
59 line_count = output.count("\n")
60 position_of_last_newline = output.rindex(RUBY_VERSION >= '1.9' ? /\n/ : ?\n)
61 if position_of_last_newline
62 after_last_newline = output[position_of_last_newline + 1 .. -1]
63 ends_with_newline = after_last_newline[/\A(?:<\/span>)*\z/]
64 line_count += 1 if not ends_with_newline
65 end
66
67 case mode
68 when :inline
69 max_width = (start + line_count).to_s.size
70 line_number = start
71 nesting = []
72 output.gsub!(/^.*$\n?/) do |line|
73 line.chomp!
74 open = nesting.join
75 line.scan(%r!<(/)?span[^>]*>?!) do |close,|
76 if close
77 nesting.pop
78 else
79 nesting << $&
80 end
81 end
82 close = '</span>' * nesting.size
83
84 line_number_text = bolding.call line_number
85 indent = ' ' * (max_width - line_number.to_s.size) # TODO: Optimize (10^x)
86 line_number += 1
87 "<span class=\"line-numbers\">#{indent}#{line_number_text}</span>#{open}#{line}#{close}\n"
88 end
89
90 when :table
91 line_numbers = (start ... start + line_count).map(&bolding).join("\n")
92 line_numbers << "\n"
93 line_numbers_table_template = Output::TABLE.apply('LINE_NUMBERS', line_numbers)
94
95 output.gsub!(/<\/div>\n/, '</div>')
96 output.wrap_in! line_numbers_table_template
97 output.wrapped_in = :div
98
99 when :list
100 raise NotImplementedError, 'The :list option is no longer available. Use :table.'
101
102 else
103 raise ArgumentError, 'Unknown value %p for mode: expected one of %p' %
104 [mode, [:table, :inline]]
105 end
106
107 output
108 end
109
110 end
111
112 end
113
114 end
115 end