diff --git a/lib/coderay/encoders/html.rb b/lib/coderay/encoders/html.rb index 942b9c89..b6db0514 100644 --- a/lib/coderay/encoders/html.rb +++ b/lib/coderay/encoders/html.rb @@ -199,13 +199,11 @@ def finish options end if @out.respond_to? :to_str - @out.extend Output - @out.css = @css if options[:line_numbers] Numbering.number! @out, options[:line_numbers], options end - @out.wrap! options[:wrap] - @out.apply_title! options[:title] + @out = Output.wrap_string_in @out, options[:wrap], @css if options[:wrap] + @out = @out.sub(/()(<\/title>)/) { $1 + options[:title] + $2 } if options[:title] end if defined?(@real_out) && @real_out @@ -274,6 +272,10 @@ def check_options! options raise ArgumentError, 'Unknown value %p for :css.' % [options[:css]] end + unless [nil, false, :span, :div, :page].include? options[:wrap] + raise ArgumentError, 'Unknown value %p for :wrap.' % [options[:wrap]] + end + options[:break_lines] = true if options[:line_numbers] == :inline end diff --git a/lib/coderay/encoders/html/numbering.rb b/lib/coderay/encoders/html/numbering.rb index a1b9c04a..9c2d679f 100644 --- a/lib/coderay/encoders/html/numbering.rb +++ b/lib/coderay/encoders/html/numbering.rb @@ -1,10 +1,7 @@ module CodeRay module Encoders - class HTML - module Numbering # :nodoc: - def self.number! output, mode = :table, options = {} return self unless mode @@ -12,7 +9,7 @@ def self.number! output, mode = :table, options = {} start = options[:line_number_start] unless start.is_a? Integer - raise ArgumentError, "Invalid value %p for :line_number_start; Integer expected." % start + raise ArgumentError, "Invalid value %p for :line_number_start; Integer expected." % [start] end anchor_prefix = options[:line_number_anchors] @@ -53,7 +50,7 @@ def self.number! output, mode = :table, options = {} end end else - raise ArgumentError, 'Invalid value %p for :bolding; false or Integer expected.' % bold_every + raise ArgumentError, 'Invalid value %p for :bolding; false or Integer expected.' % [bold_every] end if position_of_last_newline = output.rindex(RUBY_VERSION >= '1.9' ? /\n/ : ?\n) @@ -83,26 +80,25 @@ def self.number! output, mode = :table, options = {} 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) + line_numbers_table_template = TABLE.sub('<%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.' + output.replace line_numbers_table_template.sub('<%CONTENT%>', output) else - raise ArgumentError, 'Unknown value %p for mode: expected one of %p' % - [mode, [:table, :inline]] + raise ArgumentError, 'Unknown value %p for mode: expected one of %p' % [mode, [:table, :inline]] end output end + TABLE = <<-TABLE +<table class="CodeRay"><tr> + <td class="line-numbers"><pre><%LINE_NUMBERS%></pre></td> + <td class="code"><pre><%CONTENT%></pre></td> +</tr></table> + TABLE end - end - end end diff --git a/lib/coderay/encoders/html/output.rb b/lib/coderay/encoders/html/output.rb index de6f6ea1..66ff0ba5 100644 --- a/lib/coderay/encoders/html/output.rb +++ b/lib/coderay/encoders/html/output.rb @@ -1,135 +1,41 @@ module CodeRay module Encoders - class HTML - - # This module is included in the output String of the HTML Encoder. - # - # It provides methods like wrap, div, page etc. - # - # Remember to use #clone instead of #dup to keep the modules the object was - # extended with. - # - # TODO: Rewrite this without monkey patching. module Output - - attr_accessor :css - - class << self - - # Raises an exception if an object that doesn't respond to to_str is extended by Output, - # to prevent users from misuse. Use Module#remove_method to disable. - def extended o # :nodoc: - warn "The Output module is intended to extend instances of String, not #{o.class}." unless o.respond_to? :to_str - end - - def make_stylesheet css, in_tag = false # :nodoc: - sheet = css.stylesheet - sheet = <<-'CSS' if in_tag -<style type="text/css"> -#{sheet} -</style> - CSS - sheet - end - - def page_template_for_css css # :nodoc: - sheet = make_stylesheet css - PAGE.apply 'CSS', sheet - end - - end - - def wrapped_in? element - wrapped_in == element - end - - def wrapped_in - @wrapped_in ||= nil - end - attr_writer :wrapped_in - - def wrap_in! template - Template.wrap! self, template, 'CONTENT' - self - end - - def apply_title! title - self.sub!(/(<title>)(<\/title>)/) { $1 + title + $2 } - self - end - - def wrap! element, *args - return self if not element or element == wrapped_in + def self.wrap_string_in string, element, css = nil case element - when :div - raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? nil - wrap_in! DIV when :span - raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? nil - wrap_in! SPAN + SPAN + when :div + return string if string[/\A<(?:div|table)\b/] + DIV when :page - wrap! :div if wrapped_in? nil - raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? :div - wrap_in! Output.page_template_for_css(@css) - if args.first.is_a?(Hash) && title = args.first[:title] - apply_title! title - end - self - when nil - return self + string = wrap_string_in(string, :div) unless string[/\A<(?:div|table)\b/] + PAGE.sub('<%CSS%>', css ? css.stylesheet : '') else - raise "Unknown value %p for :wrap" % element - end - @wrapped_in = element - self - end - - def stylesheet in_tag = false - Output.make_stylesheet @css, in_tag + raise ArgumentError, 'Unknown wrap element: %p' % [element] + end.sub('<%CONTENT%>', string) end - -#-- don't include the templates in docu - - class Template < String # :nodoc: - - def self.wrap! str, template, target - target = Regexp.new(Regexp.escape("<%#{target}%>")) - if template =~ target - str[0,0] = $` - str << $' - else - raise "Template target <%%%p%%> not found" % target - end - end - - def apply target, replacement - target = Regexp.new(Regexp.escape("<%#{target}%>")) - if self =~ target - Template.new($` + replacement + $') - else - raise "Template target <%%%p%%> not found" % target - end + + def self.wrap! str, template, target + target = Regexp.new(Regexp.escape("<%#{target}%>")) + if template =~ target + str[0,0] = $` + str << $' + else + raise "Template target <%%%p%%> not found" % target end - end - - SPAN = Template.new '<span class="CodeRay"><%CONTENT%></span>' - - DIV = Template.new <<-DIV + + SPAN = '<span class="CodeRay"><%CONTENT%></span>' + + DIV = <<-DIV <div class="CodeRay"> <div class="code"><pre><%CONTENT%></pre></div> </div> DIV - - TABLE = Template.new <<-TABLE -<table class="CodeRay"><tr> - <td class="line-numbers"><pre><%LINE_NUMBERS%></pre></td> - <td class="code"><pre><%CONTENT%></pre></td> -</tr></table> - TABLE - - PAGE = Template.new <<-PAGE + + PAGE = <<-PAGE <!DOCTYPE html> <html> <head> @@ -157,10 +63,7 @@ def apply target, replacement </body> </html> PAGE - end - end - end end