coderay 0.4.3.48

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/LICENSE +340 -0
  2. data/README +103 -0
  3. data/demo/demo_count.rb +10 -0
  4. data/demo/demo_css.rb +4 -0
  5. data/demo/demo_div.rb +19 -0
  6. data/demo/demo_dump.rb +15 -0
  7. data/demo/demo_encoder.rb +39 -0
  8. data/demo/demo_global_vars.rb +13 -0
  9. data/demo/demo_global_vars2.rb +28 -0
  10. data/demo/demo_html.rb +394 -0
  11. data/demo/demo_html2.rb +11 -0
  12. data/demo/demo_load_encoder.rb +17 -0
  13. data/demo/demo_more.rb +204 -0
  14. data/demo/demo_scanner.rb +36 -0
  15. data/demo/demo_server.rb +92 -0
  16. data/demo/demo_simple.rb +10 -0
  17. data/demo/demo_stream.rb +25 -0
  18. data/demo/demo_stream2.rb +8 -0
  19. data/demo/demo_tokens.rb +3 -0
  20. data/lib/coderay.rb +284 -0
  21. data/lib/coderay/encoder.rb +151 -0
  22. data/lib/coderay/encoders/count.rb +21 -0
  23. data/lib/coderay/encoders/div.rb +16 -0
  24. data/lib/coderay/encoders/helpers/html_css.rb +155 -0
  25. data/lib/coderay/encoders/helpers/html_helper.rb +68 -0
  26. data/lib/coderay/encoders/helpers/html_output.rb +237 -0
  27. data/lib/coderay/encoders/html.rb +169 -0
  28. data/lib/coderay/encoders/null.rb +20 -0
  29. data/lib/coderay/encoders/span.rb +16 -0
  30. data/lib/coderay/encoders/statistic.rb +74 -0
  31. data/lib/coderay/encoders/text.rb +33 -0
  32. data/lib/coderay/encoders/tokens.rb +44 -0
  33. data/lib/coderay/encoders/yaml.rb +19 -0
  34. data/lib/coderay/helpers/filetype.rb +145 -0
  35. data/lib/coderay/helpers/gzip_simple.rb +123 -0
  36. data/lib/coderay/helpers/plugin.rb +286 -0
  37. data/lib/coderay/helpers/scanner_helper.rb +63 -0
  38. data/lib/coderay/scanner.rb +197 -0
  39. data/lib/coderay/scanners/c.rb +147 -0
  40. data/lib/coderay/scanners/delphi.rb +123 -0
  41. data/lib/coderay/scanners/helpers/ruby_helper.rb +212 -0
  42. data/lib/coderay/scanners/plaintext.rb +13 -0
  43. data/lib/coderay/scanners/ruby.rb +337 -0
  44. data/lib/coderay/tokens.rb +324 -0
  45. metadata +89 -0
