summaryrefslogtreecommitdiff
path: root/lib/coderay/encoders
diff options
context:
space:
mode:
Diffstat (limited to 'lib/coderay/encoders')
-rw-r--r--lib/coderay/encoders/debug.rb23
-rw-r--r--lib/coderay/encoders/debug_lint.rb63
-rw-r--r--lib/coderay/encoders/html.rb29
-rw-r--r--lib/coderay/encoders/html/numbering.rb4
-rw-r--r--lib/coderay/encoders/lint.rb59
-rw-r--r--lib/coderay/encoders/statistic.rb1
-rw-r--r--lib/coderay/encoders/terminal.rb179
7 files changed, 247 insertions, 111 deletions
diff --git a/lib/coderay/encoders/debug.rb b/lib/coderay/encoders/debug.rb
index c03d3fb..f4db330 100644
--- a/lib/coderay/encoders/debug.rb
+++ b/lib/coderay/encoders/debug.rb
@@ -9,7 +9,6 @@ module Encoders
#
# You cannot fully restore the tokens information from the
# output, because consecutive :space tokens are merged.
- # Use Tokens#dump for caching purposes.
#
# See also: Scanners::Debug
class Debug < Encoder
@@ -18,38 +17,26 @@ module Encoders
FILE_EXTENSION = 'raydebug'
- def initialize options = {}
- super
- @opened = []
- end
-
def text_token text, kind
- raise 'empty token' if $CODERAY_DEBUG && text.empty?
if kind == :space
@out << text
else
- # TODO: Escape (
- text = text.gsub(/[)\\]/, '\\\\\0') if text.index(/[)\\]/)
- @out << kind.to_s << '(' << text << ')'
+ text = text.gsub('\\', '\\\\\\\\') if text.index('\\')
+ text = text.gsub(')', '\\\\)') if text.index(')')
+ @out << "#{kind}(#{text})"
end
end
def begin_group kind
- @opened << kind
- @out << kind.to_s << '<'
+ @out << "#{kind}<"
end
def end_group kind
- if @opened.last != kind
- puts @out
- raise "we are inside #{@opened.inspect}, not #{kind}"
- end
- @opened.pop
@out << '>'
end
def begin_line kind
- @out << kind.to_s << '['
+ @out << "#{kind}["
end
def end_line kind
diff --git a/lib/coderay/encoders/debug_lint.rb b/lib/coderay/encoders/debug_lint.rb
new file mode 100644
index 0000000..a4eba2c
--- /dev/null
+++ b/lib/coderay/encoders/debug_lint.rb
@@ -0,0 +1,63 @@
+module CodeRay
+module Encoders
+
+ load :lint
+
+ # = Debug Lint Encoder
+ #
+ # Debug encoder with additional checks for:
+ #
+ # - empty tokens
+ # - incorrect nesting
+ #
+ # It will raise an InvalidTokenStream exception when any of the above occurs.
+ #
+ # See also: Encoders::Debug
+ class DebugLint < Debug
+
+ register_for :debug_lint
+
+ def text_token text, kind
+ raise Lint::EmptyToken, 'empty token for %p' % [kind] if text.empty?
+ raise Lint::UnknownTokenKind, 'unknown token kind %p (text was %p)' % [kind, text] unless TokenKinds.has_key? kind
+ super
+ end
+
+ def begin_group kind
+ @opened << kind
+ super
+ end
+
+ def end_group kind
+ raise Lint::IncorrectTokenGroupNesting, 'We are inside %s, not %p (end_group)' % [@opened.reverse.map(&:inspect).join(' < '), kind] if @opened.last != kind
+ @opened.pop
+ super
+ end
+
+ def begin_line kind
+ @opened << kind
+ super
+ end
+
+ def end_line kind
+ raise Lint::IncorrectTokenGroupNesting, 'We are inside %s, not %p (end_line)' % [@opened.reverse.map(&:inspect).join(' < '), kind] if @opened.last != kind
+ @opened.pop
+ super
+ end
+
+ protected
+
+ def setup options
+ super
+ @opened = []
+ end
+
+ def finish options
+ raise 'Some tokens still open at end of token stream: %p' % [@opened] unless @opened.empty?
+ super
+ end
+
+ end
+
+end
+end
diff --git a/lib/coderay/encoders/html.rb b/lib/coderay/encoders/html.rb
index b897f5e..942b9c8 100644
--- a/lib/coderay/encoders/html.rb
+++ b/lib/coderay/encoders/html.rb
@@ -25,7 +25,8 @@ module Encoders
# == Options
#
# === :tab_width
- # Convert \t characters to +n+ spaces (a number.)
+ # Convert \t characters to +n+ spaces (a number or false.)
+ # false will keep tab characters untouched.
#
# Default: 8
#
@@ -180,7 +181,7 @@ module Encoders
@break_lines = (options[:break_lines] == true)
- @HTML_ESCAPE = HTML_ESCAPE.merge("\t" => ' ' * options[:tab_width])
+ @HTML_ESCAPE = HTML_ESCAPE.merge("\t" => options[:tab_width] ? ' ' * options[:tab_width] : "\t")
@opened = []
@last_opened = nil
@@ -193,18 +194,19 @@ module Encoders
def finish options
unless @opened.empty?
- warn '%d tokens still open: %p' % [@opened.size, @opened] if $CODERAY_DEBUG
@out << '</span>' while @opened.pop
@last_opened = nil
end
- @out.extend Output
- @out.css = @css
- if options[:line_numbers]
- Numbering.number! @out, options[:line_numbers], options
+ if @out.respond_to? :to_str
+ @out.extend Output
+ @out.css = @css
+ if options[:line_numbers]
+ Numbering.number! @out, options[:line_numbers], options
+ end
+ @out.wrap! options[:wrap]
+ @out.apply_title! options[:title]
end
- @out.wrap! options[:wrap]
- @out.apply_title! options[:title]
if defined?(@real_out) && @real_out
@real_out << @out
@@ -286,7 +288,7 @@ module Encoders
def make_span_for_kinds method, hint
Hash.new do |h, kinds|
- h[kinds.is_a?(Symbol) ? kinds : kinds.dup] = begin
+ begin
css_class = css_class_for_kinds(kinds)
title = HTML.token_path_to_hint hint, kinds if hint
@@ -298,6 +300,9 @@ module Encoders
"<span#{title}#{" class=\"#{css_class}\"" if css_class}>"
end
end
+ end.tap do |span|
+ h.clear if h.size >= 100
+ h[kinds] = span
end
end
end
@@ -310,8 +315,8 @@ module Encoders
def break_lines text, style
reopen = ''
- @opened.each_with_index do |k, index|
- reopen << (@span_for_kinds[index > 0 ? [k, *@opened[0...index]] : k] || '<span>')
+ @opened.each_with_index do |kind, index|
+ reopen << (@span_for_kinds[index > 0 ? [kind, *@opened[0...index]] : kind] || '<span>')
end
text.gsub("\n", "#{'</span>' * @opened.size}#{'</span>' if style}\n#{reopen}#{style}")
end
diff --git a/lib/coderay/encoders/html/numbering.rb b/lib/coderay/encoders/html/numbering.rb
index 332145b..a1b9c04 100644
--- a/lib/coderay/encoders/html/numbering.rb
+++ b/lib/coderay/encoders/html/numbering.rb
@@ -26,7 +26,7 @@ module Encoders
"<a href=\"##{anchor}\" name=\"#{anchor}\">#{line}</a>"
end
else
- proc { |line| line.to_s } # :to_s.to_proc in Ruby 1.8.7+
+ :to_s.to_proc
end
bold_every = options[:bold_every]
@@ -75,7 +75,7 @@ module Encoders
line_number = start
output.gsub!(/^.*$\n?/) do |line|
line_number_text = bolding.call line_number
- indent = ' ' * (max_width - line_number.to_s.size) # TODO: Optimize (10^x)
+ indent = ' ' * (max_width - line_number.to_s.size)
line_number += 1
"<span class=\"line-numbers\">#{indent}#{line_number_text}</span>#{line}"
end
diff --git a/lib/coderay/encoders/lint.rb b/lib/coderay/encoders/lint.rb
new file mode 100644
index 0000000..88c8bd1
--- /dev/null
+++ b/lib/coderay/encoders/lint.rb
@@ -0,0 +1,59 @@
+module CodeRay
+module Encoders
+
+ # = Lint Encoder
+ #
+ # Checks for:
+ #
+ # - empty tokens
+ # - incorrect nesting
+ #
+ # It will raise an InvalidTokenStream exception when any of the above occurs.
+ #
+ # See also: Encoders::DebugLint
+ class Lint < Debug
+
+ register_for :lint
+
+ InvalidTokenStream = Class.new StandardError
+ EmptyToken = Class.new InvalidTokenStream
+ UnknownTokenKind = Class.new InvalidTokenStream
+ IncorrectTokenGroupNesting = Class.new InvalidTokenStream
+
+ def text_token text, kind
+ raise EmptyToken, 'empty token for %p' % [kind] if text.empty?
+ raise UnknownTokenKind, 'unknown token kind %p (text was %p)' % [kind, text] unless TokenKinds.has_key? kind
+ end
+
+ def begin_group kind
+ @opened << kind
+ end
+
+ def end_group kind
+ raise IncorrectTokenGroupNesting, 'We are inside %s, not %p (end_group)' % [@opened.reverse.map(&:inspect).join(' < '), kind] if @opened.last != kind
+ @opened.pop
+ end
+
+ def begin_line kind
+ @opened << kind
+ end
+
+ def end_line kind
+ raise IncorrectTokenGroupNesting, 'We are inside %s, not %p (end_line)' % [@opened.reverse.map(&:inspect).join(' < '), kind] if @opened.last != kind
+ @opened.pop
+ end
+
+ protected
+
+ def setup options
+ @opened = []
+ end
+
+ def finish options
+ raise 'Some tokens still open at end of token stream: %p' % [@opened] unless @opened.empty?
+ end
+
+ end
+
+end
+end
diff --git a/lib/coderay/encoders/statistic.rb b/lib/coderay/encoders/statistic.rb
index 2315d9e..b2f8b83 100644
--- a/lib/coderay/encoders/statistic.rb
+++ b/lib/coderay/encoders/statistic.rb
@@ -67,7 +67,6 @@ Token Types (%d):
@type_stats['TOTAL'].count += 1
end
- # TODO Hierarchy handling
def begin_group kind
block_token ':begin_group', kind
end
diff --git a/lib/coderay/encoders/terminal.rb b/lib/coderay/encoders/terminal.rb
index 500e5d8..c7ae014 100644
--- a/lib/coderay/encoders/terminal.rb
+++ b/lib/coderay/encoders/terminal.rb
@@ -19,105 +19,135 @@ module CodeRay
register_for :terminal
TOKEN_COLORS = {
- :annotation => "\e[35m",
- :attribute_name => "\e[33m",
+ :debug => "\e[1;37;44m",
+
+ :annotation => "\e[34m",
+ :attribute_name => "\e[35m",
:attribute_value => "\e[31m",
- :binary => "\e[1;35m",
+ :binary => {
+ :self => "\e[31m",
+ :char => "\e[1;31m",
+ :delimiter => "\e[1;31m",
+ },
:char => {
- :self => "\e[36m", :delimiter => "\e[1;34m"
+ :self => "\e[35m",
+ :delimiter => "\e[1;35m"
},
- :class => "\e[1;35m",
+ :class => "\e[1;35;4m",
:class_variable => "\e[36m",
:color => "\e[32m",
- :comment => "\e[37m",
- :complex => "\e[1;34m",
- :constant => "\e[1;34m\e[4m",
- :decoration => "\e[35m",
- :definition => "\e[1;32m",
- :directive => "\e[32m\e[4m",
- :doc => "\e[46m",
- :doctype => "\e[1;30m",
- :doc_string => "\e[31m\e[4m",
- :entity => "\e[33m",
- :error => "\e[1;33m\e[41m",
+ :comment => {
+ :self => "\e[1;30m",
+ :char => "\e[37m",
+ :delimiter => "\e[37m",
+ },
+ :constant => "\e[1;34;4m",
+ :decorator => "\e[35m",
+ :definition => "\e[1;33m",
+ :directive => "\e[33m",
+ :docstring => "\e[31m",
+ :doctype => "\e[1;34m",
+ :done => "\e[1;30;2m",
+ :entity => "\e[31m",
+ :error => "\e[1;37;41m",
:exception => "\e[1;31m",
:float => "\e[1;35m",
:function => "\e[1;34m",
- :global_variable => "\e[42m",
+ :global_variable => "\e[1;32m",
:hex => "\e[1;36m",
- :include => "\e[33m",
+ :id => "\e[1;34m",
+ :include => "\e[31m",
:integer => "\e[1;34m",
- :key => "\e[35m",
- :label => "\e[1;15m",
+ :imaginary => "\e[1;34m",
+ :important => "\e[1;31m",
+ :key => {
+ :self => "\e[35m",
+ :char => "\e[1;35m",
+ :delimiter => "\e[1;35m",
+ },
+ :keyword => "\e[32m",
+ :label => "\e[1;33m",
:local_variable => "\e[33m",
- :octal => "\e[1;35m",
- :operator_name => "\e[1;29m",
+ :namespace => "\e[1;35m",
+ :octal => "\e[1;34m",
+ :predefined => "\e[36m",
:predefined_constant => "\e[1;36m",
- :predefined_type => "\e[1;30m",
- :predefined => "\e[4m\e[1;34m",
- :preprocessor => "\e[36m",
+ :predefined_type => "\e[1;32m",
+ :preprocessor => "\e[1;36m",
:pseudo_class => "\e[1;34m",
:regexp => {
- :self => "\e[31m",
- :content => "\e[31m",
- :delimiter => "\e[1;29m",
+ :self => "\e[35m",
+ :delimiter => "\e[1;35m",
:modifier => "\e[35m",
+ :char => "\e[1;35m",
},
- :reserved => "\e[1;31m",
+ :reserved => "\e[32m",
:shell => {
- :self => "\e[42m",
- :content => "\e[1;29m",
- :delimiter => "\e[37m",
+ :self => "\e[33m",
+ :char => "\e[1;33m",
+ :delimiter => "\e[1;33m",
+ :escape => "\e[1;33m",
},
:string => {
- :self => "\e[32m",
- :modifier => "\e[1;32m",
- :escape => "\e[1;36m",
- :delimiter => "\e[1;32m",
- :char => "\e[1;36m",
+ :self => "\e[31m",
+ :modifier => "\e[1;31m",
+ :char => "\e[1;35m",
+ :delimiter => "\e[1;31m",
+ :escape => "\e[1;31m",
+ },
+ :symbol => {
+ :self => "\e[33m",
+ :delimiter => "\e[1;33m",
},
- :symbol => "\e[1;32m",
- :tag => "\e[1;34m",
+ :tag => "\e[32m",
:type => "\e[1;34m",
:value => "\e[36m",
- :variable => "\e[1;34m",
+ :variable => "\e[34m",
- :insert => "\e[42m",
- :delete => "\e[41m",
- :change => "\e[44m",
- :head => "\e[45m"
+ :insert => {
+ :self => "\e[42m",
+ :insert => "\e[1;32;42m",
+ :eyecatcher => "\e[102m",
+ },
+ :delete => {
+ :self => "\e[41m",
+ :delete => "\e[1;31;41m",
+ :eyecatcher => "\e[101m",
+ },
+ :change => {
+ :self => "\e[44m",
+ :change => "\e[37;44m",
+ },
+ :head => {
+ :self => "\e[45m",
+ :filename => "\e[37;45m"
+ },
}
+
TOKEN_COLORS[:keyword] = TOKEN_COLORS[:reserved]
TOKEN_COLORS[:method] = TOKEN_COLORS[:function]
- TOKEN_COLORS[:imaginary] = TOKEN_COLORS[:complex]
- TOKEN_COLORS[:begin_group] = TOKEN_COLORS[:end_group] =
- TOKEN_COLORS[:escape] = TOKEN_COLORS[:delimiter]
+ TOKEN_COLORS[:escape] = TOKEN_COLORS[:delimiter]
protected
def setup(options)
super
@opened = []
- @subcolors = nil
+ @color_scopes = [TOKEN_COLORS]
end
public
def text_token text, kind
- if color = (@subcolors || TOKEN_COLORS)[kind]
- if Hash === color
- if color[:self]
- color = color[:self]
- else
- @out << text
- return
- end
- end
+ if color = @color_scopes.last[kind]
+ color = color[:self] if color.is_a? Hash
@out << color
- @out << text.gsub("\n", "\e[0m\n" + color)
+ @out << (text.index("\n") ? text.gsub("\n", "\e[0m\n" + color) : text)
@out << "\e[0m"
- @out << @subcolors[:self] if @subcolors
+ if outer_color = @color_scopes.last[:self]
+ @out << outer_color
+ end
else
@out << text
end
@@ -130,40 +160,33 @@ module CodeRay
alias begin_line begin_group
def end_group kind
- if @opened.empty?
- # nothing to close
- else
- @opened.pop
+ if @opened.pop
+ @color_scopes.pop
@out << "\e[0m"
- @out << open_token(@opened.last)
+ if outer_color = @color_scopes.last[:self]
+ @out << outer_color
+ end
end
end
def end_line kind
- if @opened.empty?
- # nothing to close
- else
- @opened.pop
- # whole lines to be highlighted,
- # eg. added/modified/deleted lines in a diff
- @out << (@line_filler ||= "\t" * 100 + "\e[0m")
- @out << open_token(@opened.last)
- end
+ @out << (@line_filler ||= "\t" * 100)
+ end_group kind
end
private
def open_token kind
- if color = TOKEN_COLORS[kind]
- if Hash === color
- @subcolors = color
+ if color = @color_scopes.last[kind]
+ if color.is_a? Hash
+ @color_scopes << color
color[:self]
else
- @subcolors = {}
+ @color_scopes << @color_scopes.last
color
end
else
- @subcolors = nil
+ @color_scopes << @color_scopes.last
''
end
end