Skip to content

Commit e01ccf7

Browse files
committed
Merge branch 'possible-speedups' into dsl
2 parents 545398f + c999deb commit e01ccf7

File tree

7 files changed

+48
-55
lines changed

7 files changed

+48
-55
lines changed

coderay.gemspec

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,6 @@ Gem::Specification.new do |s|
3232
s.rubyforge_project = s.name
3333
s.rdoc_options = '-SNw2', "-m#{readme_file}", '-t CodeRay Documentation'
3434
s.extra_rdoc_files = readme_file
35+
36+
s.add_dependency 'escape_utils', '>= 1.0'
3537
end

lib/coderay/encoders/html.rb

Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require 'set'
2+
require 'escape_utils'
23

34
module CodeRay
45
module Encoders
@@ -127,21 +128,6 @@ class HTML < Encoder
127128

128129
protected
129130

130-
def self.make_html_escape_hash
131-
{
132-
'&' => '&amp;',
133-
'>' => '&gt;',
134-
'<' => '&lt;',
135-
"\t" => ' ' * DEFAULT_OPTIONS[:tab_width],
136-
}.tap do |hash|
137-
# Escape ASCII control codes except \x9 == \t and \xA == \n.
138-
(Array(0x00..0x8) + Array(0xB..0x1F)).each { |invalid| hash[invalid.chr] = ' ' }
139-
end
140-
end
141-
142-
HTML_ESCAPE = make_html_escape_hash
143-
HTML_ESCAPE_PATTERN = /[\t&><\0-\x8\xB-\x1F]/
144-
145131
TOKEN_KIND_TO_INFO = Hash.new do |h, kind|
146132
h[kind] = kind.to_s.gsub(/_/, ' ').gsub(/\b\w/) { $&.capitalize }
147133
end
@@ -180,8 +166,6 @@ def setup options
180166

181167
@break_lines = (options[:break_lines] == true)
182168

183-
@escape_cache = make_escape_cache(options)
184-
185169
@opened = []
186170
@last_opened = nil
187171
@css = CSS.new options[:style]
@@ -220,7 +204,7 @@ def finish options
220204
def text_token text, kind
221205
style = @span_for_kinds[@last_opened ? [kind, *@opened] : kind]
222206

223-
text = @escape_cache[text] if text.size <= 1 || text =~ /#{HTML_ESCAPE_PATTERN}/o
207+
text = EscapeUtils.escape_html text, false
224208
text = break_lines(text, style) if @break_lines && (style || @opened.size > 0) && text.index("\n")
225209

226210
if style
@@ -276,26 +260,6 @@ def check_options! options
276260
options[:break_lines] = true if options[:line_numbers] == :inline
277261
end
278262

279-
def make_escape_cache options
280-
html_escape =
281-
if options[:tab_width] == DEFAULT_OPTIONS[:tab_width]
282-
HTML_ESCAPE
283-
else
284-
HTML_ESCAPE.merge("\t" => options[:tab_width] ? ' ' * options[:tab_width] : "\t")
285-
end
286-
287-
Hash.new do |cache, text|
288-
cache.clear if cache.size >= 100
289-
290-
cache[text] =
291-
if text =~ /#{HTML_ESCAPE_PATTERN}/o
292-
text.gsub(/#{HTML_ESCAPE_PATTERN}/o) { |m| html_escape[m] }
293-
else
294-
text
295-
end
296-
end
297-
end
298-
299263
def css_class_for_kinds kinds
300264
TokenKinds[kinds.is_a?(Symbol) ? kinds : kinds.first]
301265
end

lib/coderay/helpers/plugin_host.rb

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,21 @@ def load_all
4747
# Example:
4848
# yaml_plugin = MyPluginHost[:yaml]
4949
def [] id, *args, &blk
50-
plugin = validate_id(id)
51-
begin
52-
plugin = plugin_hash.[](plugin, *args, &blk)
53-
end while plugin.is_a? String
54-
plugin
50+
if !args.empty? || blk
51+
plugin = validate_id(id)
52+
begin
53+
plugin = plugin_hash.[](plugin, *args, &blk)
54+
end while plugin.is_a? String
55+
plugin
56+
else
57+
(@cache ||= Hash.new do |cache, key|
58+
plugin = validate_id(key)
59+
begin
60+
plugin = plugin_hash.[](plugin)
61+
end while plugin.is_a? String
62+
cache[key] = plugin
63+
end)[id]
64+
end
5565
end
5666

5767
alias load []

test/functional/basic.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77

88
class BasicTest < Test::Unit::TestCase
99

10+
def normalize_html html
11+
html.gsub('&#39;', "'").gsub('&quot;', '"')
12+
end
13+
1014
def test_version
1115
assert_nothing_raised do
1216
assert_match(/\A\d\.\d\.\d?\z/, CodeRay::VERSION)
@@ -50,7 +54,7 @@ def test_simple_scan
5054
'<span class="content">Hello, World!</span><span class="delimiter">"</span></span>'
5155
def test_simple_highlight
5256
assert_nothing_raised do
53-
assert_equal RUBY_TEST_HTML, CodeRay.scan(RUBY_TEST_CODE, :ruby).html
57+
assert_equal RUBY_TEST_HTML, normalize_html(CodeRay.scan(RUBY_TEST_CODE, :ruby).html)
5458
end
5559
end
5660

@@ -75,7 +79,8 @@ def test_highlight
7579
end
7680

7781
def test_highlight_file
78-
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__)
82+
assert_match "require <span class=\"string\"><span class=\"delimiter\">'</span><span class=\"content\">test/unit</span><span class=\"delimiter\">'</span></span>\n",
83+
normalize_html(CodeRay.highlight_file(__FILE__))
7984
end
8085

