summaryrefslogtreecommitdiff
path: root/lib/coderay/encoders
diff options
context:
space:
mode:
authorKornelius Kalnbach <murphy@rubychan.de>2016-06-04 14:07:48 +0200
committerKornelius Kalnbach <murphy@rubychan.de>2016-06-04 14:07:48 +0200
commita38b3370cae2d5917734c6480ea99c9c8e9a5cea (patch)
treec52f2b30f79abbc2ba5b46e375a0ad137eba0cee /lib/coderay/encoders
parent86b0bcf98a22a3933a569c7c4c0beb76d1a1b108 (diff)
parent3e10d565f99025bdca003cc8fbd98d3260ae451a (diff)
downloadcoderay-a38b3370cae2d5917734c6480ea99c9c8e9a5cea.tar.gz
Merge branch 'possible-speedups' into dsl
Diffstat (limited to 'lib/coderay/encoders')
-rw-r--r--lib/coderay/encoders/html.rb37
-rw-r--r--lib/coderay/encoders/html/css.rb38
2 files changed, 47 insertions, 28 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
{
- '&' => '&amp;',
- '"' => '&quot;',
- '>' => '&gt;',
- '<' => '&lt;',
- # "\t" => will be set to ' ' * options[:tab_width] during setup
+ '&' => '&amp;',
+ '>' => '&gt;',
+ '<' => '&lt;',
+ "\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