diff options
-rw-r--r-- | coderay.gemspec | 2 | ||||
-rw-r--r-- | lib/coderay/encoders/html.rb | 40 | ||||
-rw-r--r-- | lib/coderay/helpers/plugin_host.rb | 20 | ||||
-rwxr-xr-x | test/functional/basic.rb | 9 | ||||
-rwxr-xr-x | test/functional/examples.rb | 14 | ||||
-rw-r--r-- | test/functional/for_redcloth.rb | 8 | ||||
-rw-r--r-- | test/unit/html.rb | 10 |
7 files changed, 48 insertions, 55 deletions
diff --git a/coderay.gemspec b/coderay.gemspec index 328b94c..6da3e1d 100644 --- a/coderay.gemspec +++ b/coderay.gemspec @@ -32,4 +32,6 @@ Gem::Specification.new do |s| s.rubyforge_project = s.name s.rdoc_options = '-SNw2', "-m#{readme_file}", '-t CodeRay Documentation' s.extra_rdoc_files = readme_file + + s.add_dependency 'escape_utils', '>= 1.0' end diff --git a/lib/coderay/encoders/html.rb b/lib/coderay/encoders/html.rb index 55b1291..0365022 100644 --- a/lib/coderay/encoders/html.rb +++ b/lib/coderay/encoders/html.rb @@ -1,4 +1,5 @@ require 'set' +require 'escape_utils' module CodeRay module Encoders @@ -127,21 +128,6 @@ module Encoders protected - def self.make_html_escape_hash - { - '&' => '&', - '>' => '>', - '<' => '<', - "\t" => ' ' * DEFAULT_OPTIONS[:tab_width], - }.tap do |hash| - # Escape ASCII control codes except \x9 == \t and \xA == \n. - (Array(0x00..0x8) + Array(0xB..0x1F)).each { |invalid| hash[invalid.chr] = ' ' } - end - end - - HTML_ESCAPE = make_html_escape_hash - HTML_ESCAPE_PATTERN = /[\t&><\0-\x8\xB-\x1F]/ - TOKEN_KIND_TO_INFO = Hash.new do |h, kind| h[kind] = kind.to_s.gsub(/_/, ' ').gsub(/\b\w/) { $&.capitalize } end @@ -180,8 +166,6 @@ module Encoders @break_lines = (options[:break_lines] == true) - @escape_cache = make_escape_cache(options) - @opened = [] @last_opened = nil @css = CSS.new options[:style] @@ -220,7 +204,7 @@ module Encoders def text_token text, kind style = @span_for_kinds[@last_opened ? [kind, *@opened] : kind] - text = @escape_cache[text] if text.size <= 1 || text =~ /#{HTML_ESCAPE_PATTERN}/o + text = EscapeUtils.escape_html text, false text = break_lines(text, style) if @break_lines && (style || @opened.size > 0) && text.index("\n") if style @@ -276,26 +260,6 @@ module Encoders options[:break_lines] = true if options[:line_numbers] == :inline end - def make_escape_cache options - html_escape = - if options[:tab_width] == DEFAULT_OPTIONS[:tab_width] - HTML_ESCAPE - else - HTML_ESCAPE.merge("\t" => options[:tab_width] ? ' ' * options[:tab_width] : "\t") - end - - Hash.new do |cache, text| - cache.clear if cache.size >= 100 - - cache[text] = - if text =~ /#{HTML_ESCAPE_PATTERN}/o - text.gsub(/#{HTML_ESCAPE_PATTERN}/o) { |m| html_escape[m] } - else - text - end - end - end - def css_class_for_kinds kinds TokenKinds[kinds.is_a?(Symbol) ? kinds : kinds.first] end diff --git a/lib/coderay/helpers/plugin_host.rb b/lib/coderay/helpers/plugin_host.rb index e9bc17c..12ee29d 100644 --- a/lib/coderay/helpers/plugin_host.rb +++ b/lib/coderay/helpers/plugin_host.rb @@ -47,11 +47,21 @@ module CodeRay # Example: # yaml_plugin = MyPluginHost[:yaml] def [] id, *args, &blk - plugin = validate_id(id) - begin - plugin = plugin_hash.[](plugin, *args, &blk) - end while plugin.is_a? String - plugin + if !args.empty? || blk + plugin = validate_id(id) + begin + plugin = plugin_hash.[](plugin, *args, &blk) + end while plugin.is_a? String + plugin + else + (@cache ||= Hash.new do |cache, key| + plugin = validate_id(key) + begin + plugin = plugin_hash.[](plugin) + end while plugin.is_a? String + cache[key] = plugin + end)[id] + end end alias load [] diff --git a/test/functional/basic.rb b/test/functional/basic.rb index 917b5ff..8554a78 100755 --- a/test/functional/basic.rb +++ b/test/functional/basic.rb @@ -7,6 +7,10 @@ require 'coderay' class BasicTest < Test::Unit::TestCase + def normalize_html html + html.gsub(''', "'").gsub('"', '"') + end + def test_version assert_nothing_raised do assert_match(/\A\d\.\d\.\d?\z/, CodeRay::VERSION) @@ -50,7 +54,7 @@ class BasicTest < Test::Unit::TestCase '<span class="content">Hello, World!</span><span class="delimiter">"</span></span>' def test_simple_highlight assert_nothing_raised do - assert_equal RUBY_TEST_HTML, CodeRay.scan(RUBY_TEST_CODE, :ruby).html + assert_equal RUBY_TEST_HTML, normalize_html(CodeRay.scan(RUBY_TEST_CODE, :ruby).html) end end @@ -75,7 +79,8 @@ class BasicTest < Test::Unit::TestCase end def test_highlight_file - assert_match "require <span class=\"string\"><span class=\"delimiter\">'</span><span class=\"content\">test/unit</span><span class=\"delimiter\">'</span></span>\n", CodeRay.highlight_file(__FILE__) + assert_match "require <span class=\"string\"><span class=\"delimiter\">'</span><span class=\"content\">test/unit</span><span class=\"delimiter\">'</span></span>\n", + normalize_html(CodeRay.highlight_file(__FILE__)) end def test_duo diff --git a/test/functional/examples.rb b/test/functional/examples.rb index 8da4fc7..49337cb 100755 --- a/test/functional/examples.rb +++ b/test/functional/examples.rb @@ -5,10 +5,14 @@ require 'coderay' class ExamplesTest < Test::Unit::TestCase + def normalize_html html + html.gsub(''', "'").gsub('"', '"') + end + def test_examples # output as HTML div (using inline CSS styles) div = CodeRay.scan('puts "Hello, world!"', :ruby).div - assert_equal <<-DIV, div + assert_equal <<-DIV, normalize_html(div) <div class="CodeRay"> <div class="code"><pre>puts <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">Hello, world!</span><span style="color:#710">"</span></span></pre></div> </div> @@ -20,7 +24,7 @@ class ExamplesTest < Test::Unit::TestCase puts 'Hello, world!' end CODE - assert_equal <<-DIV, div + assert_equal <<-DIV, normalize_html(div) <table class="CodeRay"><tr> <td class="line-numbers"><pre><a href="#n1" name="n1">1</a> <a href="#n2" name="n2">2</a> @@ -34,7 +38,7 @@ end # output as standalone HTML page (using CSS classes) page = CodeRay.scan('puts "Hello, world!"', :ruby).page - assert_match <<-PAGE, page + assert_match <<-PAGE, normalize_html(page) <body> <table class="CodeRay"><tr> @@ -90,7 +94,7 @@ Token Types (7): # produce a HTML div, but with CSS classes div = tokens.div(:css => :class) - assert_equal <<-DIV, div + assert_equal <<-DIV, normalize_html(div) <div class="CodeRay"> <div class="code"><pre>{ <span class="key"><span class="delimiter">"</span><span class="content">just</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">an</span><span class="delimiter">"</span></span>, <span class="key"><span class="delimiter">"</span><span class="content">example</span><span class="delimiter">"</span></span>: <span class="integer">42</span> }</pre></div> </div> @@ -119,7 +123,7 @@ Token Types (7): # re-using scanner and encoder ruby_highlighter = CodeRay::Duo[:ruby, :div] div = ruby_highlighter.encode('puts "Hello, world!"') - assert_equal <<-DIV, div + assert_equal <<-DIV, normalize_html(div) <div class="CodeRay"> <div class="code"><pre>puts <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">Hello, world!</span><span style="color:#710">"</span></span></pre></div> </div> diff --git a/test/functional/for_redcloth.rb b/test/functional/for_redcloth.rb index eebf19c..50fc50c 100644 --- a/test/functional/for_redcloth.rb +++ b/test/functional/for_redcloth.rb @@ -14,16 +14,20 @@ end class BasicTest < Test::Unit::TestCase + def normalize_html html + html.gsub(''', "'").gsub('"', '"') + end + def test_for_redcloth require 'coderay/for_redcloth' assert_equal "<p><span lang=\"ruby\" class=\"CodeRay\">puts <span style=\"background-color:hsla(0,100%,50%,0.05)\"><span style=\"color:#710\">\"</span><span style=\"color:#D20\">Hello, World!</span><span style=\"color:#710\">\"</span></span></span></p>", - RedCloth.new('@[ruby]puts "Hello, World!"@').to_html + normalize_html(RedCloth.new('@[ruby]puts "Hello, World!"@').to_html) assert_equal <<-BLOCKCODE.chomp, <div lang="ruby" class="CodeRay"> <div class="code"><pre>puts <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">Hello, World!</span><span style="color:#710">"</span></span></pre></div> </div> BLOCKCODE - RedCloth.new('bc[ruby]. puts "Hello, World!"').to_html + normalize_html(RedCloth.new('bc[ruby]. puts "Hello, World!"').to_html) end def test_for_redcloth_no_lang diff --git a/test/unit/html.rb b/test/unit/html.rb index 750b6c9..9175a4f 100644 --- a/test/unit/html.rb +++ b/test/unit/html.rb @@ -3,6 +3,10 @@ require 'coderay' class HtmlTest < Test::Unit::TestCase + def normalize_html html + html.gsub(''', "'").gsub('"', '"') + end + def test_break_lines_option snippets = {} @@ -95,9 +99,9 @@ public class Test { for lang, code in snippets tokens = CodeRay.scan code[:in], lang - assert_equal code[:expected_with_option_off], tokens.html - assert_equal code[:expected_with_option_off], tokens.html(:break_lines => false) - assert_equal code[:expected_with_option_on], tokens.html(:break_lines => true) + assert_equal code[:expected_with_option_off], normalize_html(tokens.html) + assert_equal code[:expected_with_option_off], normalize_html(tokens.html(:break_lines => false)) + assert_equal code[:expected_with_option_on], normalize_html(tokens.html(:break_lines => true)) end end end |