8186
def test_duo

test/functional/examples.rb

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@
55

66
class ExamplesTest < Test::Unit::TestCase
77

8+
def normalize_html html
9+
html.gsub('&#39;', "'").gsub('&quot;', '"')
10+
end
11+
812
def test_examples
913
# output as HTML div (using inline CSS styles)
1014
div = CodeRay.scan('puts "Hello, world!"', :ruby).div
11-
assert_equal <<-DIV, div
15+
assert_equal <<-DIV, normalize_html(div)
1216
<div class="CodeRay">
1317
<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>
1418
</div>
@@ -20,7 +24,7 @@ def test_examples
2024
puts 'Hello, world!'
2125
end
2226
CODE
23-
assert_equal <<-DIV, div
27+
assert_equal <<-DIV, normalize_html(div)
2428
<table class="CodeRay"><tr>
2529
<td class="line-numbers"><pre><a href="#n1" name="n1">1</a>
2630
<a href="#n2" name="n2">2</a>
@@ -34,7 +38,7 @@ def test_examples
3438

3539
# output as standalone HTML page (using CSS classes)
3640
page = CodeRay.scan('puts "Hello, world!"', :ruby).page
37-
assert_match <<-PAGE, page
41+
assert_match <<-PAGE, normalize_html(page)
3842
<body>
3943
4044
<table class="CodeRay"><tr>
@@ -90,7 +94,7 @@ def test_examples
9094

9195
# produce a HTML div, but with CSS classes
9296
div = tokens.div(:css => :class)
93-
assert_equal <<-DIV, div
97+
assert_equal <<-DIV, normalize_html(div)
9498
<div class="CodeRay">
9599
<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>
96100
</div>
@@ -119,7 +123,7 @@ def test_examples
119123
# re-using scanner and encoder
120124
ruby_highlighter = CodeRay::Duo[:ruby, :div]
121125
div = ruby_highlighter.encode('puts "Hello, world!"')
122-
assert_equal <<-DIV, div
126+
assert_equal <<-DIV, normalize_html(div)
123127
<div class="CodeRay">
124128
<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>
125129
</div>

test/functional/for_redcloth.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,20 @@
1414

1515
class BasicTest < Test::Unit::TestCase
1616

17+
def normalize_html html
18+
html.gsub('&#39;', "'").gsub('&quot;', '"')
19+
end
20+
1721
def test_for_redcloth
1822
require 'coderay/for_redcloth'
1923
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>",
20-
RedCloth.new('@[ruby]puts "Hello, World!"@').to_html
24+
normalize_html(RedCloth.new('@[ruby]puts "Hello, World!"@').to_html)
2125
assert_equal <<-BLOCKCODE.chomp,
2226
<div lang="ruby" class="CodeRay">
2327
<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>
2428
</div>
2529
BLOCKCODE
26-
RedCloth.new('bc[ruby]. puts "Hello, World!"').to_html
30+
normalize_html(RedCloth.new('bc[ruby]. puts "Hello, World!"').to_html)
2731
end
2832

2933
def test_for_redcloth_no_lang

test/unit/html.rb

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33

44
class HtmlTest < Test::Unit::TestCase
55

6+
def normalize_html html
7+
html.gsub('&#39;', "'").gsub('&quot;', '"')
8+
end
9+
610
def test_break_lines_option
711
snippets = {}
812

@@ -95,9 +99,9 @@ def test_break_lines_option
9599
for lang, code in snippets
96100
tokens = CodeRay.scan code[:in], lang
97101

98-
assert_equal code[:expected_with_option_off], tokens.html
99-
assert_equal code[:expected_with_option_off], tokens.html(:break_lines => false)
100-
assert_equal code[:expected_with_option_on], tokens.html(:break_lines => true)
102+
assert_equal code[:expected_with_option_off], normalize_html(tokens.html)
103+
assert_equal code[:expected_with_option_off], normalize_html(tokens.html(:break_lines => false))
104+
assert_equal code[:expected_with_option_on], normalize_html(tokens.html(:break_lines => true))
101105
end
102106
end
103107
end

0 commit comments

Comments
 (0)