summaryrefslogtreecommitdiffstats
path: root/vendor/plugins/coderay-0.7.6.227/lib/coderay/encoders/html/numerization.rb
blob: 1e4a4ed539b286ac6d6651d253aa0627bc058fdc (plain)
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
module CodeRay
module Encoders

  class HTML

    module Output

      def numerize *args
        clone.numerize!(*args)
      end

=begin      NUMERIZABLE_WRAPPINGS = {
        :table => [:div, :page, nil],
        :inline => :all,
        :list => [:div, :page, nil]
      }
      NUMERIZABLE_WRAPPINGS.default = :all
=end
      def numerize! mode = :table, options = {}
        return self unless mode

        options = DEFAULT_OPTIONS.merge options

        start = options[:line_number_start]
        unless start.is_a? Integer
          raise ArgumentError, "Invalid value %p for :line_number_start; Integer expected." % start
        end

        #allowed_wrappings = NUMERIZABLE_WRAPPINGS[mode]
        #unless allowed_wrappings == :all or allowed_wrappings.include? options[:wrap]
        #  raise ArgumentError, "Can't numerize, :wrap must be in %p, but is %p" % [NUMERIZABLE_WRAPPINGS, options[:wrap]]
        #end

        bold_every = options[:bold_every]
        bolding =
          if bold_every == false
            proc { |line| line.to_s }
          elsif bold_every.is_a? Integer
            raise ArgumentError, ":bolding can't be 0." if bold_every == 0
            proc do |line|
              if line % bold_every == 0
                "<strong>#{line}</strong>"  # every bold_every-th number in bold
              else
                line.to_s
              end
            end
          else
            raise ArgumentError, 'Invalid value %p for :bolding; false or Integer expected.' % bold_every
          end

        case mode
        when :inline
          max_width = (start + line_count).to_s.size
          line = start
          gsub!(/^/) do
            line_number = bolding.call line
            indent = ' ' * (max_width - line.to_s.size)
            res = "<span class=\"no\">#{indent}#{line_number}</span> "
            line += 1
            res
          end

        when :table
          # This is really ugly.
          # Because even monospace fonts seem to have different heights when bold,
          # I make the newline bold, both in the code and the line numbers.
          # FIXME Still not working perfect for Mr. Internet Exploder
          # FIXME Firefox struggles with very long codes (> 200 lines)
          line_numbers = (start ... start + line_count).to_a.map(&bolding).join("\n")
          line_numbers << "\n"  # also for Mr. MS Internet Exploder :-/
          line_numbers.gsub!(/\n/) { "<tt>\n</tt>" }

          line_numbers_table_tpl = TABLE.apply('LINE_NUMBERS', line_numbers)
          gsub!(/\n/) { "<tt>\n</tt>" }
          wrap_in! line_numbers_table_tpl
          @wrapped_in = :div

        when :list
          opened_tags = []
          gsub!(/^.*$\n?/) do |line|
            line.chomp!

            open = opened_tags.join
            line.scan(%r!<(/)?span[^>]*>?!) do |close,|
              if close
                opened_tags.pop
              else
                opened_tags << $&
              end
            end
            close = '</span>' * opened_tags.size

            "<li>#{open}#{line}#{close}</li>"
          end
          wrap_in! LIST
          @wrapped_in = :div

        else
          raise ArgumentError, 'Unknown value %p for mode: expected one of %p' %
            [mode, [:table, :list, :inline]]
        end

        self
      end

      def line_count
        line_count = count("\n")
        position_of_last_newline = rindex(?\n)
        if position_of_last_newline
          after_last_newline = self[position_of_last_newline + 1 .. -1]
          ends_with_newline = after_last_newline[/\A(?:<\/span>)*\z/]
          line_count += 1 if not ends_with_newline
        end
        line_count
      end

    end

  end

end
end