To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / .svn / pristine / 56 / 5616c9d52a62f8dbe0d12f53a6285e1110cf74e0.svn-base @ 1297:0a574315af3e

History | View | Annotate | Download (3.75 KB)

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