annotate vendor/plugins/coderay-0.9.2/lib/coderay/encoders/html/numerization.rb @ 874:12771bc38f20 feature_123

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