coderay 0.8.357 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/lib/README +4 -3
  2. data/lib/coderay.rb +2 -1
  3. data/lib/coderay/encoder.rb +41 -15
  4. data/lib/coderay/encoders/_map.rb +3 -1
  5. data/lib/coderay/encoders/comment_filter.rb +43 -0
  6. data/lib/coderay/encoders/div.rb +2 -3
  7. data/lib/coderay/encoders/filter.rb +75 -0
  8. data/lib/coderay/encoders/html.rb +20 -3
  9. data/lib/coderay/encoders/html/css.rb +1 -1
  10. data/lib/coderay/encoders/html/numerization.rb +11 -2
  11. data/lib/coderay/encoders/html/output.rb +10 -1
  12. data/lib/coderay/encoders/json.rb +69 -0
  13. data/lib/coderay/encoders/lines_of_code.rb +90 -0
  14. data/lib/coderay/encoders/page.rb +1 -2
  15. data/lib/coderay/encoders/span.rb +2 -3
  16. data/lib/coderay/encoders/term.rb +137 -0
  17. data/lib/coderay/encoders/text.rb +4 -4
  18. data/lib/coderay/encoders/token_class_filter.rb +84 -0
  19. data/lib/coderay/encoders/xml.rb +1 -0
  20. data/lib/coderay/for_redcloth.rb +9 -4
  21. data/lib/coderay/helpers/file_type.rb +54 -15
  22. data/lib/coderay/helpers/plugin.rb +21 -3
  23. data/lib/coderay/helpers/word_list.rb +19 -4
  24. data/lib/coderay/scanner.rb +33 -2
  25. data/lib/coderay/scanners/_map.rb +10 -4
  26. data/lib/coderay/scanners/c.rb +61 -23
  27. data/lib/coderay/scanners/cpp.rb +228 -0
  28. data/lib/coderay/scanners/css.rb +9 -1
  29. data/lib/coderay/scanners/debug.rb +1 -0
  30. data/lib/coderay/scanners/delphi.rb +2 -2
  31. data/lib/coderay/scanners/diff.rb +1 -0
  32. data/lib/coderay/scanners/groovy.rb +263 -0
  33. data/lib/coderay/scanners/html.rb +9 -2
  34. data/lib/coderay/scanners/java.rb +18 -14
  35. data/lib/coderay/scanners/java_script.rb +42 -13
  36. data/lib/coderay/scanners/json.rb +7 -1
  37. data/lib/coderay/scanners/nitro_xhtml.rb +4 -0
  38. data/lib/coderay/scanners/php.rb +526 -0
  39. data/lib/coderay/scanners/plaintext.rb +4 -1
  40. data/lib/coderay/scanners/python.rb +285 -0
  41. data/lib/coderay/scanners/rhtml.rb +3 -0
  42. data/lib/coderay/scanners/ruby.rb +29 -11
  43. data/lib/coderay/scanners/ruby/patterns.rb +26 -20
  44. data/lib/coderay/scanners/scheme.rb +3 -0
  45. data/lib/coderay/scanners/sql.rb +162 -0
  46. data/lib/coderay/scanners/xml.rb +1 -1
  47. data/lib/coderay/scanners/yaml.rb +4 -1
  48. data/lib/coderay/styles/cycnus.rb +11 -7
  49. data/lib/coderay/token_classes.rb +4 -1
  50. data/lib/coderay/tokens.rb +50 -46
  51. metadata +14 -4
  52. data/lib/coderay/encoders/tokens.rb +0 -44
