coderay 0.4.3.48

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 (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