coderay 0.8.357 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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