@@ -0,0 +1,90 @@
1
+ ($:.unshift '../..'; require 'coderay') unless defined? CodeRay
2
+ module CodeRay
3
+ module Encoders
4
+
5
+ # Counts the LoC (Lines of Code). Returns an Integer >= 0.
6
+ #
7
+ # Alias: :loc
8
+ #
9
+ # Everything that is not comment, markup, doctype/shebang, or an empty line,
10
+ # is considered to be code.
11
+ #
12
+ # For example,
13
+ # * HTML files not containing JavaScript have 0 LoC
14
+ # * in a Java class without comments, LoC is the number of non-empty lines
15
+ #
16
+ # A Scanner class should define the token kinds that are not code in the
17
+ # KINDS_NOT_LOC constant, which defaults to [:comment, :doctype].
18
+ class LinesOfCode < Encoder
19
+
20
+ register_for :lines_of_code
21
+
22
+ NON_EMPTY_LINE = /^\s*\S.*$/
23
+
24
+ def compile tokens, options
25
+ if scanner = tokens.scanner
26
+ kinds_not_loc = scanner.class::KINDS_NOT_LOC
27
+ else
28
+ warn ArgumentError, 'Tokens have no scanner.' if $DEBUG
29
+ kinds_not_loc = CodeRay::Scanners::Scanner::KINDS_NOT_LOC
30
+ end
31
+ code = tokens.token_class_filter :exclude => kinds_not_loc
32
+ @loc = code.text.scan(NON_EMPTY_LINE).size
33
+ end
34
+
35
+ def finish options
36
+ @loc
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+ end
43
+
44
+ if $0 == __FILE__
45
+ $VERBOSE = true
46
+ $: << File.join(File.dirname(__FILE__), '..')
47
+ eval DATA.read, nil, $0, __LINE__ + 4
48
+ end
49
+
50
+ __END__
51
+ require 'test/unit'
52
+
53
+ class LinesOfCodeTest < Test::Unit::TestCase
54
+
55
+ def test_creation
56
+ assert CodeRay::Encoders::LinesOfCode < CodeRay::Encoders::Encoder
57
+ filter = nil
58
+ assert_nothing_raised do
59
+ filter = CodeRay.encoder :loc
60
+ end
61
+ assert_kind_of CodeRay::Encoders::LinesOfCode, filter
62
+ assert_nothing_raised do
63
+ filter = CodeRay.encoder :lines_of_code
64
+ end
65
+ assert_kind_of CodeRay::Encoders::LinesOfCode, filter
66
+ end
67
+
68
+ def test_lines_of_code
69
+ tokens = CodeRay.scan <<-RUBY, :ruby
70
+ #!/usr/bin/env ruby
71
+
72
+ # a minimal Ruby program
73
+ puts "Hello world!"
74
+ RUBY
75
+ assert_equal 1, CodeRay::Encoders::LinesOfCode.new.encode_tokens(tokens)
76
+ assert_equal 1, tokens.lines_of_code
77
+ assert_equal 1, tokens.loc
78
+ end
79
+
80
+ def test_filtering_block_tokens
81
+ tokens = CodeRay::Tokens.new
82
+ tokens << ["Hello\n", :world]
83
+ tokens << ["Hello\n", :space]
84
+ tokens << ["Hello\n", :comment]
85
+ assert_equal 2, CodeRay::Encoders::LinesOfCode.new.encode_tokens(tokens)
86
+ assert_equal 2, tokens.lines_of_code
87
+ assert_equal 2, tokens.loc
88
+ end
89
+
90
+ end
@@ -9,11 +9,10 @@ module Encoders
9
9
 
10
10
  register_for :page
11
11
 
12
- DEFAULT_OPTIONS = HTML::DEFAULT_OPTIONS.merge({
12
+ DEFAULT_OPTIONS = HTML::DEFAULT_OPTIONS.merge \
13
13
  :css => :class,
14
14
  :wrap => :page,
15
15
  :line_numbers => :table
16
- })
17
16
 
18
17
  end
19
18
 
@@ -9,10 +9,9 @@ module Encoders
9
9
 
10
10
  register_for :span
11
11
 
12
- DEFAULT_OPTIONS = HTML::DEFAULT_OPTIONS.merge({
12
+ DEFAULT_OPTIONS = HTML::DEFAULT_OPTIONS.merge \
13
13
  :css => :style,
14
- :wrap => :span,
15
- })
14
+ :wrap => :span
16
15
 
17
16
  end
18
17
 