@@ -0,0 +1,11 @@
1
+ require 'coderay'
2
+
3
+ # scan this file
4
+ tokens = CodeRay.scan(File.read($0) * 1, :ruby)
5
+
6
+ # output it with two styles of line numbers
7
+ out = tokens.div(:line_numbers => :table)
8
+ out << '<hr />'
9
+ out << tokens.div(:line_numbers => :inline, :line_number_start => 8)
10
+
11
+ puts out.page
@@ -0,0 +1,17 @@
1
+ require 'coderay'
2
+
3
+ begin
4
+ CodeRay::Encoders::YAML
5
+ rescue
6
+ puts 'CodeRay::Encoders::YAML is not defined; you must load it first.'
7
+ end
8
+
9
+ yaml_encoder = CodeRay::Encoders[:yaml]
10
+ print 'Now it is loaded: '
11
+ p yaml_encoder
12
+ puts 'See?'
13
+
14
+ tokens_encoder = require_plugin 'CodeRay::Encoders/tokens'
15
+ print 'Require is also possible: '
16
+ p tokens_encoder
17
+ puts 'See?'
@@ -0,0 +1,204 @@
1
+ require 'coderay'
2
+
3
+ c, ruby = DATA.read.split(/^---$/)
4
+ DATA.rewind
5
+ me = DATA.read[/.*^__END__$/m]
6
+ $input = c + ruby + me
7
+
8
+ require 'benchmark'
9
+ time = Benchmark.realtime do
10
+
11
+ # here CodeRay comes to play
12
+ hl = CodeRay.encoder(:html, :tab_width => 2, :line_numbers => :table, :wrap => :div)
13
+ c = hl.highlight c, :c
14
+ ruby = hl.highlight ruby, :ruby
15
+ me = hl.highlight me, :ruby
16
+
17
+ body = %w[C Ruby Genereated\ by].zip([c, ruby, me]).map do |title, code|
18
+ "<h1>#{title}</h1>\n#{code}"
19
+ end.join
20
+ body = hl.class::Output.new(body, :div).page!
21
+
22
+ # CodeRay also provides a simple page generator
23
+ $output = body #hl.class.wrap_in_page body
24
+ end
25
+
26
+ File.open('test.html', 'w') do |f|
27
+ f.write $output
28
+ end
29
+ puts 'Input: %dB, Output: %dB' % [$input.size, $output.size]
30
+ puts 'Created "test.html" in %0.3f seconds (%d KB/s). Take a look with your browser.' % [time, $input.size / 1024.0 / time]
31
+
32
+ __END__
33
+ /**********************************************************************
34
+
35
+ version.c -
36
+
37
+ $Author: nobu $
38
+ $Date: 2004/03/25 12:01:40 $
39
+ created at: Thu Sep 30 20:08:01 JST 1993
40
+
41
+ Copyright (C) 1993-2003 Yukihiro Matsumoto
42
+
43
+ **********************************************************************/
44
+
45
+ #include "ruby.h"
46
+ #include "version.h"
47
+ #include <stdio.h>
48
+
49
+ const char ruby_version[] = RUBY_VERSION;
50
+ const char ruby_release_date[] = RUBY_RELEASE_DATE;
51
+ const char ruby_platform[] = RUBY_PLATFORM;
52
+
53
+ void
54
+ Init_version()
55
+ {
56
+ VALUE v = rb_obj_freeze(rb_str_new2(ruby_version));
57
+ VALUE d = rb_obj_freeze(rb_str_new2(ruby_release_date));
58
+ VALUE p = rb_obj_freeze(rb_str_new2(ruby_platform));
59
+
60
+ rb_define_global_const("RUBY_VERSION", v);
61
+ rb_define_global_const("RUBY_RELEASE_DATE", d);
62
+ rb_define_global_const("RUBY_PLATFORM", p);
63
+ }
64
+
65
+ void
66
+ ruby_show_version()
67
+ {
68
+ printf("ruby %s (%s) [%s]\n", RUBY_VERSION, RUBY_RELEASE_DATE, RUBY_PLATFORM);
69
+ }
70
+
71
+ void
72
+ ruby_show_copyright()
73
+ {
74
+ printf("ruby - Copyright (C) 1993-%d Yukihiro Matsumoto\n", RUBY_RELEASE_YEAR);
75
+ exit(0);
76
+ }
77
+ ---
78
+ #
79
+ # = ostruct.rb: OpenStruct implementation
80
+ #
81
+ # Author:: Yukihiro Matsumoto
82
+ # Documentation:: Gavin Sinclair
83
+ #
84
+ # OpenStruct allows the creation of data objects with arbitrary attributes.
85
+ # See OpenStruct for an example.
86
+ #
87
+
88
+ #
89
+ # OpenStruct allows you to create data objects and set arbitrary attributes.
90
+ # For example:
91
+ #
92
+ # require 'ostruct'
93
+ #
94
+ # record = OpenStruct.new
95
+ # record.name = "John Smith"
96
+ # record.age = 70
97
+ # record.pension = 300
98
+ #
99
+ # puts record.name # -> "John Smith"
100
+ # puts record.address # -> nil
101
+ #
102
+ # It is like a hash with a different way to access the data. In fact, it is
103
+ # implemented with a hash, and you can initialize it with one.
104
+ #
105
+ # hash = { "country" => "Australia", :population => 20_000_000 }
106
+ # data = OpenStruct.new(hash)
107
+ #
108
+ # p data # -> <OpenStruct country="Australia" population=20000000>
109
+ #
110
+ class OpenStruct
111
+ #
112
+ # Create a new OpenStruct object. The optional +hash+, if given, will
113
+ # generate attributes and values. For example.
114
+ #
115
+ # require 'ostruct'
116
+ # hash = { "country" => "Australia", :population => 20_000_000 }
117
+ # data = OpenStruct.new(hash)
118
+ #
119
+ # p data # -> <OpenStruct country="Australia" population=20000000>
120
+ #
121
+ # By default, the resulting OpenStruct object will have no attributes.
122
+ #
123
+ def initialize(hash=nil)
124
+ @table = {}
125
+ if hash
126
+ for k,v in hash
127
+ @table[k.to_sym] = v
128
+ new_ostruct_member(k)
129
+ end
130
+ end
131
+ end
132
+
133
+ # Duplicate an OpenStruct object members.
134
+ def initialize_copy(orig)
135
+ super
136
+ @table = @table.dup
137
+ end
138
+
139
+ def marshal_dump
140
+ @table
141
+ end
142
+ def marshal_load(x)
143
+ @table = x
144
+ @table.each_key{|key| new_ostruct_member(key)}
145
+ end
146
+
147
+ def new_ostruct_member(name)
148
+ unless self.respond_to?(name)
149
+ self.instance_eval %{
150
+ def #{name}; @table[:#{name}]; end
151
+ def #{name}=(x); @table[:#{name}] = x; end
152
+ }
153
+ end
154
+ end
155
+
156
+ def method_missing(mid, *args) # :nodoc:
157
+ mname = mid.id2name
158
+ len = args.length
159
+ if mname =~ /=$/
160
+ if len != 1
161
+ raise ArgumentError, "wrong number of arguments (#{len} for 1)", caller(1)
162
+ end
163
+ if self.frozen?
164
+ raise TypeError, "can't modify frozen #{self.class}", caller(1)
165
+ end
166
+ mname.chop!
167
+ @table[mname.intern] = args[0]
168
+ self.new_ostruct_member(mname)
169
+ elsif len == 0
170
+ @table[mid]
171
+ else
172
+ raise NoMethodError, "undefined method `#{mname}' for #{self}", caller(1)
173
+ end
174
+ end
175
+
176
+ #
177
+ # Remove the named field from the object.
178
+ #
179
+ def delete_field(name)
180
+ @table.delete name.to_sym
181
+ end
182
+
183
+ #
184
+ # Returns a string containing a detailed summary of the keys and values.
185
+ #
186
+ def inspect
187
+ str = "<#{self.class}"
188
+ for k,v in @table
189
+ str << " #{k}=#{v.inspect}"
190
+ end
191
+ str << ">"
192
+ end
193
+
194
+ attr_reader :table # :nodoc:
195
+ protected :table
196
+
197
+ #
198
+ # Compare this object and +other+ for equality.
199
+ #
200
+ def ==(other)
201
+ return false unless(other.kind_of?(OpenStruct))
202
+ return @table == other.table
203
+ end
204
+ end
@@ -0,0 +1,36 @@
1
+ require 'coderay'
2
+
3
+ c_code = "if (*p == '{') nest++;"
4
+ puts 'C Code: ' + c_code
5
+ puts
6
+
7
+ c_scanner = CodeRay::Scanners[:c].new c_code
8
+
9
+ puts '> print only operators:'
10
+ for text, kind in c_scanner
11
+ print text if kind == :operator
12
+ end
13
+ puts
14
+ puts '-' * 30
15
+ puts
16
+
17
+ ruby_code = %q!ruby_code(:can, BE, %r[q[ui]te #{ /comple/x },] => $-s, &?\xee)!
18
+ puts 'Ruby Code: ' + ruby_code
19
+ puts
20
+
21
+ ruby_scanner = CodeRay::Scanners[:ruby].new ruby_code
22
+
23
+ puts '> has a string?'
24
+ puts ruby_scanner.
25
+ any? { |text, kind| kind == :string }
26
+ puts
27
+
28
+ puts '> number of regexps?'
29
+ puts ruby_scanner.
30
+ select { |token| token == [:open, :regexp] }.size
31
+ puts
32
+
33
+ puts '> has a string?'
34
+ puts ruby_scanner.
35
+ reject { |text, kind| not text.is_a? String }.
36
+ map { |text, kind| %("#{text}" (#{kind})) }.join(', ')
@@ -0,0 +1,92 @@
1
+ # CodeRay dynamic highlighter
2
+ #
3
+ # Usage: start this and your browser.
4
+ #
5
+ # Go to http://localhost:49374/?<path to the file>
6
+ # (mnemonic: 49374 = Four-Nine-Three-Seven-Four = For No Token Shall Fall)
7
+ # and you should get the highlighted version.
8
+
9
+ require 'webrick'
10
+ require 'pathname'
11
+
12
+ class << File
13
+ alias dir? directory?
14
+ end
15
+
16
+ require 'erb'
17
+ include ERB::Util
18
+ def url_decode s
19
+ s.to_s.gsub(/%([0-9a-f]{2})/i) { [$1.hex].pack 'C' }
20
+ end
21
+
22
+ class String
23
+ def to_link name = File.basename(self)
24
+ "<a href=\"?path=#{url_encode self}\">#{name}</a>"
25
+ end
26
+ end
27
+
28
+ require 'coderay'
29
+ class CodeRayServlet < WEBrick::HTTPServlet::AbstractServlet
30
+
31
+ STYLE = 'style="font-family: sans-serif; color: navy;"'
32
+ BANNER = '<p><img src="http://rd.cYcnus.de/coderay/coderay-banner" style="border: 0" alt="HIghlighted by CodeRay"/></p>'
33
+
34
+ def do_GET req, res
35
+ q = req.query_string || ''
36
+ args = Hash[*q.scan(/(.*?)=(.*?)(?:&|$)/).flatten].each_value { |v| v.replace url_decode(v) }
37
+ path = args.fetch 'path', '.'
38
+
39
+ backlinks = '<p>current path: %s<br />' % html_escape(path) +
40
+ (Pathname.new(path) + '..').cleanpath.to_s.to_link('up') + ' - ' +
41
+ '.'.to_link('current') + '</p>'
42
+
43
+ res.body =
44
+ if File.dir? path
45
+ path = Pathname.new(path).cleanpath.to_s
46
+ dirs, files = Dir[File.join(path, '*')].sort.partition { |p| File.dir? p }
47
+
48
+ page = "<html><head></head><body #{STYLE}>"
49
+ page << backlinks
50
+
51
+ page << '<dl>'
52
+ page << "<dt>Directories</dt>\n" + dirs.map do |p|
53
+ "<dd>#{p.to_link}</dd>\n"
54
+ end.join << "\n"
55
+ page << "<dt>Files</dt>\n" + files.map do |p|
56
+ "<dd>#{p.to_link}</dd>\n"
57
+ end.join << "\n"
58
+ page << "</dl>\n"
59
+ page << "#{BANNER}</body></html>"
60
+
61
+ elsif File.exist? path
62
+ div = CodeRay.scan_file(path).html :tab_width => 8, :wrap => :div
63
+ div.replace <<-DIV
64
+ <div #{STYLE}>
65
+ #{backlinks}
66
+ #{div}
67
+ </div>
68
+ #{BANNER}
69
+ DIV
70
+ div.page
71
+ end
72
+
73
+ res['Content-Type'] = 'text/html'
74
+ end
75
+ end
76
+
77
+ # this is taken by "qip_msgd" - I don't know that.
78
+ module CodeRay
79
+ PORT = 0xC0DE / 20
80
+ end
81
+
82
+ server = WEBrick::HTTPServer.new :Port => CodeRay::PORT
83
+
84
+ server.mount '/', CodeRayServlet
85
+
86
+ server.mount_proc '/version' do |req, res|
87
+ res.body = 'CodeRay::Version = ' + CodeRay::Version
88
+ res['Content-Type'] = "text/plain"
89
+ end
90
+
91
+ trap("INT") { server.shutdown }
92
+ server.start
@@ -0,0 +1,10 @@
1
+
2
+ # Load CodeRay
3
+ # If this doesn't work, try ruby -rubygems.
4
+ require 'coderay'
5
+
6
+ # Generate HTML page for Ruby code.
7
+ page = CodeRay.scan("puts 'Hello, world!'", :ruby).span
8
+
9
+ # Print it
10
+ puts page
@@ -0,0 +1,25 @@
1
+ require 'coderay'
2
+
3
+ code = File.read($0) * 500
4
+ puts "Size of code: %d KB" % [code.size / 1024]
5
+
6
+ puts "Use your system's memory tracker to see how much RAM this takes."
7
+ print 'Press some key to continue...'; gets
8
+
9
+ require 'benchmark'
10
+ e = CodeRay.encoder(:div)
11
+ for do_stream in [true, false]
12
+ puts "Scanning and encoding in %s mode, please wait..." %
13
+ [do_stream ? 'streaming' : 'normal']
14
+ output = ''
15
+ time = Benchmark.realtime do
16
+ if do_stream
17
+ output = e.encode_stream(code, :ruby)
18
+ else
19
+ output = e.encode_tokens(t = CodeRay.scan(code, :ruby))
20
+ end
21
+ end
22
+ puts 'Finished after %4.2f seconds.' % time
23
+ puts "Size of output: %d KB" % [output.size / 1024]
24
+ print 'Press some key to continue...'; gets
25
+ end
@@ -0,0 +1,8 @@
1
+ require 'coderay'
2
+
3
+ token_stream = CodeRay::TokenStream.new do |kind, text|
4
+ puts 'kind: %s, text size: %d.' % [kind, text.size]
5
+ end
6
+
7
+ token_stream << [:regexp, '/\d+/'] << [:space, "\n"]
8
+ #-> kind: rexpexp, text size: 5.
@@ -0,0 +1,3 @@
1
+ require 'coderay'
2
+
3
+ puts CodeRay.scan("puts 3 + 4, '3 + 4'", :ruby).tokens
@@ -0,0 +1,284 @@
1
+ # = CodeRay Library
2
+ #
3
+ # $Id: coderay.rb 44 2005-10-01 00:59:05Z murphy $
4
+ #
5
+ # CodeRay is a Ruby library for syntax highlighting.
6
+ #
7
+ # I try to make CodeRay easy to use and intuitive, but at the same time fully featured, complete,
8
+ # fast and efficient.
9
+ #
10
+ # See README.
11
+ #
12
+ # It consists mainly of
13
+ # * the main engine: CodeRay (Scanners::Scanner, Tokens/TokenStream, Encoders::Encoder), PluginHost
14
+ # * the scanners in CodeRay::Scanners
15
+ # * the encoders in CodeRay::Encoders
16
+ #
17
+ # Here's a fancy graphic to light up this gray docu:
18
+ #
19
+ # http://rd.cYcnus.de/coderay/scheme.png
20
+ #
21
+ # == Documentation
22
+ #
23
+ # See CodeRay, Encoders, Scanners, Tokens.
24
+ #
25
+ # == Usage
26
+ #
27
+ # Remember you need RubyGems to use CodeRay. Run Ruby with -rubygems option
28
+ # if required.
29
+ #
30
+ # === Highlight Ruby code in a string as html
31
+ #
32
+ # require 'coderay'
33
+ # print CodeRay.scan('puts "Hello, world!"', :ruby).html
34
+ #
35
+ # # prints something like this:
36
+ # puts <span class="s">&quot;Hello, world!&quot;</span>
37
+ #
38
+ #
39
+ # === Highlight C code from a file in a html div
40
+ #
41
+ # require 'coderay'
42
+ # print CodeRay.scan(File.read('ruby.h'), :c).div
43
+ # print CodeRay.scan_file('ruby.h').html.div
44
+ #
45
+ # You can include this div in your page. The used CSS styles can be printed with
46
+ #
47
+ # % ruby -rcoderay -e "print CodeRay::Encoders[:html]::CSS"
48
+ #
49
+ # === Highlight without typing too much
50
+ #
51
+ # If you are one of the hasty (or lazy, or extremely curious) people, just run this file:
52
+ #
53
+ # % ruby -rubygems coderay.rb
54
+ #
55
+ # If the output was to fast for you, try
56
+ #
57
+ # % ruby -rubygems coderay.rb > example.html
58
+ #
59
+ # and look at the file it created.
60
+ #
61
+ # = CodeRay Module
62
+ #
63
+ # The CodeRay module provides convenience methods for the engine.
64
+ #
65
+ # * The +lang+ and +format+ arguments select Scanner and Encoder to use. These are
66
+ # simply lower-case symbols, like <tt>:python</tt> or <tt>:html</tt>.
67
+ # * All methods take an optional hash as last parameter, +options+, that is send to
68
+ # the Encoder / Scanner.
69
+ # * Input and language are always sorted in this order: +code+, +lang+.
70
+ # (This is in alphabetical order, if you need a mnemonic ;)
71
+ #
72
+ # You should be able to highlight everything you want just using this methods;
73
+ # so there is no need to dive into CodeRay's deep class hierarchy.
74
+ #
75
+ # The exmaples in the demo/ directory demonstrate common cases using this interface.
76
+ #
77
+ # = Basic Access Ways
78
+ #
79
+ # Read this to get a general view what CodeRay provides.
80
+ #
81
+ # == Scanning
82
+ #
83
+ # Scanning means analysing an input string, splitting it up into Tokens.
84
+ # Each Token knows about what type it is: string, comment, class name, etc.
85
+ #
86
+ # Each +lang+ (language) has its own Scanner; for example, <tt>:ruby</tt> code is
87
+ # handled by CodeRay::Scanners::RubyScanner.
88
+ #
89
+ # CodeRay.scan:: Scan a string in a given language into Tokens.
90
+ # This is the most common method to use.
91
+ # CodeRay.scan_file:: Scan a file and guess the language using FileType.
92
+ #
93
+ # The Tokens object you get from these methods can encode itself; see Tokens.
94
+ #
95
+ # == Encoding
96
+ #
97
+ # Encoding means compiling Tokens into an output. This can be colored HTML or
98
+ # LaTeX, a textual statistic or just the number of non-whitespace tokens.
99
+ #
100
+ # Each Encoder provides output in a specific +format+, so you select Encoders via
101
+ # formats like <tt>:html</tt> or <tt>:statistic</tt>.
102
+ #
103
+ # CodeRay.encode:: Scan and encode a string in a given language.
104
+ # CodeRay.encode_tokens:: Encode the given tokens.
105
+ # CodeRay.encode_file:: Scan a file, guess the language using FileType and encode it.
106
+ #
107
+ # == Streaming
108
+ #
109
+ # Streaming saves RAM by running Scanner and Encoder in some sort of
110
+ # pipe mode; see TokenStream.
111
+ #
112
+ # CodeRay.scan_stream:: Scan in stream mode.
113
+ #
114
+ # == All-in-One Encoding
115
+ #
116
+ # CodeRay.encode:: Highlight a string with a given input and output format.
117
+ #
118
+ # == Instanciating
119
+ #
120
+ # You can use an Encoder instance to highlight multiple inputs. This way, the setup
121
+ # for this Encoder must only be done once.
122
+ #
123
+ # CodeRay.encoder:: Create an Encoder instance with format and options.
124
+ #
125
+ # There is no CodeRay.scanner method because Scanners are bound to an input string
126
+ # on creation; you can't re-use them with another string.
127
+ #
128
+ # The scanning methods provide more flexibility; we recommend to use these.
129
+ module CodeRay
130
+
131
+ Version = '0.4.4'
132
+
133
+ require 'coderay/tokens'
134
+ require 'coderay/scanner'
135
+ require 'coderay/encoder'
136
+
137
+
138
+ class << self
139
+
140
+ # Scans the given +code+ (a String) with the Scanner for +lang+.
141
+ #
142
+ # This is a simple way to use CodeRay. Example:
143
+ # require 'coderay'
144
+ # page = CodeRay.scan("puts 'Hello, world!'", :ruby).html
145
+ #
146
+ # See also demo/demo_simple.
147
+ def scan code, lang, options = {}, &block
148
+ scanner = Scanners[lang].new code, options, &block
149
+ scanner.tokenize
150
+ end
151
+
152
+ # Scans +filename+ (a path to a code file) with the Scanner for +lang+.
153
+ #
154
+ # If +lang+ is :auto or omitted, the CodeRay::FileType module is used to
155
+ # determine it. If it cannot find out what type it is, it uses
156
+ # CodeRay::Scanners::Plaintext.
157
+ #
158
+ # Calls CodeRay.scan.
159
+ #
160
+ # Example:
161
+ # require 'coderay'
162
+ # page = CodeRay.scan_file('some_c_code.c').html
163
+ def scan_file filename, lang = :auto, options = {}, &block
164
+ file = IO.read filename
165
+ if lang == :auto
166
+ require 'coderay/helpers/filetype'
167
+ lang = FileType.fetch filename, :plaintext, true
168
+ end
169
+ scan file, lang, options = {}, &block
170
+ end
171
+
172
+ # Scan the +code+ (a string) with the scanner for +lang+.
173
+ #
174
+ # Calls scan.
175
+ #
176
+ # See CodeRay.scan.
177
+ def scan_stream code, lang, options = {}, &block
178
+ options[:stream] = true
179
+ scan code, lang, options, &block
180
+ end
181
+
182
+ # Encode a string in Streaming mode.
183
+ #
184
+ # This starts scanning +code+ with the the Scanner for +lang+
185
+ # while encodes the output with the Encoder for +format+.
186
+ # +options+ will be passed to the Encoder.
187
+ #
188
+ # See CodeRay::Encoder.encode_stream
189
+ def encode_stream code, lang, format, options = {}
190
+ encoder(format, options).encode_stream code, lang, options
191
+ end
192
+
193
+ # Encode a string.
194
+ #
195
+ # This scans +code+ with the the Scanner for +lang+ and then
196
+ # encodes it with the Encoder for +format+.
197
+ # +options+ will be passed to the Encoder.
198
+ #
199
+ # See CodeRay::Encoder.encode
200
+ def encode code, lang, format, options = {}
201
+ encoder(format, options).encode code, lang, options
202
+ end
203
+
204
+ # Encode pre-scanned Tokens.
205
+ # Use this together with CodeRay.scan:
206
+ #
207
+ # require 'coderay'
208
+ #
209
+ # # Highlight a short Ruby code example in a HTML span
210
+ # tokens = CodeRay.scan '1 + 2', :ruby
211
+ # puts CodeRay.encode_tokens(tokens, :span)
212
+ #
213
+ def encode_tokens tokens, format, options = {}
214
+ encoder(format, options).encode_tokens tokens, options
215
+ end
216
+
217
+ # Encodes +filename+ (a path to a code file) with the Scanner for +lang+.
218
+ #
219
+ # See CodeRay.scan_file.
220
+ # Notice that the second argument is the output +format+, not the input language.
221
+ #
222
+ # Example:
223
+ # require 'coderay'
224
+ # page = CodeRay.encode_file 'some_c_code.c', :html
225
+ def encode_file filename, format, options = {}
226
+ tokens = scan_file filename, auto, get_scanner_options(options)
227
+ encode_tokens tokens, format, options
228
+ end
229
+
230
+ # Finds the Encoder class for +format+ and creates an instance, passing
231
+ # +options+ to it.
232
+ #
233
+ # Example:
234
+ # require 'coderay'
235
+ #
236
+ # stats = CodeRay.encoder(:statistic)
237
+ # stats.encode("puts 17 + 4\n", :ruby)
238
+ #
239
+ # puts '%d out of %d tokens have the kind :integer.' % [
240
+ # stats.type_stats[:integer].count,
241
+ # stats.real_token_count
242
+ # ]
243
+ # #-> 2 out of 4 tokens have the kind :integer.
244
+ def encoder format, options = {}
245
+ Encoders[format].new options
246
+ end
247
+
248
+ # Extract the options for the scanner from the +options+ hash.
249
+ #
250
+ # Returns an empty Hash if <tt>:scanner_options</tt> is not set.
251
+ #
252
+ # This is used if a method like CodeRay.encode has to provide options
253
+ # for Encoder _and_ scanner.
254
+ def get_scanner_options options
255
+ options.fetch :scanner_options, {}
256
+ end
257
+
258
+ end
259
+
260
+ # This Exception is raised when you try to stream with something that is not
261
+ # capable of streaming.
262
+ class NotStreamableError < Exception
263
+ def initialize obj
264
+ @obj = obj
265
+ end
266
+
267
+ def to_s
268
+ '%s is not Streamable!' % @obj.class
269
+ end
270
+ end
271
+
272
+ # A dummy module that is included by subclasses of CodeRay::Scanner an CodeRay::Encoder
273
+ # to show that they are able to handle streams.
274
+ module Streamable
275
+ end
276
+
277
+ end
278
+
279
+ # Run a test script.
280
+ if $0 == __FILE__
281
+ $stderr.print 'Press key to print demo.'; gets
282
+ code = File.read($0)[/module CodeRay.*/m]
283
+ print CodeRay.scan(code, :ruby).html
284
+ end