Skip to content

Commit 90cf032

Browse files
committed
cache escaped tokens, reduce HTML enc setup time
1 parent 718c0ac commit 90cf032

File tree

3 files changed

+37
-28
lines changed

3 files changed

+37
-28
lines changed

lib/coderay/encoders/html.rb

+13-4
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,19 @@ def setup options
178178
@out = ''
179179
end
180180

181+
@tab_replacement = ' ' * options[:tab_width]
182+
@escape_cache = Hash.new do |cache, text|
183+
cache.clear if cache.size >= 100
184+
185+
cache[text] =
186+
if text =~ /#{HTML_ESCAPE_PATTERN}/o
187+
text.gsub(/#{HTML_ESCAPE_PATTERN}/o) { |m| m == "\t" ? @tab_replacement : HTML_ESCAPE[m] }
188+
else
189+
text
190+
end
191+
end
181192
@break_lines = (options[:break_lines] == true)
182193

183-
@HTML_ESCAPE = HTML_ESCAPE.merge("\t" => ' ' * options[:tab_width])
184-
185194
@opened = []
186195
@last_opened = nil
187196
@css = CSS.new options[:style]
@@ -197,7 +206,7 @@ def finish options
197206
@last_opened = nil
198207
end
199208

200-
if @out.respond_to? :to_str
209+
if options[:wrap] || options[:line_numbers]
201210
@out.extend Output
202211
@out.css = @css
203212
if options[:line_numbers]
@@ -220,7 +229,7 @@ def finish options
220229
def text_token text, kind
221230
style = @span_for_kinds[@last_opened ? [kind, *@opened] : kind]
222231

223-
text = text.gsub(/#{HTML_ESCAPE_PATTERN}/o) { |m| @HTML_ESCAPE[m] } if text =~ /#{HTML_ESCAPE_PATTERN}/o
232+
text = @escape_cache[text] if text.size <= 1 || text =~ /#{HTML_ESCAPE_PATTERN}/o
224233
text = break_lines(text, style) if @break_lines && (style || @opened.size > 0) && text.index("\n")
225234

226235
if style

lib/coderay/encoders/html/css.rb

+23-23
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,23 @@ module Encoders
33

44
class HTML
55
class CSS # :nodoc:
6-
7-
attr :stylesheet
8-
9-
def CSS.load_stylesheet style = nil
10-
CodeRay::Styles[style]
11-
end
12-
136
def initialize style = :default
14-
@styles = Hash.new
15-
style = CSS.load_stylesheet style
16-
@stylesheet = [
17-
style::CSS_MAIN_STYLES,
18-
style::TOKEN_COLORS.gsub(/^(?!$)/, '.CodeRay ')
7+
@style = style
8+
end
9+
10+
def stylesheet
11+
@stylesheet ||= CodeRay::Styles[@style]
12+
end
13+
14+
def css
15+
[
16+
stylesheet::CSS_MAIN_STYLES,
17+
stylesheet::TOKEN_COLORS.gsub(/^(?!$)/, '.CodeRay ')
1918
].join("\n")
20-
parse style::TOKEN_COLORS
2119
end
22-
20+
2321
def get_style_for_css_classes css_classes
24-
cl = @styles[css_classes.first]
22+
cl = styles[css_classes.first]
2523
return '' unless cl
2624
style = ''
2725
1.upto css_classes.size do |offset|
@@ -46,14 +44,16 @@ def get_style_for_css_classes css_classes
4644
|
4745
( [^\n]+ ) # $3 = error
4846
/mx
49-
def parse stylesheet
50-
stylesheet.scan CSS_CLASS_PATTERN do |selectors, style, error|
51-
raise "CSS parse error: '#{error.inspect}' not recognized" if error
52-
for selector in selectors.split(',')
53-
classes = selector.scan(/[-\w]+/)
54-
cl = classes.pop
55-
@styles[cl] ||= Hash.new
56-
@styles[cl][classes] = style.to_s.strip.delete(' ').chomp(';')
47+
def styles
48+
@styles ||= Hash.new.tap do |styles|
49+
stylesheet::TOKEN_COLORS.scan CSS_CLASS_PATTERN do |selectors, style, error|
50+
raise "CSS parse error: '#{error.inspect}' not recognized" if error
51+
for selector in selectors.split(',')
52+
classes = selector.scan(/[-\w]+/)
53+
cl = classes.pop
54+
styles[cl] ||= Hash.new
55+
styles[cl][classes] = style.to_s.strip.delete(' ').chomp(';')
56+
end
5757
end
5858
end
5959
end

lib/coderay/encoders/html/output.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def extended o # :nodoc:
2424
end
2525

2626
def make_stylesheet css, in_tag = false # :nodoc:
27-
sheet = css.stylesheet
27+
sheet = css.css
2828
sheet = <<-'CSS' if in_tag
2929
<style type="text/css">
3030
#{sheet}

0 commit comments

Comments
 (0)