@@ -0,0 +1,137 @@
1
+ # encoders/term.rb
2
+ # By Rob Aldred (http://robaldred.co.uk)
3
+ # Based on idea by Nathan Weizenbaum (http://nex-3.com)
4
+ # MIT License (http://www.opensource.org/licenses/mit-license.php)
5
+ #
6
+ # A CodeRay encoder that outputs code highlighted for a color terminal.
7
+ # Check out http://robaldred.co.uk
8
+
9
+ module CodeRay
10
+ module Encoders
11
+ class Term < Encoder
12
+ register_for :term
13
+
14
+ TOKEN_COLORS = {
15
+ :attribute_name => '33',
16
+ :attribute_name_fat => '33',
17
+ :attribute_value => '31',
18
+ :attribute_value_fat => '31',
19
+ :bin => '1;35',
20
+ :char => {:self => '36', :delimiter => '34'},
21
+ :class => '1;35',
22
+ :class_variable => '36',
23
+ :color => '32',
24
+ :comment => '37',
25
+ :constant => ['34', '4'],
26
+ :definition => '1;32',
27
+ :directive => ['32', '4'],
28
+ :doc => '46',
29
+ :doc_string => ['31', '4'],
30
+ :entity => '33',
31
+ :error => ['1;33', '41'],
32
+ :exception => '1;31',
33
+ :float => '1;35',
34
+ :function => '1;34',
35
+ :global_variable => '42',
36
+ :hex => '1;36',
37
+ :include => '33',
38
+ :integer => '1;34',
39
+ :interpreted => '1;35',
40
+ :label => '1;4',
41
+ :local_variable => '33',
42
+ :oct => '1;35',
43
+ :operator_name => '1;29',
44
+ :pre_constant => '1;36',
45
+ :pre_type => '1;30',
46
+ :predefined => ['4', '1;34'],
47
+ :preprocessor => '36',
48
+ :regexp => {
49
+ :content => '31',
50
+ :delimiter => '1;29',
51
+ :modifier => '35',
52
+ :function => '1;29'
53
+ },
54
+ :reserved => '1;31',
55
+ :shell => {:self => '42', :content => '1;29'},
56
+ :string => '32',
57
+ :symbol => '1;32',
58
+ :tag => '34',
59
+ :tag_fat => '1;34',
60
+ :tag_special => ['34', '4'],
61
+ :type => '1;34',
62
+ :variable => '34'
63
+ }
64
+ TOKEN_COLORS[:procedure] = TOKEN_COLORS[:method] = TOKEN_COLORS[:function]
65
+ TOKEN_COLORS[:open] = TOKEN_COLORS[:close] = TOKEN_COLORS[:nesting_delimiter] = TOKEN_COLORS[:escape] = TOKEN_COLORS[:delimiter]
66
+
67
+ protected
68
+
69
+ def setup(options)
70
+ @out = ''
71
+ @opened = [nil]
72
+ @subcolors = nil
73
+ end
74
+
75
+ def finish(options)
76
+ super
77
+ end
78
+
79
+ def token text, type = :plain
80
+ case text
81
+
82
+ when nil
83
+ # raise 'Token with nil as text was given: %p' % [[text, type]]
84
+
85
+ when String
86
+
87
+ if color = (@subcolors || TOKEN_COLORS)[type]
88
+ color = color[:self] || return if Hash === color
89
+
90
+ @out << col(color) + text.gsub("\n", col(0) + "\n" + col(color)) + col(0)
91
+ @out << col(@subcolors[:self]) if @subcolors && @subcolors[:self]
92
+ else
93
+ @out << text
94
+ end
95
+
96
+ # token groups, eg. strings
97
+ when :open
98
+ @opened[0] = type
99
+ if color = TOKEN_COLORS[type]
100
+ if Hash === color
101
+ @subcolors = color
102
+ @out << col(color[:self]) if color[:self]
103
+ else
104
+ @subcolors = {}
105
+ @out << col(color)
106
+ end
107
+ end
108
+ @opened << type
109
+ when :close
110
+ if @opened.empty?
111
+ # nothing to close
112
+ else
113
+ if (@subcolors || {})[:self]
114
+ @out << col(0)
115
+ end
116
+ @subcolors = nil
117
+ @opened.pop
118
+ end
119
+
120
+ # whole lines to be highlighted, eg. a added/modified/deleted lines in a diff
121
+ when :begin_line
122
+
123
+ when :end_line
124
+
125
+ else
126
+ raise 'unknown token kind: %p' % [text]
127
+ end
128
+ end
129
+
130
+ private
131
+
132
+ def col(color)
133
+ Array(color).map { |c| "\e[#{c}m" }.join
134
+ end
135
+ end
136
+ end
137
+ end
@@ -14,16 +14,16 @@ module Encoders
14
14
 
