summaryrefslogtreecommitdiffstats
path: root/vendor/gems/coderay-0.9.7/lib/coderay/encoders
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2011-01-22 13:18:01 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2011-01-22 13:18:01 +0000
commit144ca23442a5e123935dea4073670d4dba4caa89 (patch)
tree61c02c4fee71195b09fd7e6270d866a3b2fabd28 /vendor/gems/coderay-0.9.7/lib/coderay/encoders
parente4faf3553a1b9d22ee171e08f62f112637b05e19 (diff)
downloadredmine-144ca23442a5e123935dea4073670d4dba4caa89.tar.gz
redmine-144ca23442a5e123935dea4073670d4dba4caa89.zip
Coderay upgraded to 0.9.7 (#5344).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@4739 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'vendor/gems/coderay-0.9.7/lib/coderay/encoders')
-rw-r--r--vendor/gems/coderay-0.9.7/lib/coderay/encoders/_map.rb12
-rw-r--r--vendor/gems/coderay-0.9.7/lib/coderay/encoders/comment_filter.rb43
-rw-r--r--vendor/gems/coderay-0.9.7/lib/coderay/encoders/count.rb21
-rw-r--r--vendor/gems/coderay-0.9.7/lib/coderay/encoders/debug.rb49
-rw-r--r--vendor/gems/coderay-0.9.7/lib/coderay/encoders/div.rb19
-rw-r--r--vendor/gems/coderay-0.9.7/lib/coderay/encoders/filter.rb75
-rw-r--r--vendor/gems/coderay-0.9.7/lib/coderay/encoders/html.rb309
-rw-r--r--vendor/gems/coderay-0.9.7/lib/coderay/encoders/html/css.rb70
-rw-r--r--vendor/gems/coderay-0.9.7/lib/coderay/encoders/html/numerization.rb133
-rw-r--r--vendor/gems/coderay-0.9.7/lib/coderay/encoders/html/output.rb206
-rw-r--r--vendor/gems/coderay-0.9.7/lib/coderay/encoders/json.rb69
-rw-r--r--vendor/gems/coderay-0.9.7/lib/coderay/encoders/lines_of_code.rb90
-rw-r--r--vendor/gems/coderay-0.9.7/lib/coderay/encoders/null.rb26
-rw-r--r--vendor/gems/coderay-0.9.7/lib/coderay/encoders/page.rb20
-rw-r--r--vendor/gems/coderay-0.9.7/lib/coderay/encoders/span.rb19
-rw-r--r--vendor/gems/coderay-0.9.7/lib/coderay/encoders/statistic.rb77
-rw-r--r--vendor/gems/coderay-0.9.7/lib/coderay/encoders/term.rb158
-rw-r--r--vendor/gems/coderay-0.9.7/lib/coderay/encoders/text.rb32
-rw-r--r--vendor/gems/coderay-0.9.7/lib/coderay/encoders/token_class_filter.rb84
-rw-r--r--vendor/gems/coderay-0.9.7/lib/coderay/encoders/xml.rb71
-rw-r--r--vendor/gems/coderay-0.9.7/lib/coderay/encoders/yaml.rb22
21 files changed, 1605 insertions, 0 deletions
diff --git a/vendor/gems/coderay-0.9.7/lib/coderay/encoders/_map.rb b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/_map.rb
new file mode 100644
index 000000000..526c3a07c
--- /dev/null
+++ b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/_map.rb
@@ -0,0 +1,12 @@
+module CodeRay
+module Encoders
+
+ map \
+ :loc => :lines_of_code,
+ :plain => :text,
+ :stats => :statistic,
+ :terminal => :term,
+ :tex => :latex
+
+end
+end
diff --git a/vendor/gems/coderay-0.9.7/lib/coderay/encoders/comment_filter.rb b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/comment_filter.rb
new file mode 100644
index 000000000..4d3fb54c2
--- /dev/null
+++ b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/comment_filter.rb
@@ -0,0 +1,43 @@
+($:.unshift '../..'; require 'coderay') unless defined? CodeRay
+module CodeRay
+module Encoders
+
+ load :token_class_filter
+
+ class CommentFilter < TokenClassFilter
+
+ register_for :comment_filter
+
+ DEFAULT_OPTIONS = superclass::DEFAULT_OPTIONS.merge \
+ :exclude => [:comment]
+
+ end
+
+end
+end
+
+if $0 == __FILE__
+ $VERBOSE = true
+ $: << File.join(File.dirname(__FILE__), '..')
+ eval DATA.read, nil, $0, __LINE__ + 4
+end
+
+__END__
+require 'test/unit'
+
+class CommentFilterTest < Test::Unit::TestCase
+
+ def test_filtering_comments
+ tokens = CodeRay.scan <<-RUBY, :ruby
+#!/usr/bin/env ruby
+# a minimal Ruby program
+puts "Hello world!"
+ RUBY
+ assert_equal <<-RUBY_FILTERED, tokens.comment_filter.text
+#!/usr/bin/env ruby
+
+puts "Hello world!"
+ RUBY_FILTERED
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/coderay-0.9.7/lib/coderay/encoders/count.rb b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/count.rb
new file mode 100644
index 000000000..c9a6dfdea
--- /dev/null
+++ b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/count.rb
@@ -0,0 +1,21 @@
+module CodeRay
+module Encoders
+
+ class Count < Encoder
+
+ include Streamable
+ register_for :count
+
+ protected
+
+ def setup options
+ @out = 0
+ end
+
+ def token text, kind
+ @out += 1
+ end
+ end
+
+end
+end
diff --git a/vendor/gems/coderay-0.9.7/lib/coderay/encoders/debug.rb b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/debug.rb
new file mode 100644
index 000000000..a4b064833
--- /dev/null
+++ b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/debug.rb
@@ -0,0 +1,49 @@
+module CodeRay
+module Encoders
+
+ # = Debug Encoder
+ #
+ # Fast encoder producing simple debug output.
+ #
+ # It is readable and diff-able and is used for testing.
+ #
+ # You cannot fully restore the tokens information from the
+ # output, because consecutive :space tokens are merged.
+ # Use Tokens#dump for caching purposes.
+ class Debug < Encoder
+
+ include Streamable
+ register_for :debug
+
+ FILE_EXTENSION = 'raydebug'
+
+ protected
+ def text_token text, kind
+ if kind == :space
+ text
+ else
+ text = text.gsub(/[)\\]/, '\\\\\0') # escape ) and \
+ "#{kind}(#{text})"
+ end
+ end
+
+ def open_token kind
+ "#{kind}<"
+ end
+
+ def close_token kind
+ ">"
+ end
+
+ def begin_line kind
+ "#{kind}["
+ end
+
+ def end_line kind
+ "]"
+ end
+
+ end
+
+end
+end
diff --git a/vendor/gems/coderay-0.9.7/lib/coderay/encoders/div.rb b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/div.rb
new file mode 100644
index 000000000..41201724a
--- /dev/null
+++ b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/div.rb
@@ -0,0 +1,19 @@
+module CodeRay
+module Encoders
+
+ load :html
+
+ class Div < HTML
+
+ FILE_EXTENSION = 'div.html'
+
+ register_for :div
+
+ DEFAULT_OPTIONS = HTML::DEFAULT_OPTIONS.merge \
+ :css => :style,
+ :wrap => :div
+
+ end
+
+end
+end
diff --git a/vendor/gems/coderay-0.9.7/lib/coderay/encoders/filter.rb b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/filter.rb
new file mode 100644
index 000000000..5e4b34d13
--- /dev/null
+++ b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/filter.rb
@@ -0,0 +1,75 @@
+($:.unshift '../..'; require 'coderay') unless defined? CodeRay
+module CodeRay
+module Encoders
+
+ class Filter < Encoder
+
+ register_for :filter
+
+ protected
+ def setup options
+ @out = Tokens.new
+ end
+
+ def text_token text, kind
+ [text, kind] if include_text_token? text, kind
+ end
+
+ def include_text_token? text, kind
+ true
+ end
+
+ def block_token action, kind
+ [action, kind] if include_block_token? action, kind
+ end
+
+ def include_block_token? action, kind
+ true
+ end
+
+ end
+
+end
+end
+
+if $0 == __FILE__
+ $VERBOSE = true
+ $: << File.join(File.dirname(__FILE__), '..')
+ eval DATA.read, nil, $0, __LINE__ + 4
+end
+
+__END__
+require 'test/unit'
+
+class FilterTest < Test::Unit::TestCase
+
+ def test_creation
+ assert CodeRay::Encoders::Filter < CodeRay::Encoders::Encoder
+ filter = nil
+ assert_nothing_raised do
+ filter = CodeRay.encoder :filter
+ end
+ assert_kind_of CodeRay::Encoders::Encoder, filter
+ end
+
+ def test_filtering_text_tokens
+ tokens = CodeRay::Tokens.new
+ 10.times do |i|
+ tokens << [i.to_s, :index]
+ end
+ assert_equal tokens, CodeRay::Encoders::Filter.new.encode_tokens(tokens)
+ assert_equal tokens, tokens.filter
+ end
+
+ def test_filtering_block_tokens
+ tokens = CodeRay::Tokens.new
+ 10.times do |i|
+ tokens << [:open, :index]
+ tokens << [i.to_s, :content]
+ tokens << [:close, :index]
+ end
+ assert_equal tokens, CodeRay::Encoders::Filter.new.encode_tokens(tokens)
+ assert_equal tokens, tokens.filter
+ end
+
+end
diff --git a/vendor/gems/coderay-0.9.7/lib/coderay/encoders/html.rb b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/html.rb
new file mode 100644
index 000000000..f280c7d36
--- /dev/null
+++ b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/html.rb
@@ -0,0 +1,309 @@
+require 'set'
+
+module CodeRay
+module Encoders
+
+ # = HTML Encoder
+ #
+ # This is CodeRay's most important highlighter:
+ # It provides save, fast XHTML generation and CSS support.
+ #
+ # == Usage
+ #
+ # require 'coderay'
+ # puts CodeRay.scan('Some /code/', :ruby).html #-> a HTML page
+ # puts CodeRay.scan('Some /code/', :ruby).html(:wrap => :span)
+ # #-> <span class="CodeRay"><span class="co">Some</span> /code/</span>
+ # puts CodeRay.scan('Some /code/', :ruby).span #-> the same
+ #
+ # puts CodeRay.scan('Some code', :ruby).html(
+ # :wrap => nil,
+ # :line_numbers => :inline,
+ # :css => :style
+ # )
+ # #-> <span class="no">1</span> <span style="color:#036; font-weight:bold;">Some</span> code
+ #
+ # == Options
+ #
+ # === :tab_width
+ # Convert \t characters to +n+ spaces (a number.)
+ # Default: 8
+ #
+ # === :css
+ # How to include the styles; can be :class or :style.
+ #
+ # Default: :class
+ #
+ # === :wrap
+ # Wrap in :page, :div, :span or nil.
+ #
+ # You can also use Encoders::Div and Encoders::Span.
+ #
+ # Default: nil
+ #
+ # === :title
+ #
+ # The title of the HTML page (works only when :wrap is set to :page.)
+ #
+ # Default: 'CodeRay output'
+ #
+ # === :line_numbers
+ # Include line numbers in :table, :inline, :list or nil (no line numbers)
+ #
+ # Default: nil
+ #
+ # === :line_number_start
+ # Where to start with line number counting.
+ #
+ # Default: 1
+ #
+ # === :bold_every
+ # Make every +n+-th number appear bold.
+ #
+ # Default: 10
+ #
+ # === :highlight_lines
+ #
+ # Highlights certain line numbers.
+ # Can be any Enumerable, typically just an Array or Range, of numbers.
+ #
+ # Bolding is deactivated when :highlight_lines is set. It only makes sense
+ # in combination with :line_numbers.
+ #
+ # Default: nil
+ #
+ # === :hint
+ # Include some information into the output using the title attribute.
+ # Can be :info (show token type on mouse-over), :info_long (with full path)
+ # or :debug (via inspect).
+ #
+ # Default: false
+ class HTML < Encoder
+
+ include Streamable
+ register_for :html
+
+ FILE_EXTENSION = 'html'
+
+ DEFAULT_OPTIONS = {
+ :tab_width => 8,
+
+ :css => :class,
+
+ :style => :cycnus,
+ :wrap => nil,
+ :title => 'CodeRay output',
+
+ :line_numbers => nil,
+ :line_number_start => 1,
+ :bold_every => 10,
+ :highlight_lines => nil,
+
+ :hint => false,
+ }
+
+ helper :output, :css
+
+ attr_reader :css
+
+ protected
+
+ HTML_ESCAPE = { #:nodoc:
+ '&' => '&amp;',
+ '"' => '&quot;',
+ '>' => '&gt;',
+ '<' => '&lt;',
+ }
+
+ # This was to prevent illegal HTML.
+ # Strange chars should still be avoided in codes.
+ evil_chars = Array(0x00...0x20) - [?\n, ?\t, ?\s]
+ evil_chars.each { |i| HTML_ESCAPE[i.chr] = ' ' }
+ #ansi_chars = Array(0x7f..0xff)
+ #ansi_chars.each { |i| HTML_ESCAPE[i.chr] = '&#%d;' % i }
+ # \x9 (\t) and \xA (\n) not included
+ #HTML_ESCAPE_PATTERN = /[\t&"><\0-\x8\xB-\x1f\x7f-\xff]/
+ HTML_ESCAPE_PATTERN = /[\t"&><\0-\x8\xB-\x1f]/
+
+ TOKEN_KIND_TO_INFO = Hash.new { |h, kind|
+ h[kind] =
+ case kind
+ when :pre_constant
+ 'Predefined constant'
+ else
+ kind.to_s.gsub(/_/, ' ').gsub(/\b\w/) { $&.capitalize }
+ end
+ }
+
+ TRANSPARENT_TOKEN_KINDS = [
+ :delimiter, :modifier, :content, :escape, :inline_delimiter,
+ ].to_set
+
+ # Generate a hint about the given +classes+ in a +hint+ style.
+ #
+ # +hint+ may be :info, :info_long or :debug.
+ def self.token_path_to_hint hint, classes
+ title =
+ case hint
+ when :info
+ TOKEN_KIND_TO_INFO[classes.first]
+ when :info_long
+ classes.reverse.map { |kind| TOKEN_KIND_TO_INFO[kind] }.join('/')
+ when :debug
+ classes.inspect
+ end
+ title ? " title=\"#{title}\"" : ''
+ end
+
+ def setup options
+ super
+
+ @HTML_ESCAPE = HTML_ESCAPE.dup
+ @HTML_ESCAPE["\t"] = ' ' * options[:tab_width]
+
+ @opened = [nil]
+ @css = CSS.new options[:style]
+
+ hint = options[:hint]
+ if hint and not [:debug, :info, :info_long].include? hint
+ raise ArgumentError, "Unknown value %p for :hint; \
+ expected :info, :debug, false, or nil." % hint
+ end
+
+ case options[:css]
+
+ when :class
+ @css_style = Hash.new do |h, k|
+ c = CodeRay::Tokens::ClassOfKind[k.first]
+ if c == :NO_HIGHLIGHT and not hint
+ h[k.dup] = false
+ else
+ title = if hint
+ HTML.token_path_to_hint(hint, k[1..-1] << k.first)
+ else
+ ''
+ end
+ if c == :NO_HIGHLIGHT
+ h[k.dup] = '<span%s>' % [title]
+ else
+ h[k.dup] = '<span%s class="%s">' % [title, c]
+ end
+ end
+ end
+
+ when :style
+ @css_style = Hash.new do |h, k|
+ if k.is_a? ::Array
+ styles = k.dup
+ else
+ styles = [k]
+ end
+ type = styles.first
+ classes = styles.map { |c| Tokens::ClassOfKind[c] }
+ if classes.first == :NO_HIGHLIGHT and not hint
+ h[k] = false
+ else
+ styles.shift if TRANSPARENT_TOKEN_KINDS.include? styles.first
+ title = HTML.token_path_to_hint hint, styles
+ style = @css[*classes]
+ h[k] =
+ if style
+ '<span%s style="%s">' % [title, style]
+ else
+ false
+ end
+ end
+ end
+
+ else
+ raise ArgumentError, "Unknown value %p for :css." % options[:css]
+
+ end
+ end
+
+ def finish options
+ not_needed = @opened.shift
+ @out << '</span>' * @opened.size
+ unless @opened.empty?
+ warn '%d tokens still open: %p' % [@opened.size, @opened]
+ end
+
+ @out.extend Output
+ @out.css = @css
+ @out.numerize! options[:line_numbers], options
+ @out.wrap! options[:wrap]
+ @out.apply_title! options[:title]
+
+ super
+ end
+
+ def token text, type = :plain
+ case text
+
+ when nil
+ # raise 'Token with nil as text was given: %p' % [[text, type]]
+
+ when String
+ if text =~ /#{HTML_ESCAPE_PATTERN}/o
+ text = text.gsub(/#{HTML_ESCAPE_PATTERN}/o) { |m| @HTML_ESCAPE[m] }
+ end
+ @opened[0] = type
+ if text != "\n" && style = @css_style[@opened]
+ @out << style << text << '</span>'
+ else
+ @out << text
+ end
+
+
+ # token groups, eg. strings
+ when :open
+ @opened[0] = type
+ @out << (@css_style[@opened] || '<span>')
+ @opened << type
+ when :close
+ if @opened.empty?
+ # nothing to close
+ else
+ if $CODERAY_DEBUG and (@opened.size == 1 or @opened.last != type)
+ raise 'Malformed token stream: Trying to close a token (%p) \
+ that is not open. Open are: %p.' % [type, @opened[1..-1]]
+ end
+ @out << '</span>'
+ @opened.pop
+ end
+
+ # whole lines to be highlighted, eg. a deleted line in a diff
+ when :begin_line
+ @opened[0] = type
+ if style = @css_style[@opened]
+ if style['class="']
+ @out << style.sub('class="', 'class="line ')
+ else
+ @out << style.sub('>', ' class="line">')
+ end
+ else
+ @out << '<span class="line">'
+ end
+ @opened << type
+ when :end_line
+ if @opened.empty?
+ # nothing to close
+ else
+ if $CODERAY_DEBUG and (@opened.size == 1 or @opened.last != type)
+ raise 'Malformed token stream: Trying to close a line (%p) \
+ that is not open. Open are: %p.' % [type, @opened[1..-1]]
+ end
+ @out << '</span>'
+ @opened.pop
+ end
+
+ else
+ raise 'unknown token kind: %p' % [text]
+
+ end
+ end
+
+ end
+
+end
+end
diff --git a/vendor/gems/coderay-0.9.7/lib/coderay/encoders/html/css.rb b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/html/css.rb
new file mode 100644
index 000000000..09ac8bc07
--- /dev/null
+++ b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/html/css.rb
@@ -0,0 +1,70 @@
+module CodeRay
+module Encoders
+
+ class HTML
+ class CSS
+
+ attr :stylesheet
+
+ def CSS.load_stylesheet style = nil
+ CodeRay::Styles[style]
+ end
+
+ def initialize style = :default
+ @classes = Hash.new
+ style = CSS.load_stylesheet style
+ @stylesheet = [
+ style::CSS_MAIN_STYLES,
+ style::TOKEN_COLORS.gsub(/^(?!$)/, '.CodeRay ')
+ ].join("\n")
+ parse style::TOKEN_COLORS
+ end
+
+ def [] *styles
+ cl = @classes[styles.first]
+ return '' unless cl
+ style = ''
+ 1.upto(styles.size) do |offset|
+ break if style = cl[styles[offset .. -1]]
+ end
+ # warn 'Style not found: %p' % [styles] if style.empty?
+ return style
+ end
+
+ private
+
+ CSS_CLASS_PATTERN = /
+ ( # $1 = selectors
+ (?:
+ (?: \s* \. [-\w]+ )+
+ \s* ,?
+ )+
+ )
+ \s* \{ \s*
+ ( [^\}]+ )? # $2 = style
+ \s* \} \s*
+ |
+ ( . ) # $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
+ @classes[cl] ||= Hash.new
+ @classes[cl][classes] = style.to_s.strip.delete(' ').chomp(';')
+ end
+ end
+ end
+
+ end
+ end
+
+end
+end
+
+if $0 == __FILE__
+ require 'pp'
+ pp CodeRay::Encoders::HTML::CSS.new
+end
diff --git a/vendor/gems/coderay-0.9.7/lib/coderay/encoders/html/numerization.rb b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/html/numerization.rb
new file mode 100644
index 000000000..17e8ddb00
--- /dev/null
+++ b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/html/numerization.rb
@@ -0,0 +1,133 @@
+module CodeRay
+module Encoders
+
+ class HTML
+
+ module Output
+
+ def numerize *args
+ clone.numerize!(*args)
+ end
+
+=begin NUMERIZABLE_WRAPPINGS = {
+ :table => [:div, :page, nil],
+ :inline => :all,
+ :list => [:div, :page, nil]
+ }
+ NUMERIZABLE_WRAPPINGS.default = :all
+=end
+ def numerize! mode = :table, options = {}
+ return self unless mode
+
+ options = DEFAULT_OPTIONS.merge options
+
+ start = options[:line_number_start]
+ unless start.is_a? Integer
+ raise ArgumentError, "Invalid value %p for :line_number_start; Integer expected." % start
+ end
+
+ #allowed_wrappings = NUMERIZABLE_WRAPPINGS[mode]
+ #unless allowed_wrappings == :all or allowed_wrappings.include? options[:wrap]
+ # raise ArgumentError, "Can't numerize, :wrap must be in %p, but is %p" % [NUMERIZABLE_WRAPPINGS, options[:wrap]]
+ #end
+
+ bold_every = options[:bold_every]
+ highlight_lines = options[:highlight_lines]
+ bolding =
+ if bold_every == false && highlight_lines == nil
+ proc { |line| line.to_s }
+ elsif highlight_lines.is_a? Enumerable
+ highlight_lines = highlight_lines.to_set
+ proc do |line|
+ if highlight_lines.include? line
+ "<strong class=\"highlighted\">#{line}</strong>" # highlighted line numbers in bold
+ else
+ line.to_s
+ end
+ end
+ elsif bold_every.is_a? Integer
+ raise ArgumentError, ":bolding can't be 0." if bold_every == 0
+ proc do |line|
+ if line % bold_every == 0
+ "<strong>#{line}</strong>" # every bold_every-th number in bold
+ else
+ line.to_s
+ end
+ end
+ else
+ raise ArgumentError, 'Invalid value %p for :bolding; false or Integer expected.' % bold_every
+ end
+
+ case mode
+ when :inline
+ max_width = (start + line_count).to_s.size
+ line_number = start
+ gsub!(/^/) do
+ line_number_text = bolding.call line_number
+ indent = ' ' * (max_width - line_number.to_s.size) # TODO: Optimize (10^x)
+ res = "<span class=\"no\">#{indent}#{line_number_text}</span> "
+ line_number += 1
+ res
+ end
+
+ when :table
+ # This is really ugly.
+ # Because even monospace fonts seem to have different heights when bold,
+ # I make the newline bold, both in the code and the line numbers.
+ # FIXME Still not working perfect for Mr. Internet Exploder
+ line_numbers = (start ... start + line_count).to_a.map(&bolding).join("\n")
+ line_numbers << "\n" # also for Mr. MS Internet Exploder :-/
+ line_numbers.gsub!(/\n/) { "<tt>\n</tt>" }
+
+ line_numbers_table_tpl = TABLE.apply('LINE_NUMBERS', line_numbers)
+ gsub!("</div>\n", '</div>')
+ gsub!("\n", "<tt>\n</tt>")
+ wrap_in! line_numbers_table_tpl
+ @wrapped_in = :div
+
+ when :list
+ opened_tags = []
+ gsub!(/^.*$\n?/) do |line|
+ line.chomp!
+
+ open = opened_tags.join
+ line.scan(%r!<(/)?span[^>]*>?!) do |close,|
+ if close
+ opened_tags.pop
+ else
+ opened_tags << $&
+ end
+ end
+ close = '</span>' * opened_tags.size
+
+ "<li>#{open}#{line}#{close}</li>\n"
+ end
+ chomp!("\n")
+ wrap_in! LIST
+ @wrapped_in = :div
+
+ else
+ raise ArgumentError, 'Unknown value %p for mode: expected one of %p' %
+ [mode, [:table, :list, :inline]]
+ end
+
+ self
+ end
+
+ def line_count
+ line_count = count("\n")
+ position_of_last_newline = rindex(?\n)
+ if position_of_last_newline
+ after_last_newline = self[position_of_last_newline + 1 .. -1]
+ ends_with_newline = after_last_newline[/\A(?:<\/span>)*\z/]
+ line_count += 1 if not ends_with_newline
+ end
+ line_count
+ end
+
+ end
+
+ end
+
+end
+end
diff --git a/vendor/gems/coderay-0.9.7/lib/coderay/encoders/html/output.rb b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/html/output.rb
new file mode 100644
index 000000000..28574a5de
--- /dev/null
+++ b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/html/output.rb
@@ -0,0 +1,206 @@
+module CodeRay
+module Encoders
+
+ class HTML
+
+ # This module is included in the output String from thew HTML Encoder.
+ #
+ # It provides methods like wrap, div, page etc.
+ #
+ # Remember to use #clone instead of #dup to keep the modules the object was
+ # extended with.
+ #
+ # TODO: more doc.
+ module Output
+
+ require 'coderay/encoders/html/numerization.rb'
+
+ attr_accessor :css
+
+ class << self
+
+ # This makes Output look like a class.
+ #
+ # Example:
+ #
+ # a = Output.new '<span class="co">Code</span>'
+ # a.wrap! :page
+ def new string, css = CSS.new, element = nil
+ output = string.clone.extend self
+ output.wrapped_in = element
+ output.css = css
+ output
+ end
+
+ # Raises an exception if an object that doesn't respond to to_str is extended by Output,
+ # to prevent users from misuse. Use Module#remove_method to disable.
+ def extended o
+ warn "The Output module is intended to extend instances of String, not #{o.class}." unless o.respond_to? :to_str
+ end
+
+ def make_stylesheet css, in_tag = false
+ sheet = css.stylesheet
+ sheet = <<-CSS if in_tag
+<style type="text/css">
+#{sheet}
+</style>
+ CSS
+ sheet
+ end
+
+ def page_template_for_css css
+ sheet = make_stylesheet css
+ PAGE.apply 'CSS', sheet
+ end
+
+ # Define a new wrapper. This is meta programming.
+ def wrapper *wrappers
+ wrappers.each do |wrapper|
+ define_method wrapper do |*args|
+ wrap wrapper, *args
+ end
+ define_method "#{wrapper}!".to_sym do |*args|
+ wrap! wrapper, *args
+ end
+ end
+ end
+
+ end
+
+ wrapper :div, :span, :page
+
+ def wrapped_in? element
+ wrapped_in == element
+ end
+
+ def wrapped_in
+ @wrapped_in ||= nil
+ end
+ attr_writer :wrapped_in
+
+ def wrap_in template
+ clone.wrap_in! template
+ end
+
+ def wrap_in! template
+ Template.wrap! self, template, 'CONTENT'
+ self
+ end
+
+ def apply_title! title
+ self.sub!(/(<title>)(<\/title>)/) { $1 + title + $2 }
+ self
+ end
+
+ def wrap! element, *args
+ return self if not element or element == wrapped_in
+ case element
+ when :div
+ raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? nil
+ wrap_in! DIV
+ when :span
+ raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? nil
+ wrap_in! SPAN
+ when :page
+ wrap! :div if wrapped_in? nil
+ raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? :div
+ wrap_in! Output.page_template_for_css(@css)
+ if args.first.is_a?(Hash) && title = args.first[:title]
+ apply_title! title
+ end
+ self
+ when nil
+ return self
+ else
+ raise "Unknown value %p for :wrap" % element
+ end
+ @wrapped_in = element
+ self
+ end
+
+ def wrap *args
+ clone.wrap!(*args)
+ end
+
+ def stylesheet in_tag = false
+ Output.make_stylesheet @css, in_tag
+ end
+
+ class Template < String
+
+ def self.wrap! str, template, target
+ target = Regexp.new(Regexp.escape("<%#{target}%>"))
+ if template =~ target
+ str[0,0] = $`
+ str << $'
+ else
+ raise "Template target <%%%p%%> not found" % target
+ end
+ end
+
+ def apply target, replacement
+ target = Regexp.new(Regexp.escape("<%#{target}%>"))
+ if self =~ target
+ Template.new($` + replacement + $')
+ else
+ raise "Template target <%%%p%%> not found" % target
+ end
+ end
+
+ module Simple
+ def ` str #` <-- for stupid editors
+ Template.new str
+ end
+ end
+ end
+
+ extend Template::Simple
+
+#-- don't include the templates in docu
+
+ SPAN = `<span class="CodeRay"><%CONTENT%></span>`
+
+ DIV = <<-`DIV`
+<div class="CodeRay">
+ <div class="code"><pre><%CONTENT%></pre></div>
+</div>
+ DIV
+
+ TABLE = <<-`TABLE`
+<table class="CodeRay"><tr>
+ <td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><%LINE_NUMBERS%></pre></td>
+ <td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><%CONTENT%></pre></td>
+</tr></table>
+ TABLE
+ # title="double click to expand"
+
+ LIST = <<-`LIST`
+<ol class="CodeRay">
+<%CONTENT%>
+</ol>
+ LIST
+
+ PAGE = <<-`PAGE`
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="de">
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+ <title></title>
+ <style type="text/css">
+<%CSS%>
+ </style>
+</head>
+<body style="background-color: white;">
+
+<%CONTENT%>
+</body>
+</html>
+ PAGE
+
+ end
+
+ end
+
+end
+end
diff --git a/vendor/gems/coderay-0.9.7/lib/coderay/encoders/json.rb b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/json.rb
new file mode 100644
index 000000000..7aa077c28
--- /dev/null
+++ b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/json.rb
@@ -0,0 +1,69 @@
+($:.unshift '../..'; require 'coderay') unless defined? CodeRay
+module CodeRay
+module Encoders
+
+ # = JSON Encoder
+ class JSON < Encoder
+
+ register_for :json
+ FILE_EXTENSION = 'json'
+
+ protected
+ def setup options
+ begin
+ require 'json'
+ rescue LoadError
+ require 'rubygems'
+ require 'json'
+ end
+ @out = []
+ end
+
+ def text_token text, kind
+ { :type => 'text', :text => text, :kind => kind }
+ end
+
+ def block_token action, kind
+ { :type => 'block', :action => action, :kind => kind }
+ end
+
+ def finish options
+ @out.to_json
+ end
+
+ end
+
+end
+end
+
+if $0 == __FILE__
+ $VERBOSE = true
+ $: << File.join(File.dirname(__FILE__), '..')
+ eval DATA.read, nil, $0, __LINE__ + 4
+end
+
+__END__
+require 'test/unit'
+$:.delete '.'
+require 'rubygems' if RUBY_VERSION < '1.9'
+
+class JSONEncoderTest < Test::Unit::TestCase
+
+ def test_json_output
+ tokens = CodeRay.scan <<-RUBY, :ruby
+puts "Hello world!"
+ RUBY
+ require 'json'
+ assert_equal [
+ {"type"=>"text", "text"=>"puts", "kind"=>"ident"},
+ {"type"=>"text", "text"=>" ", "kind"=>"space"},
+ {"type"=>"block", "action"=>"open", "kind"=>"string"},
+ {"type"=>"text", "text"=>"\"", "kind"=>"delimiter"},
+ {"type"=>"text", "text"=>"Hello world!", "kind"=>"content"},
+ {"type"=>"text", "text"=>"\"", "kind"=>"delimiter"},
+ {"type"=>"block", "action"=>"close", "kind"=>"string"},
+ {"type"=>"text", "text"=>"\n", "kind"=>"space"}
+ ], JSON.load(tokens.json)
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/coderay-0.9.7/lib/coderay/encoders/lines_of_code.rb b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/lines_of_code.rb
new file mode 100644
index 000000000..c1ad66e2e
--- /dev/null
+++ b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/lines_of_code.rb
@@ -0,0 +1,90 @@
+($:.unshift '../..'; require 'coderay') unless defined? CodeRay
+module CodeRay
+module Encoders
+
+ # Counts the LoC (Lines of Code). Returns an Integer >= 0.
+ #
+ # Alias: :loc
+ #
+ # Everything that is not comment, markup, doctype/shebang, or an empty line,
+ # is considered to be code.
+ #
+ # For example,
+ # * HTML files not containing JavaScript have 0 LoC
+ # * in a Java class without comments, LoC is the number of non-empty lines
+ #
+ # A Scanner class should define the token kinds that are not code in the
+ # KINDS_NOT_LOC constant, which defaults to [:comment, :doctype].
+ class LinesOfCode < Encoder
+
+ register_for :lines_of_code
+
+ NON_EMPTY_LINE = /^\s*\S.*$/
+
+ def compile tokens, options
+ if scanner = tokens.scanner
+ kinds_not_loc = scanner.class::KINDS_NOT_LOC
+ else
+ warn ArgumentError, 'Tokens have no scanner.' if $VERBOSE
+ kinds_not_loc = CodeRay::Scanners::Scanner::KINDS_NOT_LOC
+ end
+ code = tokens.token_class_filter :exclude => kinds_not_loc
+ @loc = code.text.scan(NON_EMPTY_LINE).size
+ end
+
+ def finish options
+ @loc
+ end
+
+ end
+
+end
+end
+
+if $0 == __FILE__
+ $VERBOSE = true
+ $: << File.join(File.dirname(__FILE__), '..')
+ eval DATA.read, nil, $0, __LINE__ + 4
+end
+
+__END__
+require 'test/unit'
+
+class LinesOfCodeTest < Test::Unit::TestCase
+
+ def test_creation
+ assert CodeRay::Encoders::LinesOfCode < CodeRay::Encoders::Encoder
+ filter = nil
+ assert_nothing_raised do
+ filter = CodeRay.encoder :loc
+ end
+ assert_kind_of CodeRay::Encoders::LinesOfCode, filter
+ assert_nothing_raised do
+ filter = CodeRay.encoder :lines_of_code
+ end
+ assert_kind_of CodeRay::Encoders::LinesOfCode, filter
+ end
+
+ def test_lines_of_code
+ tokens = CodeRay.scan <<-RUBY, :ruby
+#!/usr/bin/env ruby
+
+# a minimal Ruby program
+puts "Hello world!"
+ RUBY
+ assert_equal 1, CodeRay::Encoders::LinesOfCode.new.encode_tokens(tokens)
+ assert_equal 1, tokens.lines_of_code
+ assert_equal 1, tokens.loc
+ end
+
+ def test_filtering_block_tokens
+ tokens = CodeRay::Tokens.new
+ tokens << ["Hello\n", :world]
+ tokens << ["Hello\n", :space]
+ tokens << ["Hello\n", :comment]
+ assert_equal 2, CodeRay::Encoders::LinesOfCode.new.encode_tokens(tokens)
+ assert_equal 2, tokens.lines_of_code
+ assert_equal 2, tokens.loc
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/coderay-0.9.7/lib/coderay/encoders/null.rb b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/null.rb
new file mode 100644
index 000000000..add3862a3
--- /dev/null
+++ b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/null.rb
@@ -0,0 +1,26 @@
+module CodeRay
+module Encoders
+
+ # = Null Encoder
+ #
+ # Does nothing and returns an empty string.
+ class Null < Encoder
+
+ include Streamable
+ register_for :null
+
+ # Defined for faster processing
+ def to_proc
+ proc {}
+ end
+
+ protected
+
+ def token(*)
+ # do nothing
+ end
+
+ end
+
+end
+end
diff --git a/vendor/gems/coderay-0.9.7/lib/coderay/encoders/page.rb b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/page.rb
new file mode 100644
index 000000000..1b69cce97
--- /dev/null
+++ b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/page.rb
@@ -0,0 +1,20 @@
+module CodeRay
+module Encoders
+
+ load :html
+
+ class Page < HTML
+
+ FILE_EXTENSION = 'html'
+
+ register_for :page
+
+ DEFAULT_OPTIONS = HTML::DEFAULT_OPTIONS.merge \
+ :css => :class,
+ :wrap => :page,
+ :line_numbers => :table
+
+ end
+
+end
+end
diff --git a/vendor/gems/coderay-0.9.7/lib/coderay/encoders/span.rb b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/span.rb
new file mode 100644
index 000000000..319f6fd09
--- /dev/null
+++ b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/span.rb
@@ -0,0 +1,19 @@
+module CodeRay
+module Encoders
+
+ load :html
+
+ class Span < HTML
+
+ FILE_EXTENSION = 'span.html'
+
+ register_for :span
+
+ DEFAULT_OPTIONS = HTML::DEFAULT_OPTIONS.merge \
+ :css => :style,
+ :wrap => :span
+
+ end
+
+end
+end
diff --git a/vendor/gems/coderay-0.9.7/lib/coderay/encoders/statistic.rb b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/statistic.rb
new file mode 100644
index 000000000..6d0c64680
--- /dev/null
+++ b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/statistic.rb
@@ -0,0 +1,77 @@
+module CodeRay
+module Encoders
+
+ # Makes a statistic for the given tokens.
+ class Statistic < Encoder
+
+ include Streamable
+ register_for :stats, :statistic
+
+ attr_reader :type_stats, :real_token_count
+
+ protected
+
+ TypeStats = Struct.new :count, :size
+
+ def setup options
+ @type_stats = Hash.new { |h, k| h[k] = TypeStats.new 0, 0 }
+ @real_token_count = 0
+ end
+
+ def generate tokens, options
+ @tokens = tokens
+ super
+ end
+
+ def text_token text, kind
+ @real_token_count += 1 unless kind == :space
+ @type_stats[kind].count += 1
+ @type_stats[kind].size += text.size
+ @type_stats['TOTAL'].size += text.size
+ @type_stats['TOTAL'].count += 1
+ end
+
+ # TODO Hierarchy handling
+ def block_token action, kind
+ @type_stats['TOTAL'].count += 1
+ @type_stats['open/close'].count += 1
+ end
+
+ STATS = <<-STATS
+
+Code Statistics
+
+Tokens %8d
+ Non-Whitespace %8d
+Bytes Total %8d
+
+Token Types (%d):
+ type count ratio size (average)
+-------------------------------------------------------------
+%s
+ STATS
+# space 12007 33.81 % 1.7
+ TOKEN_TYPES_ROW = <<-TKR
+ %-20s %8d %6.2f %% %5.1f
+ TKR
+
+ def finish options
+ all = @type_stats['TOTAL']
+ all_count, all_size = all.count, all.size
+ @type_stats.each do |type, stat|
+ stat.size /= stat.count.to_f
+ end
+ types_stats = @type_stats.sort_by { |k, v| [-v.count, k.to_s] }.map do |k, v|
+ TOKEN_TYPES_ROW % [k, v.count, 100.0 * v.count / all_count, v.size]
+ end.join
+ STATS % [
+ all_count, @real_token_count, all_size,
+ @type_stats.delete_if { |k, v| k.is_a? String }.size,
+ types_stats
+ ]
+ end
+
+ end
+
+end
+end
diff --git a/vendor/gems/coderay-0.9.7/lib/coderay/encoders/term.rb b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/term.rb
new file mode 100644
index 000000000..1f284ed13
--- /dev/null
+++ b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/term.rb
@@ -0,0 +1,158 @@
+# encoders/term.rb
+# By Rob Aldred (http://robaldred.co.uk)
+# Based on idea by Nathan Weizenbaum (http://nex-3.com)
+# MIT License (http://www.opensource.org/licenses/mit-license.php)
+#
+# A CodeRay encoder that outputs code highlighted for a color terminal.
+# Check out http://robaldred.co.uk
+
+module CodeRay
+ module Encoders
+ class Term < Encoder
+ register_for :term
+
+ TOKEN_COLORS = {
+ :annotation => '35',
+ :attribute_name => '33',
+ :attribute_name_fat => '33',
+ :attribute_value => '31',
+ :attribute_value_fat => '31',
+ :bin => '1;35',
+ :char => {:self => '36', :delimiter => '34'},
+ :class => '1;35',
+ :class_variable => '36',
+ :color => '32',
+ :comment => '37',
+ :complex => '34',
+ :constant => ['34', '4'],
+ :decoration => '35',
+ :definition => '1;32',
+ :directive => ['32', '4'],
+ :doc => '46',
+ :doctype => '1;30',
+ :doc_string => ['31', '4'],
+ :entity => '33',
+ :error => ['1;33', '41'],
+ :exception => '1;31',
+ :float => '1;35',
+ :function => '1;34',
+ :global_variable => '42',
+ :hex => '1;36',
+ :important => '1;31',
+ :include => '33',
+ :integer => '1;34',
+ :interpreted => '1;35',
+ :key => '35',
+ :label => '1;4',
+ :local_variable => '33',
+ :oct => '1;35',
+ :operator_name => '1;29',
+ :pre_constant => '1;36',
+ :pre_type => '1;30',
+ :predefined => ['4', '1;34'],
+ :preprocessor => '36',
+ :pseudo_class => '34',
+ :regexp => {
+ :content => '31',
+ :delimiter => '1;29',
+ :modifier => '35',
+ :function => '1;29'
+ },
+ :reserved => '1;31',
+ :shell => {
+ :self => '42',
+ :content => '1;29',
+ :delimiter => '37',
+ },
+ :string => {
+ :self => '32',
+ :modifier => '1;32',
+ :escape => '1;36',
+ :delimiter => '1;32',
+ },
+ :symbol => '1;32',
+ :tag => '34',
+ :tag_fat => '1;34',
+ :tag_special => ['34', '4'],
+ :type => '1;34',
+ :value => '36',
+ :variable => '34',
+ :insert => '42',
+ :delete => '41',
+ :change => '44',
+ :head => '45',
+ }
+ TOKEN_COLORS[:keyword] = TOKEN_COLORS[:reserved]
+ TOKEN_COLORS[:method] = TOKEN_COLORS[:function]
+ TOKEN_COLORS[:imaginary] = TOKEN_COLORS[:complex]
+ TOKEN_COLORS[:open] = TOKEN_COLORS[:close] = TOKEN_COLORS[:nesting_delimiter] = TOKEN_COLORS[:escape] = TOKEN_COLORS[:delimiter]
+
+ protected
+
+ def setup(options)
+ @out = ''
+ @opened = [nil]
+ @subcolors = nil
+ end
+
+ def finish(options)
+ super
+ end
+
+ def token text, type = :plain
+ case text
+
+ when nil
+ # raise 'Token with nil as text was given: %p' % [[text, type]]
+
+ when String
+
+ if color = (@subcolors || TOKEN_COLORS)[type]
+ color = color[:self] || return if Hash === color
+
+ @out << col(color) + text.gsub("\n", col(0) + "\n" + col(color)) + col(0)
+ @out << col(@subcolors[:self]) if @subcolors && @subcolors[:self]
+ else
+ @out << text
+ end
+
+ # token groups, eg. strings
+ when :open
+ @opened[0] = type
+ if color = TOKEN_COLORS[type]
+ if Hash === color
+ @subcolors = color
+ @out << col(color[:self]) if color[:self]
+ else
+ @subcolors = {}
+ @out << col(color)
+ end
+ end
+ @opened << type
+ when :close
+ if @opened.empty?
+ # nothing to close
+ else
+ @out << col(0) if (@subcolors || {})[:self]
+ @subcolors = nil
+ @opened.pop
+ end
+
+ # whole lines to be highlighted, eg. a added/modified/deleted lines in a diff
+ when :begin_line
+
+ when :end_line
+
+ else
+ raise 'unknown token kind: %p' % [text]
+ end
+ end
+
+ private
+
+ def col(color)
+ Array(color).map { |c| "\e[#{c}m" }.join
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/coderay-0.9.7/lib/coderay/encoders/text.rb b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/text.rb
new file mode 100644
index 000000000..161ee67c5
--- /dev/null
+++ b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/text.rb
@@ -0,0 +1,32 @@
+module CodeRay
+module Encoders
+
+ class Text < Encoder
+
+ include Streamable
+ register_for :text
+
+ FILE_EXTENSION = 'txt'
+
+ DEFAULT_OPTIONS = {
+ :separator => ''
+ }
+
+ protected
+ def setup options
+ super
+ @sep = options[:separator]
+ end
+
+ def text_token text, kind
+ text + @sep
+ end
+
+ def finish options
+ super.chomp @sep
+ end
+
+ end
+
+end
+end
diff --git a/vendor/gems/coderay-0.9.7/lib/coderay/encoders/token_class_filter.rb b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/token_class_filter.rb
new file mode 100644
index 000000000..a9e8673a3
--- /dev/null
+++ b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/token_class_filter.rb
@@ -0,0 +1,84 @@
+($:.unshift '../..'; require 'coderay') unless defined? CodeRay
+module CodeRay
+module Encoders
+
+ load :filter
+
+ class TokenClassFilter < Filter
+
+ include Streamable
+ register_for :token_class_filter
+
+ DEFAULT_OPTIONS = {
+ :exclude => [],
+ :include => :all
+ }
+
+ protected
+ def setup options
+ super
+ @exclude = options[:exclude]
+ @exclude = Array(@exclude) unless @exclude == :all
+ @include = options[:include]
+ @include = Array(@include) unless @include == :all
+ end
+
+ def include_text_token? text, kind
+ (@include == :all || @include.include?(kind)) &&
+ !(@exclude == :all || @exclude.include?(kind))
+ end
+
+ end
+
+end
+end
+
+if $0 == __FILE__
+ $VERBOSE = true
+ $: << File.join(File.dirname(__FILE__), '..')
+ eval DATA.read, nil, $0, __LINE__ + 4
+end
+
+__END__
+require 'test/unit'
+
+class TokenClassFilterTest < Test::Unit::TestCase
+
+ def test_creation
+ assert CodeRay::Encoders::TokenClassFilter < CodeRay::Encoders::Encoder
+ assert CodeRay::Encoders::TokenClassFilter < CodeRay::Encoders::Filter
+ filter = nil
+ assert_nothing_raised do
+ filter = CodeRay.encoder :token_class_filter
+ end
+ assert_instance_of CodeRay::Encoders::TokenClassFilter, filter
+ end
+
+ def test_filtering_text_tokens
+ tokens = CodeRay::Tokens.new
+ for i in 1..10
+ tokens << [i.to_s, :index]
+ tokens << [' ', :space] if i < 10
+ end
+ assert_equal 10, CodeRay::Encoders::TokenClassFilter.new.encode_tokens(tokens, :exclude => :space).size
+ assert_equal 10, tokens.token_class_filter(:exclude => :space).size
+ assert_equal 9, CodeRay::Encoders::TokenClassFilter.new.encode_tokens(tokens, :include => :space).size
+ assert_equal 9, tokens.token_class_filter(:include => :space).size
+ assert_equal 0, CodeRay::Encoders::TokenClassFilter.new.encode_tokens(tokens, :exclude => :all).size
+ assert_equal 0, tokens.token_class_filter(:exclude => :all).size
+ end
+
+ def test_filtering_block_tokens
+ tokens = CodeRay::Tokens.new
+ 10.times do |i|
+ tokens << [:open, :index]
+ tokens << [i.to_s, :content]
+ tokens << [:close, :index]
+ end
+ assert_equal 20, CodeRay::Encoders::TokenClassFilter.new.encode_tokens(tokens, :include => :blubb).size
+ assert_equal 20, tokens.token_class_filter(:include => :blubb).size
+ assert_equal 30, CodeRay::Encoders::TokenClassFilter.new.encode_tokens(tokens, :exclude => :index).size
+ assert_equal 30, tokens.token_class_filter(:exclude => :index).size
+ end
+
+end
diff --git a/vendor/gems/coderay-0.9.7/lib/coderay/encoders/xml.rb b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/xml.rb
new file mode 100644
index 000000000..f32c967bc
--- /dev/null
+++ b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/xml.rb
@@ -0,0 +1,71 @@
+module CodeRay
+module Encoders
+
+ # = XML Encoder
+ #
+ # Uses REXML. Very slow.
+ class XML < Encoder
+
+ include Streamable
+ register_for :xml
+
+ FILE_EXTENSION = 'xml'
+
+ require 'rexml/document'
+
+ DEFAULT_OPTIONS = {
+ :tab_width => 8,
+ :pretty => -1,
+ :transitive => false,
+ }
+
+ protected
+
+ def setup options
+ @doc = REXML::Document.new
+ @doc << REXML::XMLDecl.new
+ @tab_width = options[:tab_width]
+ @root = @node = @doc.add_element('coderay-tokens')
+ end
+
+ def finish options
+ @out = ''
+ @doc.write @out, options[:pretty], options[:transitive], true
+ @out
+ end
+
+ def text_token text, kind
+ if kind == :space
+ token = @node
+ else
+ token = @node.add_element kind.to_s
+ end
+ text.scan(/(\x20+)|(\t+)|(\n)|[^\x20\t\n]+/) do |space, tab, nl|
+ case
+ when space
+ token << REXML::Text.new(space, true)
+ when tab
+ token << REXML::Text.new(tab, true)
+ when nl
+ token << REXML::Text.new(nl, true)
+ else
+ token << REXML::Text.new($&)
+ end
+ end
+ end
+
+ def open_token kind
+ @node = @node.add_element kind.to_s
+ end
+
+ def close_token kind
+ if @node == @root
+ raise 'no token to close!'
+ end
+ @node = @node.parent
+ end
+
+ end
+
+end
+end
diff --git a/vendor/gems/coderay-0.9.7/lib/coderay/encoders/yaml.rb b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/yaml.rb
new file mode 100644
index 000000000..5564e58a4
--- /dev/null
+++ b/vendor/gems/coderay-0.9.7/lib/coderay/encoders/yaml.rb
@@ -0,0 +1,22 @@
+module CodeRay
+module Encoders
+
+ # = YAML Encoder
+ #
+ # Slow.
+ class YAML < Encoder
+
+ register_for :yaml
+
+ FILE_EXTENSION = 'yaml'
+
+ protected
+ def compile tokens, options
+ require 'yaml'
+ @out = tokens.to_a.to_yaml
+ end
+
+ end
+
+end
+end