Mercurial > hg > soundsoftware-site
comparison vendor/plugins/coderay-0.9.2/lib/.svn/text-base/coderay.rb.svn-base @ 0:513646585e45
* Import Redmine trunk SVN rev 3859
| author | Chris Cannam |
|---|---|
| date | Fri, 23 Jul 2010 15:52:44 +0100 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:513646585e45 |
|---|---|
| 1 # = CodeRay Library | |
| 2 # | |
| 3 # CodeRay is a Ruby library for syntax highlighting. | |
| 4 # | |
| 5 # I try to make CodeRay easy to use and intuitive, but at the same time fully featured, complete, | |
| 6 # fast and efficient. | |
| 7 # | |
| 8 # See README. | |
| 9 # | |
| 10 # It consists mainly of | |
| 11 # * the main engine: CodeRay (Scanners::Scanner, Tokens/TokenStream, Encoders::Encoder), PluginHost | |
| 12 # * the scanners in CodeRay::Scanners | |
| 13 # * the encoders in CodeRay::Encoders | |
| 14 # | |
| 15 # Here's a fancy graphic to light up this gray docu: | |
| 16 # | |
| 17 # http://cycnus.de/raindark/coderay/scheme.png | |
| 18 # | |
| 19 # == Documentation | |
| 20 # | |
| 21 # See CodeRay, Encoders, Scanners, Tokens. | |
| 22 # | |
| 23 # == Usage | |
| 24 # | |
| 25 # Remember you need RubyGems to use CodeRay, unless you have it in your load path. Run Ruby with | |
| 26 # -rubygems option if required. | |
| 27 # | |
| 28 # === Highlight Ruby code in a string as html | |
| 29 # | |
| 30 # require 'coderay' | |
| 31 # print CodeRay.scan('puts "Hello, world!"', :ruby).html | |
| 32 # | |
| 33 # # prints something like this: | |
| 34 # puts <span class="s">"Hello, world!"</span> | |
| 35 # | |
| 36 # | |
| 37 # === Highlight C code from a file in a html div | |
| 38 # | |
| 39 # require 'coderay' | |
| 40 # print CodeRay.scan(File.read('ruby.h'), :c).div | |
| 41 # print CodeRay.scan_file('ruby.h').html.div | |
| 42 # | |
| 43 # You can include this div in your page. The used CSS styles can be printed with | |
| 44 # | |
| 45 # % coderay_stylesheet | |
| 46 # | |
| 47 # === Highlight without typing too much | |
| 48 # | |
| 49 # If you are one of the hasty (or lazy, or extremely curious) people, just run this file: | |
| 50 # | |
| 51 # % ruby -rubygems /path/to/coderay/coderay.rb > example.html | |
| 52 # | |
| 53 # and look at the file it created in your browser. | |
| 54 # | |
| 55 # = CodeRay Module | |
| 56 # | |
| 57 # The CodeRay module provides convenience methods for the engine. | |
| 58 # | |
| 59 # * The +lang+ and +format+ arguments select Scanner and Encoder to use. These are | |
| 60 # simply lower-case symbols, like <tt>:python</tt> or <tt>:html</tt>. | |
| 61 # * All methods take an optional hash as last parameter, +options+, that is send to | |
| 62 # the Encoder / Scanner. | |
| 63 # * Input and language are always sorted in this order: +code+, +lang+. | |
| 64 # (This is in alphabetical order, if you need a mnemonic ;) | |
| 65 # | |
| 66 # You should be able to highlight everything you want just using these methods; | |
| 67 # so there is no need to dive into CodeRay's deep class hierarchy. | |
| 68 # | |
| 69 # The examples in the demo directory demonstrate common cases using this interface. | |
| 70 # | |
| 71 # = Basic Access Ways | |
| 72 # | |
| 73 # Read this to get a general view what CodeRay provides. | |
| 74 # | |
| 75 # == Scanning | |
| 76 # | |
| 77 # Scanning means analysing an input string, splitting it up into Tokens. | |
| 78 # Each Token knows about what type it is: string, comment, class name, etc. | |
| 79 # | |
| 80 # Each +lang+ (language) has its own Scanner; for example, <tt>:ruby</tt> code is | |
| 81 # handled by CodeRay::Scanners::Ruby. | |
| 82 # | |
| 83 # CodeRay.scan:: Scan a string in a given language into Tokens. | |
| 84 # This is the most common method to use. | |
| 85 # CodeRay.scan_file:: Scan a file and guess the language using FileType. | |
| 86 # | |
| 87 # The Tokens object you get from these methods can encode itself; see Tokens. | |
| 88 # | |
| 89 # == Encoding | |
| 90 # | |
| 91 # Encoding means compiling Tokens into an output. This can be colored HTML or | |
| 92 # LaTeX, a textual statistic or just the number of non-whitespace tokens. | |
| 93 # | |
| 94 # Each Encoder provides output in a specific +format+, so you select Encoders via | |
| 95 # formats like <tt>:html</tt> or <tt>:statistic</tt>. | |
| 96 # | |
| 97 # CodeRay.encode:: Scan and encode a string in a given language. | |
| 98 # CodeRay.encode_tokens:: Encode the given tokens. | |
| 99 # CodeRay.encode_file:: Scan a file, guess the language using FileType and encode it. | |
| 100 # | |
| 101 # == Streaming | |
| 102 # | |
| 103 # Streaming saves RAM by running Scanner and Encoder in some sort of | |
| 104 # pipe mode; see TokenStream. | |
| 105 # | |
| 106 # CodeRay.scan_stream:: Scan in stream mode. | |
| 107 # | |
| 108 # == All-in-One Encoding | |
| 109 # | |
| 110 # CodeRay.encode:: Highlight a string with a given input and output format. | |
| 111 # | |
| 112 # == Instanciating | |
| 113 # | |
| 114 # You can use an Encoder instance to highlight multiple inputs. This way, the setup | |
| 115 # for this Encoder must only be done once. | |
| 116 # | |
| 117 # CodeRay.encoder:: Create an Encoder instance with format and options. | |
| 118 # CodeRay.scanner:: Create an Scanner instance for lang, with '' as default code. | |
| 119 # | |
| 120 # To make use of CodeRay.scanner, use CodeRay::Scanner::code=. | |
| 121 # | |
| 122 # The scanning methods provide more flexibility; we recommend to use these. | |
| 123 # | |
| 124 # == Reusing Scanners and Encoders | |
| 125 # | |
| 126 # If you want to re-use scanners and encoders (because that is faster), see | |
| 127 # CodeRay::Duo for the most convenient (and recommended) interface. | |
| 128 module CodeRay | |
| 129 | |
| 130 $CODERAY_DEBUG ||= false | |
| 131 | |
| 132 # Version: Major.Minor.Teeny[.Revision] | |
| 133 # Major: 0 for pre-stable, 1 for stable | |
| 134 # Minor: feature milestone | |
| 135 # Teeny: development state, 0 for pre-release | |
| 136 # Revision: Subversion Revision number (generated on rake gem:make) | |
| 137 VERSION = '0.9.2' | |
| 138 | |
| 139 require 'coderay/tokens' | |
| 140 require 'coderay/token_classes' | |
| 141 require 'coderay/scanner' | |
| 142 require 'coderay/encoder' | |
| 143 require 'coderay/duo' | |
| 144 require 'coderay/style' | |
| 145 | |
| 146 | |
| 147 class << self | |
| 148 | |
| 149 # Scans the given +code+ (a String) with the Scanner for +lang+. | |
| 150 # | |
| 151 # This is a simple way to use CodeRay. Example: | |
| 152 # require 'coderay' | |
| 153 # page = CodeRay.scan("puts 'Hello, world!'", :ruby).html | |
| 154 # | |
| 155 # See also demo/demo_simple. | |
| 156 def scan code, lang, options = {}, &block | |
| 157 scanner = Scanners[lang].new code, options, &block | |
| 158 scanner.tokenize | |
| 159 end | |
| 160 | |
| 161 # Scans +filename+ (a path to a code file) with the Scanner for +lang+. | |
| 162 # | |
| 163 # If +lang+ is :auto or omitted, the CodeRay::FileType module is used to | |
| 164 # determine it. If it cannot find out what type it is, it uses | |
| 165 # CodeRay::Scanners::Plaintext. | |
| 166 # | |
| 167 # Calls CodeRay.scan. | |
| 168 # | |
| 169 # Example: | |
| 170 # require 'coderay' | |
| 171 # page = CodeRay.scan_file('some_c_code.c').html | |
| 172 def scan_file filename, lang = :auto, options = {}, &block | |
| 173 file = IO.read filename | |
| 174 if lang == :auto | |
| 175 require 'coderay/helpers/file_type' | |
| 176 lang = FileType.fetch filename, :plaintext, true | |
| 177 end | |
| 178 scan file, lang, options = {}, &block | |
| 179 end | |
| 180 | |
| 181 # Scan the +code+ (a string) with the scanner for +lang+. | |
| 182 # | |
| 183 # Calls scan. | |
| 184 # | |
| 185 # See CodeRay.scan. | |
| 186 def scan_stream code, lang, options = {}, &block | |
| 187 options[:stream] = true | |
| 188 scan code, lang, options, &block | |
| 189 end | |
| 190 | |
| 191 # Encode a string in Streaming mode. | |
| 192 # | |
| 193 # This starts scanning +code+ with the the Scanner for +lang+ | |
| 194 # while encodes the output with the Encoder for +format+. | |
| 195 # +options+ will be passed to the Encoder. | |
| 196 # | |
| 197 # See CodeRay::Encoder.encode_stream | |
| 198 def encode_stream code, lang, format, options = {} | |
| 199 encoder(format, options).encode_stream code, lang, options | |
| 200 end | |
| 201 | |
| 202 # Encode a string. | |
| 203 # | |
| 204 # This scans +code+ with the the Scanner for +lang+ and then | |
| 205 # encodes it with the Encoder for +format+. | |
| 206 # +options+ will be passed to the Encoder. | |
| 207 # | |
| 208 # See CodeRay::Encoder.encode | |
| 209 def encode code, lang, format, options = {} | |
| 210 encoder(format, options).encode code, lang, options | |
| 211 end | |
| 212 | |
| 213 # Highlight a string into a HTML <div>. | |
| 214 # | |
| 215 # CSS styles use classes, so you have to include a stylesheet | |
| 216 # in your output. | |
| 217 # | |
| 218 # See encode. | |
| 219 def highlight code, lang, options = { :css => :class }, format = :div | |
| 220 encode code, lang, format, options | |
| 221 end | |
| 222 | |
| 223 # Encode pre-scanned Tokens. | |
| 224 # Use this together with CodeRay.scan: | |
| 225 # | |
| 226 # require 'coderay' | |
| 227 # | |
| 228 # # Highlight a short Ruby code example in a HTML span | |
| 229 # tokens = CodeRay.scan '1 + 2', :ruby | |
| 230 # puts CodeRay.encode_tokens(tokens, :span) | |
| 231 # | |
| 232 def encode_tokens tokens, format, options = {} | |
| 233 encoder(format, options).encode_tokens tokens, options | |
| 234 end | |
| 235 | |
| 236 # Encodes +filename+ (a path to a code file) with the Scanner for +lang+. | |
| 237 # | |
| 238 # See CodeRay.scan_file. | |
| 239 # Notice that the second argument is the output +format+, not the input language. | |
| 240 # | |
| 241 # Example: | |
| 242 # require 'coderay' | |
| 243 # page = CodeRay.encode_file 'some_c_code.c', :html | |
| 244 def encode_file filename, format, options = {} | |
| 245 tokens = scan_file filename, :auto, get_scanner_options(options) | |
| 246 encode_tokens tokens, format, options | |
| 247 end | |
| 248 | |
| 249 # Highlight a file into a HTML <div>. | |
| 250 # | |
| 251 # CSS styles use classes, so you have to include a stylesheet | |
| 252 # in your output. | |
| 253 # | |
| 254 # See encode. | |
| 255 def highlight_file filename, options = { :css => :class }, format = :div | |
| 256 encode_file filename, format, options | |
| 257 end | |
| 258 | |
| 259 # Finds the Encoder class for +format+ and creates an instance, passing | |
| 260 # +options+ to it. | |
| 261 # | |
| 262 # Example: | |
| 263 # require 'coderay' | |
| 264 # | |
| 265 # stats = CodeRay.encoder(:statistic) | |
| 266 # stats.encode("puts 17 + 4\n", :ruby) | |
| 267 # | |
| 268 # puts '%d out of %d tokens have the kind :integer.' % [ | |
| 269 # stats.type_stats[:integer].count, | |
| 270 # stats.real_token_count | |
| 271 # ] | |
| 272 # #-> 2 out of 4 tokens have the kind :integer. | |
| 273 def encoder format, options = {} | |
| 274 Encoders[format].new options | |
| 275 end | |
| 276 | |
| 277 # Finds the Scanner class for +lang+ and creates an instance, passing | |
| 278 # +options+ to it. | |
| 279 # | |
| 280 # See Scanner.new. | |
| 281 def scanner lang, options = {} | |
| 282 Scanners[lang].new '', options | |
| 283 end | |
| 284 | |
| 285 # Extract the options for the scanner from the +options+ hash. | |
| 286 # | |
| 287 # Returns an empty Hash if <tt>:scanner_options</tt> is not set. | |
| 288 # | |
| 289 # This is used if a method like CodeRay.encode has to provide options | |
| 290 # for Encoder _and_ scanner. | |
| 291 def get_scanner_options options | |
| 292 options.fetch :scanner_options, {} | |
| 293 end | |
| 294 | |
| 295 end | |
| 296 | |
| 297 # This Exception is raised when you try to stream with something that is not | |
| 298 # capable of streaming. | |
| 299 class NotStreamableError < Exception | |
| 300 def initialize obj | |
| 301 @obj = obj | |
| 302 end | |
| 303 | |
| 304 def to_s | |
| 305 '%s is not Streamable!' % @obj.class | |
| 306 end | |
| 307 end | |
| 308 | |
| 309 # A dummy module that is included by subclasses of CodeRay::Scanner an CodeRay::Encoder | |
| 310 # to show that they are able to handle streams. | |
| 311 module Streamable | |
| 312 end | |
| 313 | |
| 314 end | |
| 315 | |
| 316 # Run a test script. | |
| 317 if $0 == __FILE__ | |
| 318 $stderr.print 'Press key to print demo.'; gets | |
| 319 # Just use this file as an example of Ruby code. | |
| 320 code = File.read(__FILE__)[/module CodeRay.*/m] | |
| 321 print CodeRay.scan(code, :ruby).html | |
| 322 end |