15
15
  protected
16
16
  def setup options
17
- @out = ''
17
+ super
18
18
  @sep = options[:separator]
19
19
  end
20
20
 
21
- def token text, kind
22
- @out << text + @sep if text.is_a? ::String
21
+ def text_token text, kind
22
+ text + @sep
23
23
  end
24
24
 
25
25
  def finish options
26
- @out.chomp @sep
26
+ super.chomp @sep
27
27
  end
28
28
 
29
29
  end
@@ -0,0 +1,84 @@
1
+ ($:.unshift '../..'; require 'coderay') unless defined? CodeRay
2
+ module CodeRay
3
+ module Encoders
4
+
5
+ load :filter
6
+
7
+ class TokenClassFilter < Filter
8
+
9
+ include Streamable
10
+ register_for :token_class_filter
11
+
12
+ DEFAULT_OPTIONS = {
13
+ :exclude => [],
14
+ :include => :all
15
+ }
16
+
17
+ protected
18
+ def setup options
19
+ super
20
+ @exclude = options[:exclude]
21
+ @exclude = Array(@exclude) unless @exclude == :all
22
+ @include = options[:include]
23
+ @include = Array(@include) unless @include == :all
24
+ end
25
+
26
+ def include_text_token? text, kind
27
+ (@include == :all || @include.include?(kind)) &&
28
+ !(@exclude == :all || @exclude.include?(kind))
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+ end
35
+
36
+ if $0 == __FILE__
37
+ $VERBOSE = true
38
+ $: << File.join(File.dirname(__FILE__), '..')
39
+ eval DATA.read, nil, $0, __LINE__ + 4
40
+ end
41
+
42
+ __END__
43
+ require 'test/unit'
44
+
45
+ class TokenClassFilterTest < Test::Unit::TestCase
46
+
47
+ def test_creation
48
+ assert CodeRay::Encoders::TokenClassFilter < CodeRay::Encoders::Encoder
49
+ assert CodeRay::Encoders::TokenClassFilter < CodeRay::Encoders::Filter
50
+ filter = nil
51
+ assert_nothing_raised do
52
+ filter = CodeRay.encoder :token_class_filter
53
+ end
54
+ assert_instance_of CodeRay::Encoders::TokenClassFilter, filter
55
+ end
56
+
57
+ def test_filtering_text_tokens
58
+ tokens = CodeRay::Tokens.new
59
+ for i in 1..10
60
+ tokens << [i.to_s, :index]
61
+ tokens << [' ', :space] if i < 10
62
+ end
63
+ assert_equal 10, CodeRay::Encoders::TokenClassFilter.new.encode_tokens(tokens, :exclude => :space).size
64
+ assert_equal 10, tokens.token_class_filter(:exclude => :space).size
65
+ assert_equal 9, CodeRay::Encoders::TokenClassFilter.new.encode_tokens(tokens, :include => :space).size
66
+ assert_equal 9, tokens.token_class_filter(:include => :space).size
67
+ assert_equal 0, CodeRay::Encoders::TokenClassFilter.new.encode_tokens(tokens, :exclude => :all).size
68
+ assert_equal 0, tokens.token_class_filter(:exclude => :all).size
69
+ end
70
+
71
+ def test_filtering_block_tokens
72
+ tokens = CodeRay::Tokens.new
73
+ 10.times do |i|
74
+ tokens << [:open, :index]
75
+ tokens << [i.to_s, :content]
76
+ tokens << [:close, :index]
77
+ end
78
+ assert_equal 20, CodeRay::Encoders::TokenClassFilter.new.encode_tokens(tokens, :include => :blubb).size
79
+ assert_equal 20, tokens.token_class_filter(:include => :blubb).size
80
+ assert_equal 30, CodeRay::Encoders::TokenClassFilter.new.encode_tokens(tokens, :exclude => :index).size
81
+ assert_equal 30, tokens.token_class_filter(:exclude => :index).size
82
+ end
83
+
84
+ end
@@ -29,6 +29,7 @@ module Encoders
29
29
  end
