view vendor/gems/coderay-1.0.0/lib/coderay/encoders/html/numbering.rb @ 1082:997f6d7738f7 bug_531

In repo controller entry action, show the page for the file even if it's binary (so user still has access to history etc links). This makes it possible to use the entry action as the default when a file is clicked on
author Chris Cannam <chris.cannam@soundsoftware.ac.uk>
date Thu, 22 Nov 2012 18:04:17 +0000
parents cbb26bc654de
children
line wrap: on
line source
module CodeRay
module Encoders

  class HTML

    module Numbering  # :nodoc:

      def self.number! output, 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
        
        anchor_prefix = options[:line_number_anchors]
        anchor_prefix = 'line' if anchor_prefix == true
        anchor_prefix = anchor_prefix.to_s[/\w+/] if anchor_prefix
        anchoring =
          if anchor_prefix
            proc do |line|
              line = line.to_s
              anchor = anchor_prefix + line
              "<a href=\"##{anchor}\" name=\"#{anchor}\">#{line}</a>"
            end
          else
            proc { |line| line.to_s }  # :to_s.to_proc in Ruby 1.8.7+
          end
        
        bold_every = options[:bold_every]
        highlight_lines = options[:highlight_lines]
        bolding =
          if bold_every == false && highlight_lines == nil
            anchoring
          elsif highlight_lines.is_a? Enumerable
            highlight_lines = highlight_lines.to_set
            proc do |line|
              if highlight_lines.include? line
                "<strong class=\"highlighted\">#{anchoring[line]}</strong>"  # highlighted line numbers in bold
              else
                anchoring[line]
              end
            end
          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>#{anchoring[line]}</strong>"  # every bold_every-th number in bold
              else
                anchoring[line]
              end
            end
          else
            raise ArgumentError, 'Invalid value %p for :bolding; false or Integer expected.' % bold_every
          end
        
        line_count = output.count("\n")
        position_of_last_newline = output.rindex(RUBY_VERSION >= '1.9' ? /\n/ : ?\n)
        if position_of_last_newline
          after_last_newline = output[position_of_last_newline + 1 .. -1]
          ends_with_newline = after_last_newline[/\A(?:<\/span>)*\z/]
          line_count += 1 if not ends_with_newline
        end
        
        case mode
        when :inline
          max_width = (start + line_count).to_s.size
          line_number = start
          nesting = []
          output.gsub!(/^.*$\n?/) do |line|
            line.chomp!
            open = nesting.join
            line.scan(%r!<(/)?span[^>]*>?!) do |close,|
              if close
                nesting.pop
              else
                nesting << $&
              end
            end
            close = '</span>' * nesting.size
            
            line_number_text = bolding.call line_number
            indent = ' ' * (max_width - line_number.to_s.size)  # TODO: Optimize (10^x)
            line_number += 1
            "<span class=\"line-numbers\">#{indent}#{line_number_text}</span>#{open}#{line}#{close}\n"
          end

        when :table
          line_numbers = (start ... start + line_count).map(&bolding).join("\n")
          line_numbers << "\n"
          line_numbers_table_template = Output::TABLE.apply('LINE_NUMBERS', line_numbers)

          output.gsub!(/<\/div>\n/, '</div>')
          output.wrap_in! line_numbers_table_template
          output.wrapped_in = :div

        when :list
          raise NotImplementedError, 'The :list option is no longer available. Use :table.'

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

        output
      end

    end

  end

end
end