diff options
-rw-r--r-- | lib/coderay/encoders/html.rb | 37 | ||||
-rw-r--r-- | lib/coderay/encoders/html/css.rb | 38 | ||||
-rwxr-xr-x | test/functional/basic.rb | 4 | ||||
-rwxr-xr-x | test/functional/examples.rb | 8 | ||||
-rw-r--r-- | test/functional/for_redcloth.rb | 4 | ||||
-rw-r--r-- | test/unit/html.rb | 4 |
6 files changed, 57 insertions, 38 deletions
diff --git a/lib/coderay/encoders/html.rb b/lib/coderay/encoders/html.rb index 942b9c8..55b1291 100644 --- a/lib/coderay/encoders/html.rb +++ b/lib/coderay/encoders/html.rb @@ -129,11 +129,10 @@ module Encoders def self.make_html_escape_hash { - '&' => '&', - '"' => '"', - '>' => '>', - '<' => '<', - # "\t" => will be set to ' ' * options[:tab_width] during setup + '&' => '&', + '>' => '>', + '<' => '<', + "\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] = ' ' } @@ -141,7 +140,7 @@ module Encoders end HTML_ESCAPE = make_html_escape_hash - HTML_ESCAPE_PATTERN = /[\t"&><\0-\x8\xB-\x1F]/ + 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 } @@ -181,7 +180,7 @@ module Encoders @break_lines = (options[:break_lines] == true) - @HTML_ESCAPE = HTML_ESCAPE.merge("\t" => options[:tab_width] ? ' ' * options[:tab_width] : "\t") + @escape_cache = make_escape_cache(options) @opened = [] @last_opened = nil @@ -198,7 +197,7 @@ module Encoders @last_opened = nil end - if @out.respond_to? :to_str + if options[:wrap] || options[:line_numbers] @out.extend Output @out.css = @css if options[:line_numbers] @@ -221,7 +220,7 @@ module Encoders def text_token text, kind style = @span_for_kinds[@last_opened ? [kind, *@opened] : kind] - text = text.gsub(/#{HTML_ESCAPE_PATTERN}/o) { |m| @HTML_ESCAPE[m] } if text =~ /#{HTML_ESCAPE_PATTERN}/o + text = @escape_cache[text] if text.size <= 1 || text =~ /#{HTML_ESCAPE_PATTERN}/o text = break_lines(text, style) if @break_lines && (style || @opened.size > 0) && text.index("\n") if style @@ -277,6 +276,26 @@ 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/encoders/html/css.rb b/lib/coderay/encoders/html/css.rb index 164d7f8..e06c486 100644 --- a/lib/coderay/encoders/html/css.rb +++ b/lib/coderay/encoders/html/css.rb @@ -3,25 +3,23 @@ module Encoders class HTML class CSS # :nodoc: + def initialize style_name = :default + @style_name = style_name + end - attr :stylesheet - - def CSS.load_stylesheet style = nil - CodeRay::Styles[style] + def style + @style ||= CodeRay::Styles[@style_name] end - def initialize style = :default - @styles = Hash.new - style = CSS.load_stylesheet style - @stylesheet = [ + def stylesheet + @css ||= [ style::CSS_MAIN_STYLES, style::TOKEN_COLORS.gsub(/^(?!$)/, '.CodeRay ') ].join("\n") - parse style::TOKEN_COLORS end def get_style_for_css_classes css_classes - cl = @styles[css_classes.first] + cl = styles[css_classes.first] return '' unless cl style = '' 1.upto css_classes.size do |offset| @@ -31,7 +29,7 @@ module Encoders return style end - private + private CSS_CLASS_PATTERN = / ( # $1 = selectors @@ -46,14 +44,16 @@ module Encoders | ( [^\n]+ ) # $3 = error /mx - def parse stylesheet - stylesheet.scan CSS_CLASS_PATTERN do |selectors, style, error| - raise "CSS parse error: '#{error.inspect}' not recognized" if error - for selector in selectors.split(',') - classes = selector.scan(/[-\w]+/) - cl = classes.pop - @styles[cl] ||= Hash.new - @styles[cl][classes] = style.to_s.strip.delete(' ').chomp(';') + def styles + @styles ||= Hash.new.tap do |styles| + style::TOKEN_COLORS.scan CSS_CLASS_PATTERN do |selectors, style, error| + raise "CSS parse error: '#{error.inspect}' not recognized" if error + for selector in selectors.split(',') + classes = selector.scan(/[-\w]+/) + cl = classes.pop + styles[cl] ||= Hash.new + styles[cl][classes] = style.to_s.strip.delete(' ').chomp(';') + end end end end diff --git a/test/functional/basic.rb b/test/functional/basic.rb index 752d4ba..917b5ff 100755 --- a/test/functional/basic.rb +++ b/test/functional/basic.rb @@ -46,8 +46,8 @@ class BasicTest < Test::Unit::TestCase end end - RUBY_TEST_HTML = 'puts <span class="string"><span class="delimiter">"</span>' + - '<span class="content">Hello, World!</span><span class="delimiter">"</span></span>' + RUBY_TEST_HTML = 'puts <span class="string"><span class="delimiter">"</span>' + + '<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 diff --git a/test/functional/examples.rb b/test/functional/examples.rb index 985ef87..8da4fc7 100755 --- a/test/functional/examples.rb +++ b/test/functional/examples.rb @@ -10,7 +10,7 @@ class ExamplesTest < Test::Unit::TestCase div = CodeRay.scan('puts "Hello, world!"', :ruby).div assert_equal <<-DIV, 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 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> DIV @@ -40,7 +40,7 @@ end <table class="CodeRay"><tr> <td class="line-numbers"><pre><a href="#n1" name="n1">1</a> </pre></td> - <td class="code"><pre>puts <span class="string"><span class="delimiter">"</span><span class="content">Hello, world!</span><span class="delimiter">"</span></span></pre></td> + <td class="code"><pre>puts <span class="string"><span class="delimiter">"</span><span class="content">Hello, world!</span><span class="delimiter">"</span></span></pre></td> </tr></table> </body> @@ -92,7 +92,7 @@ Token Types (7): div = tokens.div(:css => :class) assert_equal <<-DIV, 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 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> DIV @@ -121,7 +121,7 @@ Token Types (7): div = ruby_highlighter.encode('puts "Hello, world!"') assert_equal <<-DIV, 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 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> DIV end diff --git a/test/functional/for_redcloth.rb b/test/functional/for_redcloth.rb index 9fd244e..eebf19c 100644 --- a/test/functional/for_redcloth.rb +++ b/test/functional/for_redcloth.rb @@ -16,11 +16,11 @@ class BasicTest < Test::Unit::TestCase 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>", + 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 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 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 diff --git a/test/unit/html.rb b/test/unit/html.rb index 0072635..750b6c9 100644 --- a/test/unit/html.rb +++ b/test/unit/html.rb @@ -60,7 +60,7 @@ public class Test { * used to test the */</span> <span class=\"directive\">public</span> <span class=\"type\">class</span> <span class=\"class\">Test</span> { - <span class=\"directive\">public</span> <span class=\"directive\">static</span> <span class=\"directive\">final</span> <span class=\"predefined-type\">String</span> MESSAGE = <span class=\"string\"><span class=\"delimiter\">"</span><span class=\"content\">My message To the world</span><span class=\"delimiter\">"</span></span>; + <span class=\"directive\">public</span> <span class=\"directive\">static</span> <span class=\"directive\">final</span> <span class=\"predefined-type\">String</span> MESSAGE = <span class=\"string\"><span class=\"delimiter\">\"</span><span class=\"content\">My message To the world</span><span class=\"delimiter\">\"</span></span>; <span class=\"directive\">static</span> <span class=\"type\">void</span> main() { <span class=\"comment\">/* @@ -80,7 +80,7 @@ public class Test { <span class=\"comment\"> * used to test the</span> <span class=\"comment\"> */</span> <span class=\"directive\">public</span> <span class=\"type\">class</span> <span class=\"class\">Test</span> { - <span class=\"directive\">public</span> <span class=\"directive\">static</span> <span class=\"directive\">final</span> <span class=\"predefined-type\">String</span> MESSAGE = <span class=\"string\"><span class=\"delimiter\">"</span><span class=\"content\">My message To the world</span><span class=\"delimiter\">"</span></span>; + <span class=\"directive\">public</span> <span class=\"directive\">static</span> <span class=\"directive\">final</span> <span class=\"predefined-type\">String</span> MESSAGE = <span class=\"string\"><span class=\"delimiter\">\"</span><span class=\"content\">My message To the world</span><span class=\"delimiter\">\"</span></span>; <span class=\"directive\">static</span> <span class=\"type\">void</span> main() { <span class=\"comment\">/*</span> |