30
30
 
31
31
  def finish options
32
+ @out = ''
32
33
  @doc.write @out, options[:pretty], options[:transitive], true
33
34
  @out
34
35
  end
@@ -29,21 +29,26 @@ module CodeRay
29
29
  }
30
30
  html.gsub(/&(?:amp|quot|[gl]t);/) { |entity| replacements[entity] }
31
31
  end
32
- undef_method :code, :bc_open, :bc_close, :escape_pre
32
+ undef code, bc_open, bc_close, escape_pre
33
33
  def code(opts) # :nodoc:
34
34
  opts[:block] = true
35
35
  if !opts[:lang] && RedCloth::VERSION.to_s >= '4.2.0'
36
36
  # simulating pre-4.2 behavior
37
- opts[:text].sub!(/\A\[(\w+)\]/, '')
38
- opts[:lang] = $1
37
+ if opts[:text].sub!(/\A\[(\w+)\]/, '')
38
+ if CodeRay::Scanners[$1].plugin_id == 'plaintext'
39
+ opts[:text] = $& + opts[:text]
40
+ else
41
+ opts[:lang] = $1
42
+ end
43
+ end
39
44
  end
40
45
  if opts[:lang] && !filter_coderay
41
46
  require 'coderay'
42
47
  @in_bc ||= nil
43
48
  format = @in_bc ? :div : :span
49
+ opts[:text] = unescape(opts[:text]) unless @in_bc
44
50
  highlighted_code = CodeRay.encode opts[:text], opts[:lang], format, :stream => true
45
51
  highlighted_code.sub!(/\A<(span|div)/) { |m| m + pba(@in_bc || opts) }
46
- highlighted_code = unescape(highlighted_code) unless @in_bc
47
52
  highlighted_code
48
53
  else
49
54
  "<code#{pba(opts)}>#{opts[:text]}</code>"
@@ -35,10 +35,12 @@ module FileType
35
35
  def [] filename, read_shebang = false
36
36
  name = File.basename filename
37
37
  ext = File.extname(name).sub(/^\./, '') # from last dot, delete the leading dot
38
- ext2 = filename[/\.(.*)/, 1] # from first dot
38
+ ext2 = filename.to_s[/\.(.*)/, 1] # from first dot
39
39
 
40
40
  type =
41
+ TypeFromExt[ext] ||
41
42
  TypeFromExt[ext.downcase] ||
43
+ (TypeFromExt[ext2] if ext2) ||
42
44
  (TypeFromExt[ext2.downcase] if ext2) ||
43
45
  TypeFromName[name] ||
44
46
  TypeFromName[name.downcase]
@@ -81,31 +83,46 @@ module FileType
81
83
  end
82
84
 
