From 429e6734173c8317dd1945696a802e9a936cdd13 Mon Sep 17 00:00:00 2001 From: murphy Date: Sat, 5 Nov 2005 02:14:23 +0000 Subject: New helper module scheme, step 1 --- lib/coderay/encoders/html/html_numerization.rb | 112 +++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 lib/coderay/encoders/html/html_numerization.rb (limited to 'lib/coderay/encoders/html/html_numerization.rb') diff --git a/lib/coderay/encoders/html/html_numerization.rb b/lib/coderay/encoders/html/html_numerization.rb new file mode 100644 index 0000000..f51b5d3 --- /dev/null +++ b/lib/coderay/encoders/html/html_numerization.rb @@ -0,0 +1,112 @@ +module CodeRay + module Encoders + + class HTML + + module Output + + def numerize *args + clone.numerize!(*args) + end + + NUMERIZABLE_WRAPPINGS = { + :table => [:div, :page], + :inline => :all, + :list => [:div, :page], + nil => :all + } + + 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 == :no_bolding or bold_every == 0 + proc { |line| line.to_s } + elsif bold_every.is_a? Integer + proc do |line| + if line % bold_every == 0 + "#{line}" # every bold_every-th number in bold + else + line.to_s + end + end + else + raise ArgumentError, "Invalid value %p for :bolding; :no_bolding or Integer expected." % bolding + end + + line_count = count("\n") + line_count += 1 if self[-1] != ?\n + + case mode + when :inline + max_width = (start + line_count).to_s.size + line = start + gsub!(/^/) do + line_number = bolding.call line + line += 1 + "#{ line_number.rjust(max_width) } " + end + #wrap! :div + + 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/) { "\n" } + + line_numbers_table_tpl = TABLE.apply('LINE_NUMBERS', line_numbers) + gsub!(/\n/) { "\n" } + 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 = '' * opened_tags.size + + "
  • #{open}#{line}#{close}
  • " + end + wrap_in! LIST + @wrapped_in = :div + + else + raise ArgumentError, "Unknown value %p for mode: expected one of %p" % + [mode, NUMERIZABLE_WRAPPINGS.keys - [:all]] + end + + self + end + + end + + end + +end +end -- cgit v1.2.1