83
85
  TypeFromExt = {
84
- 'rb' => :ruby,
85
- 'rbw' => :ruby,
86
- 'rake' => :ruby,
87
- 'mab' => :ruby,
88
- 'cpp' => :c,
89
86
  'c' => :c,
87
+ 'css' => :css,
88
+ 'diff' => :diff,
89
+ 'dpr' => :delphi,
90
+ 'groovy' => :groovy,
91
+ 'gvy' => :groovy,
90
92
  'h' => :c,
93
+ 'htm' => :html,
94
+ 'html' => :html,
95
+ 'html.erb' => :rhtml,
91
96
  'java' => :java,
92
97
  'js' => :java_script,
93
98
  'json' => :json,
94
- 'diff' => :diff,
99
+ 'mab' => :ruby,
100
+ 'pas' => :delphi,
95
101
  'patch' => :diff,
96
- 'css' => :css,
97
- 'xml' => :xml,
98
- 'htm' => :html,
99
- 'html' => :html,
100
- 'xhtml' => :xhtml,
102
+ 'php' => :php,
103
+ 'php3' => :php,
104
+ 'php4' => :php,
105
+ 'php5' => :php,
106
+ 'py' => :python,
107
+ 'py3' => :python,
108
+ 'pyw' => :python,
109
+ 'rake' => :ruby,
101
110
  'raydebug' => :debug,
111
+ 'rb' => :ruby,
112
+ 'rbw' => :ruby,
102
113
  'rhtml' => :rhtml,
103
- 'html.erb' => :rhtml,
104
- 'ss' => :scheme,
114
+ 'rxml' => :ruby,
105
115
  'sch' => :scheme,
116
+ 'sql' => :sql,
117
+ 'ss' => :scheme,
118
+ 'xhtml' => :xhtml,
119
+ 'xml' => :xml,
106
120
  'yaml' => :yaml,
107
121
  'yml' => :yaml,
108
122
  }
123
+ for cpp_alias in %w[cc cpp cp cxx c++ C hh hpp h++ cu]
124
+ TypeFromExt[cpp_alias] = :cpp
125
+ end
109
126
 
110
127
  TypeFromShebang = /\b(?:ruby|perl|python|sh)\b/
111
128
 
@@ -126,7 +143,7 @@ end
126
143
  __END__
127
144
  require 'test/unit'
128
145
 
129
- class TC_FileType < Test::Unit::TestCase
146
+ class FileTypeTests < Test::Unit::TestCase
130
147
 
131
148
  include CodeRay
132
149
 
@@ -156,6 +173,8 @@ class TC_FileType < Test::Unit::TestCase
156
173
 
157
174
  def test_ruby
158
175
  assert_equal :ruby, FileType['test.rb']
176
+ assert_equal :ruby, FileType['test.java.rb']
177
+ assert_equal :java, FileType['test.rb.java']
159
178
  assert_equal :ruby, FileType['C:\\Program Files\\x\\y\\c\\test.rbw']
160
179
  assert_equal :ruby, FileType['/usr/bin/something/Rakefile']
161
180
  assert_equal :ruby, FileType['~/myapp/gem/Rantfile']
@@ -175,6 +194,17 @@ class TC_FileType < Test::Unit::TestCase
175
194
  assert_not_equal :c, FileType['~/projects/blabla/c']
176
195
  end
177
196
 
197
+ def test_cpp
198
+ assert_equal :cpp, FileType['test.c++']
199
+ assert_equal :cpp, FileType['test.cxx']
200
+ assert_equal :cpp, FileType['test.hh']
201
+ assert_equal :cpp, FileType['test.hpp']
202
+ assert_equal :cpp, FileType['test.cu']
203
+ assert_equal :cpp, FileType['test.C']
204
+ assert_not_equal :cpp, FileType['test.c']
205
+ assert_not_equal :cpp, FileType['test.h']
206
+ end
207
+
178
208
  def test_html
179
209
  assert_equal :html, FileType['test.htm']
180
210
  assert_equal :xhtml, FileType['test.xhtml']
@@ -190,6 +220,15 @@ class TC_FileType < Test::Unit::TestCase
190
220
  assert_not_equal :yaml, FileType['YAML']
191
221
  end
192
222
 
223
+ def test_pathname
224
+ require 'pathname'
225
+ pn = Pathname.new 'test.rb'
226
+ assert_equal :ruby, FileType[pn]
227
+ dir = Pathname.new '/etc/var/blubb'
228
+ assert_equal :ruby, FileType[dir + pn]
229
+ assert_equal :cpp, FileType[dir + 'test.cpp']
230
+ end
231
+
193
232
  def test_no_shebang
194
233
  dir = './test'
195
234
  if File.directory? dir