coderay-1.1.1/0000755000004100000410000000000012663664402013201 5ustar www-datawww-datacoderay-1.1.1/Rakefile0000644000004100000410000000151712663664402014652 0ustar www-datawww-datarequire 'bundler/gem_tasks' $:.unshift File.dirname(__FILE__) unless $:.include? '.' ROOT = '.' LIB_ROOT = File.join ROOT, 'lib' task :default => :test if File.directory? 'rake_tasks' # load rake tasks from subfolder for task_file in Dir['rake_tasks/*.rake'].sort load task_file end else # fallback tasks when rake_tasks folder is not present (eg. in the distribution package) desc 'Run CodeRay tests (basic)' task :test do ruby './test/functional/suite.rb' ruby './test/functional/for_redcloth.rb' end gem 'rdoc' if defined? gem require 'rdoc/task' desc 'Generate documentation for CodeRay' Rake::RDocTask.new :doc do |rd| rd.title = 'CodeRay Documentation' rd.main = 'README_INDEX.rdoc' rd.rdoc_files.add Dir['lib'] rd.rdoc_files.add rd.main rd.rdoc_dir = 'doc' end end coderay-1.1.1/bin/0000755000004100000410000000000012663664402013751 5ustar www-datawww-datacoderay-1.1.1/bin/coderay0000755000004100000410000001314612663664402015332 0ustar www-datawww-data#!/usr/bin/env ruby require 'coderay' $options, args = ARGV.partition { |arg| arg[/^-[hv]$|--\w+/] } subcommand = args.first if /^\w/ === args.first subcommand = nil if subcommand && File.exist?(subcommand) args.delete subcommand def option? *options !($options & options).empty? end def tty? $stdout.tty? || option?('--tty') end def version puts <<-USAGE CodeRay #{CodeRay::VERSION} USAGE end def help puts <<-HELP This is CodeRay #{CodeRay::VERSION}, a syntax highlighting tool for selected languages. usage: coderay [-language] [input] [-format] [output] defaults: language detect from input file name or shebang; fall back to plain text input STDIN format detect from output file name or use terminal; fall back to HTML output STDOUT common: coderay file.rb # highlight file to terminal coderay file.rb -page > file.html # highlight file to HTML page coderay file.rb -div > file.html # highlight file to HTML snippet configure output: coderay file.py output.json # output tokens as JSON coderay file.py -loc # count lines of code in Python file configure input: coderay -python file # specify the input language coderay -ruby # take input from STDIN more: coderay stylesheet [style] # print CSS stylesheet HELP end def commands puts <<-COMMANDS general: highlight code highlighting (default command, optional) stylesheet print the CSS stylesheet with the given name (aliases: style, css) about: list [of] list all available plugins (or just the scanners|encoders|styles|filetypes) commands print this list help show some help version print CodeRay version COMMANDS end def print_list_of plugin_host plugins = plugin_host.all_plugins.map do |plugin| info = " #{plugin.plugin_id}: #{plugin.title}" aliases = (plugin.aliases - [:default]).map { |key| "-#{key}" }.sort_by { |key| key.size } if plugin.respond_to?(:file_extension) || !aliases.empty? additional_info = [] additional_info << aliases.join(', ') unless aliases.empty? info << " (#{additional_info.join('; ')})" end info << ' <-- default' if plugin.aliases.include? :default info end puts plugins.sort end if option? '-v', '--version' version end if option? '-h', '--help' help end case subcommand when 'highlight', nil if ARGV.empty? version help else signature = args.map { |arg| arg[/^-/] ? '-' : 'f' }.join names = args.map { |arg| arg.sub(/^-/, '') } case signature when /^$/ exit when /^ff?$/ input_file, output_file, = *names when /^f-f?$/ input_file, output_format, output_file, = *names when /^-ff?$/ input_lang, input_file, output_file, = *names when /^-f-f?$/ input_lang, input_file, output_format, output_file, = *names when /^--?f?$/ input_lang, output_format, output_file, = *names else $stdout = $stderr help puts puts "Unknown parameter order: #{args.join ' '}, expected: [-language] [input] [-format] [output]" exit 1 end if input_file input_lang ||= CodeRay::FileType.fetch input_file, :text, true end if output_file output_format ||= CodeRay::FileType[output_file] || :plain else output_format ||= :terminal end output_format = :page if output_format.to_s == 'html' if input_file input = File.read input_file else input = $stdin.read end begin file = if output_file File.open output_file, 'w' else $stdout end CodeRay.encode(input, input_lang, output_format, :out => file) file.puts rescue CodeRay::PluginHost::PluginNotFound => boom $stdout = $stderr if boom.message[/CodeRay::(\w+)s could not load plugin :?(.*?): /] puts "I don't know the #$1 \"#$2\"." else puts boom.message end # puts "I don't know this plugin: #{boom.message[/Could not load plugin (.*?): /, 1]}." rescue CodeRay::Scanners::Scanner::ScanError # this is sometimes raised by pagers; ignore # FIXME: rescue Errno::EPIPE ensure file.close if output_file end end when 'li', 'list' arg = args.first && args.first.downcase if [nil, 's', 'sc', 'scanner', 'scanners'].include? arg puts 'input languages (Scanners):' print_list_of CodeRay::Scanners end if [nil, 'e', 'en', 'enc', 'encoder', 'encoders'].include? arg puts 'output formats (Encoders):' print_list_of CodeRay::Encoders end if [nil, 'st', 'style', 'styles'].include? arg puts 'CSS themes for HTML output (Styles):' print_list_of CodeRay::Styles end if [nil, 'f', 'ft', 'file', 'filetype', 'filetypes'].include? arg puts 'recognized file types:' filetypes = Hash.new { |h, k| h[k] = [] } CodeRay::FileType::TypeFromExt.inject filetypes do |types, (ext, type)| types[type.to_s] << ".#{ext}" types end CodeRay::FileType::TypeFromName.inject filetypes do |types, (name, type)| types[type.to_s] << name types end filetypes.sort.each do |type, exts| puts " #{type}: #{exts.sort_by { |ext| ext.size }.join(', ')}" end end when 'stylesheet', 'style', 'css' puts CodeRay::Encoders[:html]::CSS.new(args.first || :default).stylesheet when 'commands' commands when 'help' help else $stdout = $stderr help puts if subcommand[/\A\w+\z/] puts "Unknown command: #{subcommand}" else puts "File not found: #{subcommand}" end exit 1 end coderay-1.1.1/lib/0000755000004100000410000000000012663664402013747 5ustar www-datawww-datacoderay-1.1.1/lib/coderay.rb0000644000004100000410000002166112663664402015730 0ustar www-datawww-data# encoding: utf-8 # Encoding.default_internal = 'UTF-8' # = CodeRay Library # # CodeRay is a Ruby library for syntax highlighting. # # I try to make CodeRay easy to use and intuitive, but at the same time fully # featured, complete, fast and efficient. # # See README. # # It consists mainly of # * the main engine: CodeRay (Scanners::Scanner, Tokens, Encoders::Encoder) # * the plugin system: PluginHost, Plugin # * the scanners in CodeRay::Scanners # * the encoders in CodeRay::Encoders # * the styles in CodeRay::Styles # # Here's a fancy graphic to light up this gray docu: # # http://cycnus.de/raindark/coderay/scheme.png # # == Documentation # # See CodeRay, Encoders, Scanners, Tokens. # # == Usage # # Remember you need RubyGems to use CodeRay, unless you have it in your load # path. Run Ruby with -rubygems option if required. # # === Highlight Ruby code in a string as html # # require 'coderay' # print CodeRay.scan('puts "Hello, world!"', :ruby).html # # # prints something like this: # puts "Hello, world!" # # # === Highlight C code from a file in a html div # # require 'coderay' # print CodeRay.scan(File.read('ruby.h'), :c).div # print CodeRay.scan_file('ruby.h').html.div # # You can include this div in your page. The used CSS styles can be printed with # # % coderay_stylesheet # # === Highlight without typing too much # # If you are one of the hasty (or lazy, or extremely curious) people, just run this file: # # % ruby -rubygems /path/to/coderay/coderay.rb > example.html # # and look at the file it created in your browser. # # = CodeRay Module # # The CodeRay module provides convenience methods for the engine. # # * The +lang+ and +format+ arguments select Scanner and Encoder to use. These are # simply lower-case symbols, like :python or :html. # * All methods take an optional hash as last parameter, +options+, that is send to # the Encoder / Scanner. # * Input and language are always sorted in this order: +code+, +lang+. # (This is in alphabetical order, if you need a mnemonic ;) # # You should be able to highlight everything you want just using these methods; # so there is no need to dive into CodeRay's deep class hierarchy. # # The examples in the demo directory demonstrate common cases using this interface. # # = Basic Access Ways # # Read this to get a general view what CodeRay provides. # # == Scanning # # Scanning means analysing an input string, splitting it up into Tokens. # Each Token knows about what type it is: string, comment, class name, etc. # # Each +lang+ (language) has its own Scanner; for example, :ruby code is # handled by CodeRay::Scanners::Ruby. # # CodeRay.scan:: Scan a string in a given language into Tokens. # This is the most common method to use. # CodeRay.scan_file:: Scan a file and guess the language using FileType. # # The Tokens object you get from these methods can encode itself; see Tokens. # # == Encoding # # Encoding means compiling Tokens into an output. This can be colored HTML or # LaTeX, a textual statistic or just the number of non-whitespace tokens. # # Each Encoder provides output in a specific +format+, so you select Encoders via # formats like :html or :statistic. # # CodeRay.encode:: Scan and encode a string in a given language. # CodeRay.encode_tokens:: Encode the given tokens. # CodeRay.encode_file:: Scan a file, guess the language using FileType and encode it. # # == All-in-One Encoding # # CodeRay.encode:: Highlight a string with a given input and output format. # # == Instanciating # # You can use an Encoder instance to highlight multiple inputs. This way, the setup # for this Encoder must only be done once. # # CodeRay.encoder:: Create an Encoder instance with format and options. # CodeRay.scanner:: Create an Scanner instance for lang, with '' as default code. # # To make use of CodeRay.scanner, use CodeRay::Scanner::code=. # # The scanning methods provide more flexibility; we recommend to use these. # # == Reusing Scanners and Encoders # # If you want to re-use scanners and encoders (because that is faster), see # CodeRay::Duo for the most convenient (and recommended) interface. module CodeRay $CODERAY_DEBUG ||= false CODERAY_PATH = File.expand_path('../coderay', __FILE__) # Assuming the path is a subpath of lib/coderay/ def self.coderay_path *path File.join CODERAY_PATH, *path end autoload :VERSION, 'coderay/version' # helpers autoload :FileType, coderay_path('helpers', 'file_type') # Tokens autoload :Tokens, coderay_path('tokens') autoload :TokensProxy, coderay_path('tokens_proxy') autoload :TokenKinds, coderay_path('token_kinds') # Plugin system autoload :PluginHost, coderay_path('helpers', 'plugin_host') autoload :Plugin, coderay_path('helpers', 'plugin') # Plugins autoload :Scanners, coderay_path('scanners') autoload :Encoders, coderay_path('encoders') autoload :Styles, coderay_path('styles') # convenience access and reusable Encoder/Scanner pair autoload :Duo, coderay_path('duo') class << self # Scans the given +code+ (a String) with the Scanner for +lang+. # # This is a simple way to use CodeRay. Example: # require 'coderay' # page = CodeRay.scan("puts 'Hello, world!'", :ruby).html # # See also demo/demo_simple. def scan code, lang, options = {}, &block CodeRay::TokensProxy.new code, lang, options, block end # Scans +filename+ (a path to a code file) with the Scanner for +lang+. # # If +lang+ is :auto or omitted, the CodeRay::FileType module is used to # determine it. If it cannot find out what type it is, it uses # CodeRay::Scanners::Text. # # Calls CodeRay.scan. # # Example: # require 'coderay' # page = CodeRay.scan_file('some_c_code.c').html def scan_file filename, lang = :auto, options = {}, &block lang = CodeRay::FileType.fetch filename, :text, true if lang == :auto code = File.read filename scan code, lang, options, &block end # Encode a string. # # This scans +code+ with the the Scanner for +lang+ and then # encodes it with the Encoder for +format+. # +options+ will be passed to the Encoder. # # See CodeRay::Encoder.encode. def encode code, lang, format, options = {} encoder(format, options).encode code, lang, options end # Encode pre-scanned Tokens. # Use this together with CodeRay.scan: # # require 'coderay' # # # Highlight a short Ruby code example in a HTML span # tokens = CodeRay.scan '1 + 2', :ruby # puts CodeRay.encode_tokens(tokens, :span) # def encode_tokens tokens, format, options = {} encoder(format, options).encode_tokens tokens, options end # Encodes +filename+ (a path to a code file) with the Scanner for +lang+. # # See CodeRay.scan_file. # Notice that the second argument is the output +format+, not the input language. # # Example: # require 'coderay' # page = CodeRay.encode_file 'some_c_code.c', :html def encode_file filename, format, options = {} tokens = scan_file filename, :auto, get_scanner_options(options) encode_tokens tokens, format, options end # Highlight a string into a HTML
. # # CSS styles use classes, so you have to include a stylesheet # in your output. # # See encode. def highlight code, lang, options = { :css => :class }, format = :div encode code, lang, format, options end # Highlight a file into a HTML
. # # CSS styles use classes, so you have to include a stylesheet # in your output. # # See encode. def highlight_file filename, options = { :css => :class }, format = :div encode_file filename, format, options end # Finds the Encoder class for +format+ and creates an instance, passing # +options+ to it. # # Example: # require 'coderay' # # stats = CodeRay.encoder(:statistic) # stats.encode("puts 17 + 4\n", :ruby) # # puts '%d out of %d tokens have the kind :integer.' % [ # stats.type_stats[:integer].count, # stats.real_token_count # ] # #-> 2 out of 4 tokens have the kind :integer. def encoder format, options = {} CodeRay::Encoders[format].new options end # Finds the Scanner class for +lang+ and creates an instance, passing # +options+ to it. # # See Scanner.new. def scanner lang, options = {}, &block CodeRay::Scanners[lang].new '', options, &block end # Extract the options for the scanner from the +options+ hash. # # Returns an empty Hash if :scanner_options is not set. # # This is used if a method like CodeRay.encode has to provide options # for Encoder _and_ scanner. def get_scanner_options options options.fetch :scanner_options, {} end end end coderay-1.1.1/lib/coderay/0000755000004100000410000000000012663664402015375 5ustar www-datawww-datacoderay-1.1.1/lib/coderay/tokens_proxy.rb0000644000004100000410000000277312663664402020477 0ustar www-datawww-datamodule CodeRay # The result of a scan operation is a TokensProxy, but should act like Tokens. # # This proxy makes it possible to use the classic CodeRay.scan.encode API # while still providing the benefits of direct streaming. class TokensProxy attr_accessor :input, :lang, :options, :block # Create a new TokensProxy with the arguments of CodeRay.scan. def initialize input, lang, options = {}, block = nil @input = input @lang = lang @options = options @block = block end # Call CodeRay.encode if +encoder+ is a Symbol; # otherwise, convert the receiver to tokens and call encoder.encode_tokens. def encode encoder, options = {} if encoder.respond_to? :to_sym CodeRay.encode(input, lang, encoder, options) else encoder.encode_tokens tokens, options end end # Tries to call encode; # delegates to tokens otherwise. def method_missing method, *args, &blk encode method.to_sym, *args rescue PluginHost::PluginNotFound tokens.send(method, *args, &blk) end # The (cached) result of the tokenized input; a Tokens instance. def tokens @tokens ||= scanner.tokenize(input) end # A (cached) scanner instance to use for the scan task. def scanner @scanner ||= CodeRay.scanner(lang, options, &block) end # Overwrite Struct#each. def each *args, &blk tokens.each(*args, &blk) self end end end coderay-1.1.1/lib/coderay/tokens.rb0000644000004100000410000001211112663664402017221 0ustar www-datawww-datamodule CodeRay # The Tokens class represents a list of tokens returned from # a Scanner. It's actually just an Array with a few helper methods. # # A token itself is not a special object, just two elements in an Array: # * the _token_ _text_ (the original source of the token in a String) or # a _token_ _action_ (begin_group, end_group, begin_line, end_line) # * the _token_ _kind_ (a Symbol representing the type of the token) # # It looks like this: # # ..., '# It looks like this', :comment, ... # ..., '3.1415926', :float, ... # ..., '$^', :error, ... # # Some scanners also yield sub-tokens, represented by special # token actions, for example :begin_group and :end_group. # # The Ruby scanner, for example, splits "a string" into: # # [ # :begin_group, :string, # '"', :delimiter, # 'a string', :content, # '"', :delimiter, # :end_group, :string # ] # # Tokens can be used to save the output of a Scanners in a simple # Ruby object that can be send to an Encoder later: # # tokens = CodeRay.scan('price = 2.59', :ruby).tokens # tokens.encode(:html) # tokens.html # CodeRay.encoder(:html).encode_tokens(tokens) # # Tokens gives you the power to handle pre-scanned code very easily: # You can serialize it to a JSON string and store it in a database, pass it # around to encode it more than once, send it to other algorithms... class Tokens < Array # The Scanner instance that created the tokens. attr_accessor :scanner # Encode the tokens using encoder. # # encoder can be # * a plugin name like :html oder 'statistic' # * an Encoder object # # options are passed to the encoder. def encode encoder, options = {} encoder = Encoders[encoder].new options if encoder.respond_to? :to_sym encoder.encode_tokens self, options end # Turn tokens into a string by concatenating them. def to_s encode CodeRay::Encoders::Encoder.new end # Redirects unknown methods to encoder calls. # # For example, if you call +tokens.html+, the HTML encoder # is used to highlight the tokens. def method_missing meth, options = {} encode meth, options rescue PluginHost::PluginNotFound super end # Split the tokens into parts of the given +sizes+. # # The result will be an Array of Tokens objects. The parts have # the text size specified by the parameter. In addition, each # part closes all opened tokens. This is useful to insert tokens # betweem them. # # This method is used by @Scanner#tokenize@ when called with an Array # of source strings. The Diff encoder uses it for inline highlighting. def split_into_parts *sizes return Array.new(sizes.size) { Tokens.new } if size == 2 && first == '' parts = [] opened = [] content = nil part = Tokens.new part_size = 0 size = sizes.first i = 0 for item in self case content when nil content = item when String if size && part_size + content.size > size # token must be cut if part_size < size # some part of the token goes into this part content = content.dup # content may no be safe to change part << content.slice!(0, size - part_size) << item end # close all open groups and lines... closing = opened.reverse.flatten.map do |content_or_kind| case content_or_kind when :begin_group :end_group when :begin_line :end_line else content_or_kind end end part.concat closing begin parts << part part = Tokens.new size = sizes[i += 1] end until size.nil? || size > 0 # ...and open them again. part.concat opened.flatten part_size = 0 redo unless content.empty? else part << content << item part_size += content.size end content = nil when Symbol case content when :begin_group, :begin_line opened << [content, item] when :end_group, :end_line opened.pop else raise ArgumentError, 'Unknown token action: %p, kind = %p' % [content, item] end part << content << item content = nil else raise ArgumentError, 'Token input junk: %p, kind = %p' % [content, item] end end parts << part parts << Tokens.new while parts.size < sizes.size parts end # Return the actual number of tokens. def count size / 2 end alias text_token push def begin_group kind; push :begin_group, kind end def end_group kind; push :end_group, kind end def begin_line kind; push :begin_line, kind end def end_line kind; push :end_line, kind end alias tokens concat end end coderay-1.1.1/lib/coderay/encoders.rb0000644000004100000410000000103312663664402017521 0ustar www-datawww-datamodule CodeRay # This module holds the Encoder class and its subclasses. # For example, the HTML encoder is named CodeRay::Encoders::HTML # can be found in coderay/encoders/html. # # Encoders also provides methods and constants for the register # mechanism and the [] method that returns the Encoder class # belonging to the given format. module Encoders extend PluginHost plugin_path File.dirname(__FILE__), 'encoders' autoload :Encoder, CodeRay.coderay_path('encoders', 'encoder') end end coderay-1.1.1/lib/coderay/duo.rb0000644000004100000410000000450712663664402016517 0ustar www-datawww-datamodule CodeRay # = Duo # # A Duo is a convenient way to use CodeRay. You just create a Duo, # giving it a lang (language of the input code) and a format (desired # output format), and call Duo#highlight with the code. # # Duo makes it easy to re-use both scanner and encoder for a repetitive # task. It also provides a very easy interface syntax: # # require 'coderay' # CodeRay::Duo[:python, :div].highlight 'import this' # # Until you want to do uncommon things with CodeRay, I recommend to use # this method, since it takes care of everything. class Duo attr_accessor :lang, :format, :options # Create a new Duo, holding a lang and a format to highlight code. # # simple: # CodeRay::Duo[:ruby, :html].highlight 'bla 42' # # with options: # CodeRay::Duo[:ruby, :html, :hint => :debug].highlight '????::??' # # alternative syntax without options: # CodeRay::Duo[:ruby => :statistic].encode 'class << self; end' # # alternative syntax with options: # CodeRay::Duo[{ :ruby => :statistic }, :do => :something].encode 'abc' # # The options are forwarded to scanner and encoder # (see CodeRay.get_scanner_options). def initialize lang = nil, format = nil, options = {} if format.nil? && lang.is_a?(Hash) && lang.size == 1 @lang = lang.keys.first @format = lang[@lang] else @lang = lang @format = format end @options = options end class << self # To allow calls like Duo[:ruby, :html].highlight. alias [] new end # The scanner of the duo. Only created once. def scanner @scanner ||= CodeRay.scanner @lang, CodeRay.get_scanner_options(@options) end # The encoder of the duo. Only created once. def encoder @encoder ||= CodeRay.encoder @format, @options end # Tokenize and highlight the code using +scanner+ and +encoder+. def encode code, options = {} options = @options.merge options encoder.encode(code, @lang, options) end alias highlight encode # Allows to use Duo like a proc object: # # CodeRay::Duo[:python => :yaml].call(code) # # or, in Ruby 1.9 and later: # # CodeRay::Duo[:python => :yaml].(code) alias call encode end end coderay-1.1.1/lib/coderay/version.rb0000644000004100000410000000004712663664402017410 0ustar www-datawww-datamodule CodeRay VERSION = '1.1.1' end coderay-1.1.1/lib/coderay/encoders/0000755000004100000410000000000012663664402017177 5ustar www-datawww-datacoderay-1.1.1/lib/coderay/encoders/html/0000755000004100000410000000000012663664402020143 5ustar www-datawww-datacoderay-1.1.1/lib/coderay/encoders/html/output.rb0000644000004100000410000000755612663664402022045 0ustar www-datawww-datamodule CodeRay module Encoders class HTML # This module is included in the output String of the HTML Encoder. # # It provides methods like wrap, div, page etc. # # Remember to use #clone instead of #dup to keep the modules the object was # extended with. # # TODO: Rewrite this without monkey patching. module Output attr_accessor :css class << self # Raises an exception if an object that doesn't respond to to_str is extended by Output, # to prevent users from misuse. Use Module#remove_method to disable. def extended o # :nodoc: warn "The Output module is intended to extend instances of String, not #{o.class}." unless o.respond_to? :to_str end def make_stylesheet css, in_tag = false # :nodoc: sheet = css.stylesheet sheet = <<-'CSS' if in_tag CSS sheet end def page_template_for_css css # :nodoc: sheet = make_stylesheet css PAGE.apply 'CSS', sheet end end def wrapped_in? element wrapped_in == element end def wrapped_in @wrapped_in ||= nil end attr_writer :wrapped_in def wrap_in! template Template.wrap! self, template, 'CONTENT' self end def apply_title! title self.sub!(/()(<\/title>)/) { $1 + title + $2 } self end def wrap! element, *args return self if not element or element == wrapped_in case element when :div raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? nil wrap_in! DIV when :span raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? nil wrap_in! SPAN when :page wrap! :div if wrapped_in? nil raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? :div wrap_in! Output.page_template_for_css(@css) if args.first.is_a?(Hash) && title = args.first[:title] apply_title! title end self when nil return self else raise "Unknown value %p for :wrap" % element end @wrapped_in = element self end def stylesheet in_tag = false Output.make_stylesheet @css, in_tag end #-- don't include the templates in docu class Template < String # :nodoc: def self.wrap! str, template, target target = Regexp.new(Regexp.escape("<%#{target}%>")) if template =~ target str[0,0] = $` str << $' else raise "Template target <%%%p%%> not found" % target end end def apply target, replacement target = Regexp.new(Regexp.escape("<%#{target}%>")) if self =~ target Template.new($` + replacement + $') else raise "Template target <%%%p%%> not found" % target end end end SPAN = Template.new '<span class="CodeRay"><%CONTENT%></span>' DIV = Template.new <<-DIV <div class="CodeRay"> <div class="code"><pre><%CONTENT%></pre></div> </div> DIV TABLE = Template.new <<-TABLE <table class="CodeRay"><tr> <td class="line-numbers"><pre><%LINE_NUMBERS%></pre></td> <td class="code"><pre><%CONTENT%></pre></td> </tr></table> TABLE PAGE = Template.new <<-PAGE <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title> <%CONTENT%> PAGE end end end end coderay-1.1.1/lib/coderay/encoders/html/numbering.rb0000644000004100000410000000700212663664402022455 0ustar www-datawww-datamodule CodeRay module Encoders class HTML module Numbering # :nodoc: def self.number! output, mode = :table, options = {} return self unless mode options = DEFAULT_OPTIONS.merge options start = options[:line_number_start] unless start.is_a? Integer raise ArgumentError, "Invalid value %p for :line_number_start; Integer expected." % start end anchor_prefix = options[:line_number_anchors] anchor_prefix = 'line' if anchor_prefix == true anchor_prefix = anchor_prefix.to_s[/[\w-]+/] if anchor_prefix anchoring = if anchor_prefix proc do |line| line = line.to_s anchor = anchor_prefix + line "#{line}" end else :to_s.to_proc end bold_every = options[:bold_every] highlight_lines = options[:highlight_lines] bolding = if bold_every == false && highlight_lines == nil anchoring elsif highlight_lines.is_a? Enumerable highlight_lines = highlight_lines.to_set proc do |line| if highlight_lines.include? line "#{anchoring[line]}" # highlighted line numbers in bold else anchoring[line] end end elsif bold_every.is_a? Integer raise ArgumentError, ":bolding can't be 0." if bold_every == 0 proc do |line| if line % bold_every == 0 "#{anchoring[line]}" # every bold_every-th number in bold else anchoring[line] end end else raise ArgumentError, 'Invalid value %p for :bolding; false or Integer expected.' % bold_every end if position_of_last_newline = output.rindex(RUBY_VERSION >= '1.9' ? /\n/ : ?\n) after_last_newline = output[position_of_last_newline + 1 .. -1] ends_with_newline = after_last_newline[/\A(?:<\/span>)*\z/] if ends_with_newline line_count = output.count("\n") else line_count = output.count("\n") + 1 end else line_count = 1 end case mode when :inline max_width = (start + line_count).to_s.size line_number = start output.gsub!(/^.*$\n?/) do |line| line_number_text = bolding.call line_number indent = ' ' * (max_width - line_number.to_s.size) line_number += 1 "#{indent}#{line_number_text}#{line}" end when :table line_numbers = (start ... start + line_count).map(&bolding).join("\n") line_numbers << "\n" line_numbers_table_template = Output::TABLE.apply('LINE_NUMBERS', line_numbers) output.gsub!(/<\/div>\n/, '
') output.wrap_in! line_numbers_table_template output.wrapped_in = :div when :list raise NotImplementedError, 'The :list option is no longer available. Use :table.' else raise ArgumentError, 'Unknown value %p for mode: expected one of %p' % [mode, [:table, :inline]] end output end end end end end coderay-1.1.1/lib/coderay/encoders/html/css.rb0000644000004100000410000000307612663664402021266 0ustar www-datawww-datamodule CodeRay module Encoders class HTML class CSS # :nodoc: attr :stylesheet def CSS.load_stylesheet style = nil CodeRay::Styles[style] end def initialize style = :default @styles = Hash.new style = CSS.load_stylesheet style @stylesheet = [ style::CSS_MAIN_STYLES, style::TOKEN_COLORS.gsub(/^(?!$)/, '.CodeRay ') ].join("\n") parse style::TOKEN_COLORS end def get_style_for_css_classes css_classes cl = @styles[css_classes.first] return '' unless cl style = '' 1.upto css_classes.size do |offset| break if style = cl[css_classes[offset .. -1]] end # warn 'Style not found: %p' % [styles] if style.empty? return style end private CSS_CLASS_PATTERN = / ( # $1 = selectors (?: (?: \s* \. [-\w]+ )+ \s* ,? )+ ) \s* \{ \s* ( [^\}]+ )? # $2 = style \s* \} \s* | ( [^\n]+ ) # $3 = error /mx def parse stylesheet stylesheet.scan CSS_CLASS_PATTERN do |selectors, style, error| raise "CSS parse error: '#{error.inspect}' not recognized" if error for selector in selectors.split(',') classes = selector.scan(/[-\w]+/) cl = classes.pop @styles[cl] ||= Hash.new @styles[cl][classes] = style.to_s.strip.delete(' ').chomp(';') end end end end end end end coderay-1.1.1/lib/coderay/encoders/debug_lint.rb0000644000004100000410000000266412663664402021650 0ustar www-datawww-datamodule CodeRay module Encoders load :lint # = Debug Lint Encoder # # Debug encoder with additional checks for: # # - empty tokens # - incorrect nesting # # It will raise an InvalidTokenStream exception when any of the above occurs. # # See also: Encoders::Debug class DebugLint < Debug register_for :debug_lint def text_token text, kind raise Lint::EmptyToken, 'empty token for %p' % [kind] if text.empty? raise Lint::UnknownTokenKind, 'unknown token kind %p (text was %p)' % [kind, text] unless TokenKinds.has_key? kind super end def begin_group kind @opened << kind super end def end_group kind raise Lint::IncorrectTokenGroupNesting, 'We are inside %s, not %p (end_group)' % [@opened.reverse.map(&:inspect).join(' < '), kind] if @opened.last != kind @opened.pop super end def begin_line kind @opened << kind super end def end_line kind raise Lint::IncorrectTokenGroupNesting, 'We are inside %s, not %p (end_line)' % [@opened.reverse.map(&:inspect).join(' < '), kind] if @opened.last != kind @opened.pop super end protected def setup options super @opened = [] end def finish options raise 'Some tokens still open at end of token stream: %p' % [@opened] unless @opened.empty? super end end end end coderay-1.1.1/lib/coderay/encoders/div.rb0000644000004100000410000000065212663664402020311 0ustar www-datawww-datamodule CodeRay module Encoders load :html # Wraps HTML output into a DIV element, using inline styles by default. # # See Encoders::HTML for available options. class Div < HTML FILE_EXTENSION = 'div.html' register_for :div DEFAULT_OPTIONS = HTML::DEFAULT_OPTIONS.merge \ :css => :style, :wrap => :div, :line_numbers => false end end end coderay-1.1.1/lib/coderay/encoders/comment_filter.rb0000644000004100000410000000077512663664402022544 0ustar www-datawww-datamodule CodeRay module Encoders load :token_kind_filter # A simple Filter that removes all tokens of the :comment kind. # # Alias: +remove_comments+ # # Usage: # CodeRay.scan('print # foo', :ruby).comment_filter.text # #-> "print " # # See also: TokenKindFilter, LinesOfCode class CommentFilter < TokenKindFilter register_for :comment_filter DEFAULT_OPTIONS = superclass::DEFAULT_OPTIONS.merge \ :exclude => [:comment, :docstring] end end end coderay-1.1.1/lib/coderay/encoders/yaml.rb0000644000004100000410000000131012663664402020461 0ustar www-datawww-dataautoload :YAML, 'yaml' module CodeRay module Encoders # = YAML Encoder # # Slow. class YAML < Encoder register_for :yaml FILE_EXTENSION = 'yaml' protected def setup options super @data = [] end def finish options output ::YAML.dump(@data) end public def text_token text, kind @data << [text, kind] end def begin_group kind @data << [:begin_group, kind] end def end_group kind @data << [:end_group, kind] end def begin_line kind @data << [:begin_line, kind] end def end_line kind @data << [:end_line, kind] end end end end coderay-1.1.1/lib/coderay/encoders/encoder.rb0000644000004100000410000001300512663664402021142 0ustar www-datawww-datamodule CodeRay module Encoders # = Encoder # # The Encoder base class. Together with Scanner and # Tokens, it forms the highlighting triad. # # Encoder instances take a Tokens object and do something with it. # # The most common Encoder is surely the HTML encoder # (CodeRay::Encoders::HTML). It highlights the code in a colorful # html page. # If you want the highlighted code in a div or a span instead, # use its subclasses Div and Span. class Encoder extend Plugin plugin_host Encoders class << self # If FILE_EXTENSION isn't defined, this method returns the # downcase class name instead. def const_missing sym if sym == :FILE_EXTENSION (defined?(@plugin_id) && @plugin_id || name[/\w+$/].downcase).to_s else super end end # The default file extension for output file of this encoder class. def file_extension self::FILE_EXTENSION end end # Subclasses are to store their default options in this constant. DEFAULT_OPTIONS = { } # The options you gave the Encoder at creating. attr_accessor :options, :scanner # Creates a new Encoder. # +options+ is saved and used for all encode operations, as long # as you don't overwrite it there by passing additional options. # # Encoder objects provide three encode methods: # - encode simply takes a +code+ string and a +lang+ # - encode_tokens expects a +tokens+ object instead # # Each method has an optional +options+ parameter. These are # added to the options you passed at creation. def initialize options = {} @options = self.class::DEFAULT_OPTIONS.merge options @@CODERAY_TOKEN_INTERFACE_DEPRECATION_WARNING_GIVEN = false end # Encode a Tokens object. def encode_tokens tokens, options = {} options = @options.merge options @scanner = tokens.scanner if tokens.respond_to? :scanner setup options compile tokens, options finish options end # Encode the given +code+ using the Scanner for +lang+. def encode code, lang, options = {} options = @options.merge options @scanner = Scanners[lang].new code, CodeRay.get_scanner_options(options).update(:tokens => self) setup options @scanner.tokenize finish options end # You can use highlight instead of encode, if that seems # more clear to you. alias highlight encode # The default file extension for this encoder. def file_extension self.class.file_extension end def << token unless @@CODERAY_TOKEN_INTERFACE_DEPRECATION_WARNING_GIVEN warn 'Using old Tokens#<< interface.' @@CODERAY_TOKEN_INTERFACE_DEPRECATION_WARNING_GIVEN = true end self.token(*token) end # Called with +content+ and +kind+ of the currently scanned token. # For simple scanners, it's enougth to implement this method. # # By default, it calls text_token, begin_group, end_group, begin_line, # or end_line, depending on the +content+. def token content, kind case content when String text_token content, kind when :begin_group begin_group kind when :end_group end_group kind when :begin_line begin_line kind when :end_line end_line kind else raise ArgumentError, 'Unknown token content type: %p, kind = %p' % [content, kind] end end # Called for each text token ([text, kind]), where text is a String. def text_token text, kind @out << text end # Starts a token group with the given +kind+. def begin_group kind end # Ends a token group with the given +kind+. def end_group kind end # Starts a new line token group with the given +kind+. def begin_line kind end # Ends a new line token group with the given +kind+. def end_line kind end protected # Called with merged options before encoding starts. # Sets @out to an empty string. # # See the HTML Encoder for an example of option caching. def setup options @out = get_output(options) end def get_output options options[:out] || '' end # Append data.to_s to the output. Returns the argument. def output data @out << data.to_s data end # Called with merged options after encoding starts. # The return value is the result of encoding, typically @out. def finish options @out end # Do the encoding. # # The already created +tokens+ object must be used; it must be a # Tokens object. def compile tokens, options = {} content = nil for item in tokens if item.is_a? Array raise ArgumentError, 'Two-element array tokens are no longer supported.' end if content token content, item content = nil else content = item end end raise 'odd number list for Tokens' if content end alias tokens compile public :tokens end end end coderay-1.1.1/lib/coderay/encoders/xml.rb0000644000004100000410000000260312663664402020325 0ustar www-datawww-datamodule CodeRay module Encoders # = XML Encoder # # Uses REXML. Very slow. class XML < Encoder register_for :xml FILE_EXTENSION = 'xml' autoload :REXML, 'rexml/document' DEFAULT_OPTIONS = { :tab_width => 8, :pretty => -1, :transitive => false, } protected def setup options super @doc = REXML::Document.new @doc << REXML::XMLDecl.new @tab_width = options[:tab_width] @root = @node = @doc.add_element('coderay-tokens') end def finish options @doc.write @out, options[:pretty], options[:transitive], true super end public def text_token text, kind if kind == :space token = @node else token = @node.add_element kind.to_s end text.scan(/(\x20+)|(\t+)|(\n)|[^\x20\t\n]+/) do |space, tab, nl| case when space token << REXML::Text.new(space, true) when tab token << REXML::Text.new(tab, true) when nl token << REXML::Text.new(nl, true) else token << REXML::Text.new($&) end end end def begin_group kind @node = @node.add_element kind.to_s end def end_group kind if @node == @root raise 'no token to close!' end @node = @node.parent end end end end coderay-1.1.1/lib/coderay/encoders/text.rb0000644000004100000410000000134112663664402020507 0ustar www-datawww-datamodule CodeRay module Encoders # Concats the tokens into a single string, resulting in the original # code string if no tokens were removed. # # Alias: +plain+, +plaintext+ # # == Options # # === :separator # A separator string to join the tokens. # # Default: empty String class Text < Encoder register_for :text FILE_EXTENSION = 'txt' DEFAULT_OPTIONS = { :separator => nil } def text_token text, kind super if @first @first = false else @out << @sep end if @sep end protected def setup options super @first = true @sep = options[:separator] end end end end coderay-1.1.1/lib/coderay/encoders/json.rb0000644000004100000410000000344712663664402020505 0ustar www-datawww-datamodule CodeRay module Encoders # A simple JSON Encoder. # # Example: # CodeRay.scan('puts "Hello world!"', :ruby).json # yields # [ # {"type"=>"text", "text"=>"puts", "kind"=>"ident"}, # {"type"=>"text", "text"=>" ", "kind"=>"space"}, # {"type"=>"block", "action"=>"open", "kind"=>"string"}, # {"type"=>"text", "text"=>"\"", "kind"=>"delimiter"}, # {"type"=>"text", "text"=>"Hello world!", "kind"=>"content"}, # {"type"=>"text", "text"=>"\"", "kind"=>"delimiter"}, # {"type"=>"block", "action"=>"close", "kind"=>"string"}, # ] class JSON < Encoder begin require 'json' rescue LoadError begin require 'rubygems' unless defined? Gem gem 'json' require 'json' rescue LoadError $stderr.puts "The JSON encoder needs the JSON library.\n" \ "Please gem install json." raise end end register_for :json FILE_EXTENSION = 'json' protected def setup options super @first = true @out << '[' end def finish options @out << ']' end def append data if @first @first = false else @out << ',' end @out << data.to_json end public def text_token text, kind append :type => 'text', :text => text, :kind => kind end def begin_group kind append :type => 'block', :action => 'open', :kind => kind end def end_group kind append :type => 'block', :action => 'close', :kind => kind end def begin_line kind append :type => 'block', :action => 'begin_line', :kind => kind end def end_line kind append :type => 'block', :action => 'end_line', :kind => kind end end end end coderay-1.1.1/lib/coderay/encoders/span.rb0000644000004100000410000000065712663664402020475 0ustar www-datawww-datamodule CodeRay module Encoders load :html # Wraps HTML output into a SPAN element, using inline styles by default. # # See Encoders::HTML for available options. class Span < HTML FILE_EXTENSION = 'span.html' register_for :span DEFAULT_OPTIONS = HTML::DEFAULT_OPTIONS.merge \ :css => :style, :wrap => :span, :line_numbers => false end end end coderay-1.1.1/lib/coderay/encoders/terminal.rb0000644000004100000410000001171612663664402021345 0ustar www-datawww-datamodule CodeRay module Encoders # Outputs code highlighted for a color terminal. # # Note: This encoder is in beta. It currently doesn't use the Styles. # # Alias: +term+ # # == Authors & License # # By Rob Aldred (http://robaldred.co.uk) # # Based on idea by Nathan Weizenbaum (http://nex-3.com) # # MIT License (http://www.opensource.org/licenses/mit-license.php) class Terminal < Encoder register_for :terminal TOKEN_COLORS = { :debug => "\e[1;37;44m", :annotation => "\e[34m", :attribute_name => "\e[35m", :attribute_value => "\e[31m", :binary => { :self => "\e[31m", :char => "\e[1;31m", :delimiter => "\e[1;31m", }, :char => { :self => "\e[35m", :delimiter => "\e[1;35m" }, :class => "\e[1;35;4m", :class_variable => "\e[36m", :color => "\e[32m", :comment => { :self => "\e[1;30m", :char => "\e[37m", :delimiter => "\e[37m", }, :constant => "\e[1;34;4m", :decorator => "\e[35m", :definition => "\e[1;33m", :directive => "\e[33m", :docstring => "\e[31m", :doctype => "\e[1;34m", :done => "\e[1;30;2m", :entity => "\e[31m", :error => "\e[1;37;41m", :exception => "\e[1;31m", :float => "\e[1;35m", :function => "\e[1;34m", :global_variable => "\e[1;32m", :hex => "\e[1;36m", :id => "\e[1;34m", :include => "\e[31m", :integer => "\e[1;34m", :imaginary => "\e[1;34m", :important => "\e[1;31m", :key => { :self => "\e[35m", :char => "\e[1;35m", :delimiter => "\e[1;35m", }, :keyword => "\e[32m", :label => "\e[1;33m", :local_variable => "\e[33m", :namespace => "\e[1;35m", :octal => "\e[1;34m", :predefined => "\e[36m", :predefined_constant => "\e[1;36m", :predefined_type => "\e[1;32m", :preprocessor => "\e[1;36m", :pseudo_class => "\e[1;34m", :regexp => { :self => "\e[35m", :delimiter => "\e[1;35m", :modifier => "\e[35m", :char => "\e[1;35m", }, :reserved => "\e[32m", :shell => { :self => "\e[33m", :char => "\e[1;33m", :delimiter => "\e[1;33m", :escape => "\e[1;33m", }, :string => { :self => "\e[31m", :modifier => "\e[1;31m", :char => "\e[1;35m", :delimiter => "\e[1;31m", :escape => "\e[1;31m", }, :symbol => { :self => "\e[33m", :delimiter => "\e[1;33m", }, :tag => "\e[32m", :type => "\e[1;34m", :value => "\e[36m", :variable => "\e[34m", :insert => { :self => "\e[42m", :insert => "\e[1;32;42m", :eyecatcher => "\e[102m", }, :delete => { :self => "\e[41m", :delete => "\e[1;31;41m", :eyecatcher => "\e[101m", }, :change => { :self => "\e[44m", :change => "\e[37;44m", }, :head => { :self => "\e[45m", :filename => "\e[37;45m" }, } TOKEN_COLORS[:keyword] = TOKEN_COLORS[:reserved] TOKEN_COLORS[:method] = TOKEN_COLORS[:function] TOKEN_COLORS[:escape] = TOKEN_COLORS[:delimiter] protected def setup(options) super @opened = [] @color_scopes = [TOKEN_COLORS] end public def text_token text, kind if color = @color_scopes.last[kind] color = color[:self] if color.is_a? Hash @out << color @out << (text.index("\n") ? text.gsub("\n", "\e[0m\n" + color) : text) @out << "\e[0m" if outer_color = @color_scopes.last[:self] @out << outer_color end else @out << text end end def begin_group kind @opened << kind @out << open_token(kind) end alias begin_line begin_group def end_group kind if @opened.pop @color_scopes.pop @out << "\e[0m" if outer_color = @color_scopes.last[:self] @out << outer_color end end end def end_line kind @out << (@line_filler ||= "\t" * 100) end_group kind end private def open_token kind if color = @color_scopes.last[kind] if color.is_a? Hash @color_scopes << color color[:self] else @color_scopes << @color_scopes.last color end else @color_scopes << @color_scopes.last '' end end end end end coderay-1.1.1/lib/coderay/encoders/_map.rb0000644000004100000410000000062212663664402020440 0ustar www-datawww-datamodule CodeRay module Encoders map \ :loc => :lines_of_code, :plain => :text, :plaintext => :text, :remove_comments => :comment_filter, :stats => :statistic, :term => :terminal, :tty => :terminal, :yml => :yaml # No default because Tokens#nonsense should raise NoMethodError. end end coderay-1.1.1/lib/coderay/encoders/count.rb0000644000004100000410000000105612663664402020656 0ustar www-datawww-datamodule CodeRay module Encoders # Returns the number of tokens. # # Text and block tokens are counted. class Count < Encoder register_for :count protected def setup options super @count = 0 end def finish options output @count end public def text_token text, kind @count += 1 end def begin_group kind @count += 1 end alias end_group begin_group alias begin_line begin_group alias end_line begin_group end end end coderay-1.1.1/lib/coderay/encoders/debug.rb0000644000004100000410000000165312663664402020617 0ustar www-datawww-datamodule CodeRay module Encoders # = Debug Encoder # # Fast encoder producing simple debug output. # # It is readable and diff-able and is used for testing. # # You cannot fully restore the tokens information from the # output, because consecutive :space tokens are merged. # # See also: Scanners::Debug class Debug < Encoder register_for :debug FILE_EXTENSION = 'raydebug' def text_token text, kind if kind == :space @out << text else text = text.gsub('\\', '\\\\\\\\') if text.index('\\') text = text.gsub(')', '\\\\)') if text.index(')') @out << "#{kind}(#{text})" end end def begin_group kind @out << "#{kind}<" end def end_group kind @out << '>' end def begin_line kind @out << "#{kind}[" end def end_line kind @out << ']' end end end end coderay-1.1.1/lib/coderay/encoders/filter.rb0000644000004100000410000000204512663664402021012 0ustar www-datawww-datamodule CodeRay module Encoders # A Filter encoder has another Tokens instance as output. # It can be subclass to select, remove, or modify tokens in the stream. # # Subclasses of Filter are called "Filters" and can be chained. # # == Options # # === :tokens # # The Tokens object which will receive the output. # # Default: Tokens.new # # See also: TokenKindFilter class Filter < Encoder register_for :filter protected def setup options super @tokens = options[:tokens] || Tokens.new end def finish options output @tokens end public def text_token text, kind # :nodoc: @tokens.text_token text, kind end def begin_group kind # :nodoc: @tokens.begin_group kind end def begin_line kind # :nodoc: @tokens.begin_line kind end def end_group kind # :nodoc: @tokens.end_group kind end def end_line kind # :nodoc: @tokens.end_line kind end end end end coderay-1.1.1/lib/coderay/encoders/token_kind_filter.rb0000644000004100000410000000462712663664402023227 0ustar www-datawww-datamodule CodeRay module Encoders load :filter # A Filter that selects tokens based on their token kind. # # == Options # # === :exclude # # One or many symbols (in an Array) which shall be excluded. # # Default: [] # # === :include # # One or many symbols (in an array) which shall be included. # # Default: :all, which means all tokens are included. # # Exclusion wins over inclusion. # # See also: CommentFilter class TokenKindFilter < Filter register_for :token_kind_filter DEFAULT_OPTIONS = { :exclude => [], :include => :all } protected def setup options super @group_excluded = false @exclude = options[:exclude] @exclude = Array(@exclude) unless @exclude == :all @include = options[:include] @include = Array(@include) unless @include == :all end def include_text_token? text, kind include_group? kind end def include_group? kind (@include == :all || @include.include?(kind)) && !(@exclude == :all || @exclude.include?(kind)) end public # Add the token to the output stream if +kind+ matches the conditions. def text_token text, kind super if !@group_excluded && include_text_token?(text, kind) end # Add the token group to the output stream if +kind+ matches the # conditions. # # If it does not, all tokens inside the group are excluded from the # stream, even if their kinds match. def begin_group kind if @group_excluded @group_excluded += 1 elsif include_group? kind super else @group_excluded = 1 end end # See +begin_group+. def begin_line kind if @group_excluded @group_excluded += 1 elsif include_group? kind super else @group_excluded = 1 end end # Take care of re-enabling the delegation of tokens to the output stream # if an exluded group has ended. def end_group kind if @group_excluded @group_excluded -= 1 @group_excluded = false if @group_excluded.zero? else super end end # See +end_group+. def end_line kind if @group_excluded @group_excluded -= 1 @group_excluded = false if @group_excluded.zero? else super end end end end end coderay-1.1.1/lib/coderay/encoders/page.rb0000644000004100000410000000071612663664402020444 0ustar www-datawww-datamodule CodeRay module Encoders load :html # Wraps the output into a HTML page, using CSS classes and # line numbers in the table format by default. # # See Encoders::HTML for available options. class Page < HTML FILE_EXTENSION = 'html' register_for :page DEFAULT_OPTIONS = HTML::DEFAULT_OPTIONS.merge \ :css => :class, :wrap => :page, :line_numbers => :table end end end coderay-1.1.1/lib/coderay/encoders/lint.rb0000644000004100000410000000300512663664402020470 0ustar www-datawww-datamodule CodeRay module Encoders # = Lint Encoder # # Checks for: # # - empty tokens # - incorrect nesting # # It will raise an InvalidTokenStream exception when any of the above occurs. # # See also: Encoders::DebugLint class Lint < Debug register_for :lint InvalidTokenStream = Class.new StandardError EmptyToken = Class.new InvalidTokenStream UnknownTokenKind = Class.new InvalidTokenStream IncorrectTokenGroupNesting = Class.new InvalidTokenStream def text_token text, kind raise EmptyToken, 'empty token for %p' % [kind] if text.empty? raise UnknownTokenKind, 'unknown token kind %p (text was %p)' % [kind, text] unless TokenKinds.has_key? kind end def begin_group kind @opened << kind end def end_group kind raise IncorrectTokenGroupNesting, 'We are inside %s, not %p (end_group)' % [@opened.reverse.map(&:inspect).join(' < '), kind] if @opened.last != kind @opened.pop end def begin_line kind @opened << kind end def end_line kind raise IncorrectTokenGroupNesting, 'We are inside %s, not %p (end_line)' % [@opened.reverse.map(&:inspect).join(' < '), kind] if @opened.last != kind @opened.pop end protected def setup options @opened = [] end def finish options raise 'Some tokens still open at end of token stream: %p' % [@opened] unless @opened.empty? end end end end coderay-1.1.1/lib/coderay/encoders/statistic.rb0000644000004100000410000000407512663664402021541 0ustar www-datawww-datamodule CodeRay module Encoders # Makes a statistic for the given tokens. # # Alias: +stats+ class Statistic < Encoder register_for :statistic attr_reader :type_stats, :real_token_count # :nodoc: TypeStats = Struct.new :count, :size # :nodoc: protected def setup options super @type_stats = Hash.new { |h, k| h[k] = TypeStats.new 0, 0 } @real_token_count = 0 end STATS = <<-STATS # :nodoc: Code Statistics Tokens %8d Non-Whitespace %8d Bytes Total %8d Token Types (%d): type count ratio size (average) ------------------------------------------------------------- %s STATS TOKEN_TYPES_ROW = <<-TKR # :nodoc: %-20s %8d %6.2f %% %5.1f TKR def finish options all = @type_stats['TOTAL'] all_count, all_size = all.count, all.size @type_stats.each do |type, stat| stat.size /= stat.count.to_f end types_stats = @type_stats.sort_by { |k, v| [-v.count, k.to_s] }.map do |k, v| TOKEN_TYPES_ROW % [k, v.count, 100.0 * v.count / all_count, v.size] end.join @out << STATS % [ all_count, @real_token_count, all_size, @type_stats.delete_if { |k, v| k.is_a? String }.size, types_stats ] super end public def text_token text, kind @real_token_count += 1 unless kind == :space @type_stats[kind].count += 1 @type_stats[kind].size += text.size @type_stats['TOTAL'].size += text.size @type_stats['TOTAL'].count += 1 end def begin_group kind block_token ':begin_group', kind end def end_group kind block_token ':end_group', kind end def begin_line kind block_token ':begin_line', kind end def end_line kind block_token ':end_line', kind end def block_token action, kind @type_stats['TOTAL'].count += 1 @type_stats[action].count += 1 @type_stats[kind].count += 1 end end end end coderay-1.1.1/lib/coderay/encoders/null.rb0000644000004100000410000000035612663664402020502 0ustar www-datawww-datamodule CodeRay module Encoders # = Null Encoder # # Does nothing and returns an empty string. class Null < Encoder register_for :null def text_token text, kind # do nothing end end end end coderay-1.1.1/lib/coderay/encoders/lines_of_code.rb0000644000004100000410000000215112663664402022313 0ustar www-datawww-datamodule CodeRay module Encoders # Counts the LoC (Lines of Code). Returns an Integer >= 0. # # Alias: +loc+ # # Everything that is not comment, markup, doctype/shebang, or an empty line, # is considered to be code. # # For example, # * HTML files not containing JavaScript have 0 LoC # * in a Java class without comments, LoC is the number of non-empty lines # # A Scanner class should define the token kinds that are not code in the # KINDS_NOT_LOC constant, which defaults to [:comment, :doctype]. class LinesOfCode < TokenKindFilter register_for :lines_of_code NON_EMPTY_LINE = /^\s*\S.*$/ protected def setup options if scanner kinds_not_loc = scanner.class::KINDS_NOT_LOC else warn "Tokens have no associated scanner, counting all nonempty lines." if $VERBOSE kinds_not_loc = CodeRay::Scanners::Scanner::KINDS_NOT_LOC end options[:exclude] = kinds_not_loc super options end def finish options output @tokens.text.scan(NON_EMPTY_LINE).size end end end end coderay-1.1.1/lib/coderay/encoders/html.rb0000644000004100000410000002177112663664402020500 0ustar www-datawww-datarequire 'set' module CodeRay module Encoders # = HTML Encoder # # This is CodeRay's most important highlighter: # It provides save, fast XHTML generation and CSS support. # # == Usage # # require 'coderay' # puts CodeRay.scan('Some /code/', :ruby).html #-> a HTML page # puts CodeRay.scan('Some /code/', :ruby).html(:wrap => :span) # #-> Some /code/ # puts CodeRay.scan('Some /code/', :ruby).span #-> the same # # puts CodeRay.scan('Some code', :ruby).html( # :wrap => nil, # :line_numbers => :inline, # :css => :style # ) # # == Options # # === :tab_width # Convert \t characters to +n+ spaces (a number or false.) # false will keep tab characters untouched. # # Default: 8 # # === :css # How to include the styles; can be :class or :style. # # Default: :class # # === :wrap # Wrap in :page, :div, :span or nil. # # You can also use Encoders::Div and Encoders::Span. # # Default: nil # # === :title # # The title of the HTML page (works only when :wrap is set to :page.) # # Default: 'CodeRay output' # # === :break_lines # # Split multiline blocks at line breaks. # Forced to true if :line_numbers option is set to :inline. # # Default: false # # === :line_numbers # Include line numbers in :table, :inline, or nil (no line numbers) # # Default: nil # # === :line_number_anchors # Adds anchors and links to the line numbers. Can be false (off), true (on), # or a prefix string that will be prepended to the anchor name. # # The prefix must consist only of letters, digits, and underscores. # # Default: true, default prefix name: "line" # # === :line_number_start # Where to start with line number counting. # # Default: 1 # # === :bold_every # Make every +n+-th number appear bold. # # Default: 10 # # === :highlight_lines # # Highlights certain line numbers. # Can be any Enumerable, typically just an Array or Range, of numbers. # # Bolding is deactivated when :highlight_lines is set. It only makes sense # in combination with :line_numbers. # # Default: nil # # === :hint # Include some information into the output using the title attribute. # Can be :info (show token kind on mouse-over), :info_long (with full path) # or :debug (via inspect). # # Default: false class HTML < Encoder register_for :html FILE_EXTENSION = 'snippet.html' DEFAULT_OPTIONS = { :tab_width => 8, :css => :class, :style => :alpha, :wrap => nil, :title => 'CodeRay output', :break_lines => false, :line_numbers => nil, :line_number_anchors => 'n', :line_number_start => 1, :bold_every => 10, :highlight_lines => nil, :hint => false, } autoload :Output, CodeRay.coderay_path('encoders', 'html', 'output') autoload :CSS, CodeRay.coderay_path('encoders', 'html', 'css') autoload :Numbering, CodeRay.coderay_path('encoders', 'html', 'numbering') attr_reader :css protected def self.make_html_escape_hash { '&' => '&', '"' => '"', '>' => '>', '<' => '<', # "\t" => will be set to ' ' * options[:tab_width] during setup }.tap do |hash| # Escape ASCII control codes except \x9 == \t and \xA == \n. (Array(0x00..0x8) + Array(0xB..0x1F)).each { |invalid| hash[invalid.chr] = ' ' } end end HTML_ESCAPE = make_html_escape_hash HTML_ESCAPE_PATTERN = /[\t"&><\0-\x8\xB-\x1F]/ TOKEN_KIND_TO_INFO = Hash.new do |h, kind| h[kind] = kind.to_s.gsub(/_/, ' ').gsub(/\b\w/) { $&.capitalize } end TRANSPARENT_TOKEN_KINDS = Set[ :delimiter, :modifier, :content, :escape, :inline_delimiter, ] # Generate a hint about the given +kinds+ in a +hint+ style. # # +hint+ may be :info, :info_long or :debug. def self.token_path_to_hint hint, kinds kinds = Array kinds title = case hint when :info kinds = kinds[1..-1] if TRANSPARENT_TOKEN_KINDS.include? kinds.first TOKEN_KIND_TO_INFO[kinds.first] when :info_long kinds.reverse.map { |kind| TOKEN_KIND_TO_INFO[kind] }.join('/') when :debug kinds.inspect end title ? " title=\"#{title}\"" : '' end def setup options super check_options! options if options[:wrap] || options[:line_numbers] @real_out = @out @out = '' end @break_lines = (options[:break_lines] == true) @HTML_ESCAPE = HTML_ESCAPE.merge("\t" => options[:tab_width] ? ' ' * options[:tab_width] : "\t") @opened = [] @last_opened = nil @css = CSS.new options[:style] @span_for_kinds = make_span_for_kinds(options[:css], options[:hint]) @set_last_opened = options[:hint] || options[:css] == :style end def finish options unless @opened.empty? @out << '' while @opened.pop @last_opened = nil end if @out.respond_to? :to_str @out.extend Output @out.css = @css if options[:line_numbers] Numbering.number! @out, options[:line_numbers], options end @out.wrap! options[:wrap] @out.apply_title! options[:title] end if defined?(@real_out) && @real_out @real_out << @out @out = @real_out end super end public def text_token text, kind style = @span_for_kinds[@last_opened ? [kind, *@opened] : kind] text = text.gsub(/#{HTML_ESCAPE_PATTERN}/o) { |m| @HTML_ESCAPE[m] } if text =~ /#{HTML_ESCAPE_PATTERN}/o text = break_lines(text, style) if @break_lines && (style || @opened.size > 0) && text.index("\n") if style @out << style << text << '' else @out << text end end # token groups, eg. strings def begin_group kind @out << (@span_for_kinds[@last_opened ? [kind, *@opened] : kind] || '') @opened << kind @last_opened = kind if @set_last_opened end def end_group kind check_group_nesting 'token group', kind if $CODERAY_DEBUG close_span end # whole lines to be highlighted, eg. a deleted line in a diff def begin_line kind if style = @span_for_kinds[@last_opened ? [kind, *@opened] : kind] if style['class="'] @out << style.sub('class="', 'class="line ') else @out << style.sub('>', ' class="line">') end else @out << '' end @opened << kind @last_opened = kind if @options[:css] == :style end def end_line kind check_group_nesting 'line', kind if $CODERAY_DEBUG close_span end protected def check_options! options unless [false, nil, :debug, :info, :info_long].include? options[:hint] raise ArgumentError, "Unknown value %p for :hint; expected :info, :info_long, :debug, false, or nil." % [options[:hint]] end unless [:class, :style].include? options[:css] raise ArgumentError, 'Unknown value %p for :css.' % [options[:css]] end options[:break_lines] = true if options[:line_numbers] == :inline end def css_class_for_kinds kinds TokenKinds[kinds.is_a?(Symbol) ? kinds : kinds.first] end def style_for_kinds kinds css_classes = kinds.is_a?(Array) ? kinds.map { |c| TokenKinds[c] } : [TokenKinds[kinds]] @css.get_style_for_css_classes css_classes end def make_span_for_kinds method, hint Hash.new do |h, kinds| begin css_class = css_class_for_kinds(kinds) title = HTML.token_path_to_hint hint, kinds if hint if css_class || title if method == :style style = style_for_kinds(kinds) "" else "" end end end.tap do |span| h.clear if h.size >= 100 h[kinds] = span end end end def check_group_nesting name, kind if @opened.empty? || @opened.last != kind warn "Malformed token stream: Trying to close a #{name} (%p) that is not open. Open are: %p." % [kind, @opened[1..-1]] end end def break_lines text, style reopen = '' @opened.each_with_index do |kind, index| reopen << (@span_for_kinds[index > 0 ? [kind, *@opened[0...index]] : kind] || '') end text.gsub("\n", "#{'' * @opened.size}#{'' if style}\n#{reopen}#{style}") end def close_span if @opened.pop @out << '' @last_opened = @opened.last if @last_opened end end end end end coderay-1.1.1/lib/coderay/token_kinds.rb0000755000004100000410000001214712663664402020242 0ustar www-datawww-datamodule CodeRay # A Hash of all known token kinds and their associated CSS classes. TokenKinds = Hash.new(false) # speedup TokenKinds.compare_by_identity if TokenKinds.respond_to? :compare_by_identity TokenKinds.update( # :nodoc: :debug => 'debug', # highlight for debugging (white on blue background) :annotation => 'annotation', # Groovy, Java :attribute_name => 'attribute-name', # HTML, CSS :attribute_value => 'attribute-value', # HTML :binary => 'binary', # Python, Ruby :char => 'char', # most scanners, also inside of strings :class => 'class', # lots of scanners, for different purposes also in CSS :class_variable => 'class-variable', # Ruby, YAML :color => 'color', # CSS :comment => 'comment', # most scanners :constant => 'constant', # PHP, Ruby :content => 'content', # inside of strings, most scanners :decorator => 'decorator', # Python :definition => 'definition', # CSS :delimiter => 'delimiter', # inside strings, comments and other types :directive => 'directive', # lots of scanners :doctype => 'doctype', # Goorvy, HTML, Ruby, YAML :docstring => 'docstring', # Python :done => 'done', # Taskpaper :entity => 'entity', # HTML :error => 'error', # invalid token, most scanners :escape => 'escape', # Ruby (string inline variables like #$foo, #@bar) :exception => 'exception', # Java, PHP, Python :filename => 'filename', # Diff :float => 'float', # most scanners :function => 'function', # CSS, JavaScript, PHP :global_variable => 'global-variable', # Ruby, YAML :hex => 'hex', # hexadecimal number; lots of scanners :id => 'id', # CSS :imaginary => 'imaginary', # Python :important => 'important', # CSS, Taskpaper :include => 'include', # C, Groovy, Java, Python, Sass :inline => 'inline', # nested code, eg. inline string evaluation; lots of scanners :inline_delimiter => 'inline-delimiter', # used instead of :inline > :delimiter FIXME: Why use inline_delimiter? :instance_variable => 'instance-variable', # Ruby :integer => 'integer', # most scanners :key => 'key', # lots of scanners, used together with :value :keyword => 'keyword', # reserved word that's actually implemented; most scanners :label => 'label', # C, PHP :local_variable => 'local-variable', # local and magic variables; some scanners :map => 'map', # Lua tables :modifier => 'modifier', # used inside on strings; lots of scanners :namespace => 'namespace', # Clojure, Java, Taskpaper :octal => 'octal', # lots of scanners :predefined => 'predefined', # predefined function: lots of scanners :predefined_constant => 'predefined-constant',# lots of scanners :predefined_type => 'predefined-type', # C, Java, PHP :preprocessor => 'preprocessor', # C, Delphi, HTML :pseudo_class => 'pseudo-class', # CSS :regexp => 'regexp', # Groovy, JavaScript, Ruby :reserved => 'reserved', # most scanners :shell => 'shell', # Ruby :string => 'string', # most scanners :symbol => 'symbol', # Clojure, Ruby, YAML :tag => 'tag', # CSS, HTML :type => 'type', # CSS, Java, SQL, YAML :value => 'value', # used together with :key; CSS, JSON, YAML :variable => 'variable', # Sass, SQL, YAML :change => 'change', # Diff :delete => 'delete', # Diff :head => 'head', # Diff, YAML :insert => 'insert', # Diff :eyecatcher => 'eyecatcher', # Diff :ident => false, # almost all scanners :operator => false, # almost all scanners :space => false, # almost all scanners :plain => false # almost all scanners ) TokenKinds[:method] = TokenKinds[:function] TokenKinds[:unknown] = TokenKinds[:plain] end coderay-1.1.1/lib/coderay/styles/0000755000004100000410000000000012663664402016720 5ustar www-datawww-datacoderay-1.1.1/lib/coderay/styles/style.rb0000644000004100000410000000042312663664402020404 0ustar www-datawww-datamodule CodeRay module Styles # Base class for styles. # # Styles are used by Encoders::HTML to colorize tokens. class Style extend Plugin plugin_host Styles DEFAULT_OPTIONS = { } # :nodoc: end end end coderay-1.1.1/lib/coderay/styles/_map.rb0000644000004100000410000000007412663664402020162 0ustar www-datawww-datamodule CodeRay module Styles default :alpha end end coderay-1.1.1/lib/coderay/styles/alpha.rb0000644000004100000410000001164712663664402020343 0ustar www-datawww-datamodule CodeRay module Styles # A colorful theme using CSS 3 colors (with alpha channel). class Alpha < Style register_for :alpha code_background = 'hsl(0,0%,95%)' numbers_background = 'hsl(180,65%,90%)' border_color = 'silver' normal_color = 'black' CSS_MAIN_STYLES = <<-MAIN # :nodoc: .CodeRay { background-color: #{code_background}; border: 1px solid #{border_color}; color: #{normal_color}; } .CodeRay pre { margin: 0px; } span.CodeRay { white-space: pre; border: 0px; padding: 2px; } table.CodeRay { border-collapse: collapse; width: 100%; padding: 2px; } table.CodeRay td { padding: 2px 4px; vertical-align: top; } .CodeRay .line-numbers { background-color: #{numbers_background}; color: gray; text-align: right; -webkit-user-select: none; -moz-user-select: none; user-select: none; } .CodeRay .line-numbers a { background-color: #{numbers_background} !important; color: gray !important; text-decoration: none !important; } .CodeRay .line-numbers pre { word-break: normal; } .CodeRay .line-numbers a:target { color: blue !important; } .CodeRay .line-numbers .highlighted { color: red !important; } .CodeRay .line-numbers .highlighted a { color: red !important; } .CodeRay span.line-numbers { padding: 0px 4px; } .CodeRay .line { display: block; float: left; width: 100%; } .CodeRay .code { width: 100%; } MAIN TOKEN_COLORS = <<-'TOKENS' .debug { color: white !important; background: blue !important; } .annotation { color:#007 } .attribute-name { color:#b48 } .attribute-value { color:#700 } .binary { color:#549 } .binary .char { color:#325 } .binary .delimiter { color:#325 } .char { color:#D20 } .char .content { color:#D20 } .char .delimiter { color:#710 } .class { color:#B06; font-weight:bold } .class-variable { color:#369 } .color { color:#0A0 } .comment { color:#777 } .comment .char { color:#444 } .comment .delimiter { color:#444 } .constant { color:#036; font-weight:bold } .decorator { color:#B0B } .definition { color:#099; font-weight:bold } .delimiter { color:black } .directive { color:#088; font-weight:bold } .docstring { color:#D42; } .doctype { color:#34b } .done { text-decoration: line-through; color: gray } .entity { color:#800; font-weight:bold } .error { color:#F00; background-color:#FAA } .escape { color:#666 } .exception { color:#C00; font-weight:bold } .float { color:#60E } .function { color:#06B; font-weight:bold } .function .delimiter { color:#059 } .function .content { color:#037 } .global-variable { color:#d70 } .hex { color:#02b } .id { color:#33D; font-weight:bold } .include { color:#B44; font-weight:bold } .inline { background-color: hsla(0,0%,0%,0.07); color: black } .inline-delimiter { font-weight: bold; color: #666 } .instance-variable { color:#33B } .integer { color:#00D } .imaginary { color:#f00 } .important { color:#D00 } .key { color: #606 } .key .char { color: #60f } .key .delimiter { color: #404 } .keyword { color:#080; font-weight:bold } .label { color:#970; font-weight:bold } .local-variable { color:#950 } .map .content { color:#808 } .map .delimiter { color:#40A} .map { background-color:hsla(200,100%,50%,0.06); } .namespace { color:#707; font-weight:bold } .octal { color:#40E } .operator { } .predefined { color:#369; font-weight:bold } .predefined-constant { color:#069 } .predefined-type { color:#0a8; font-weight:bold } .preprocessor { color:#579 } .pseudo-class { color:#00C; font-weight:bold } .regexp { background-color:hsla(300,100%,50%,0.06); } .regexp .content { color:#808 } .regexp .delimiter { color:#404 } .regexp .modifier { color:#C2C } .reserved { color:#080; font-weight:bold } .shell { background-color:hsla(120,100%,50%,0.06); } .shell .content { color:#2B2 } .shell .delimiter { color:#161 } .string { background-color:hsla(0,100%,50%,0.05); } .string .char { color: #b0b } .string .content { color: #D20 } .string .delimiter { color: #710 } .string .modifier { color: #E40 } .symbol { color:#A60 } .symbol .content { color:#A60 } .symbol .delimiter { color:#740 } .tag { color:#070; font-weight:bold } .type { color:#339; font-weight:bold } .value { color: #088 } .variable { color:#037 } .insert { background: hsla(120,100%,50%,0.12) } .delete { background: hsla(0,100%,50%,0.12) } .change { color: #bbf; background: #007 } .head { color: #f8f; background: #505 } .head .filename { color: white; } .delete .eyecatcher { background-color: hsla(0,100%,50%,0.2); border: 1px solid hsla(0,100%,45%,0.5); margin: -1px; border-bottom: none; border-top-left-radius: 5px; border-top-right-radius: 5px; } .insert .eyecatcher { background-color: hsla(120,100%,50%,0.2); border: 1px solid hsla(120,100%,25%,0.5); margin: -1px; border-top: none; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; } .insert .insert { color: #0c0; background:transparent; font-weight:bold } .delete .delete { color: #c00; background:transparent; font-weight:bold } .change .change { color: #88f } .head .head { color: #f4f } TOKENS end end end coderay-1.1.1/lib/coderay/scanners/0000755000004100000410000000000012663664402017211 5ustar www-datawww-datacoderay-1.1.1/lib/coderay/scanners/diff.rb0000644000004100000410000001772112663664402020456 0ustar www-datawww-datamodule CodeRay module Scanners # Scanner for output of the diff command. # # Alias: +patch+ class Diff < Scanner register_for :diff title 'diff output' DEFAULT_OPTIONS = { :highlight_code => true, :inline_diff => true, } protected def scan_tokens encoder, options line_kind = nil state = :initial deleted_lines_count = 0 scanners = Hash.new do |h, lang| h[lang] = Scanners[lang].new '', :keep_tokens => true, :keep_state => true end content_scanner = scanners[:plain] content_scanner_entry_state = nil until eos? if match = scan(/\n/) deleted_lines_count = 0 unless line_kind == :delete if line_kind encoder.end_line line_kind line_kind = nil end encoder.text_token match, :space next end case state when :initial if match = scan(/--- |\+\+\+ |=+|_+/) encoder.begin_line line_kind = :head encoder.text_token match, :head if match = scan(/[^\x00\n]+?(?=$|[\t\n]| \(revision)/) encoder.text_token match, :filename if options[:highlight_code] && match != '/dev/null' file_type = CodeRay::FileType.fetch(match, :text) file_type = :text if file_type == :diff content_scanner = scanners[file_type] content_scanner_entry_state = nil end end next unless match = scan(/.+/) encoder.text_token match, :plain elsif match = scan(/Index: |Property changes on: /) encoder.begin_line line_kind = :head encoder.text_token match, :head next unless match = scan(/.+/) encoder.text_token match, :plain elsif match = scan(/Added: /) encoder.begin_line line_kind = :head encoder.text_token match, :head next unless match = scan(/.+/) encoder.text_token match, :plain state = :added elsif match = scan(/\\ .*/) encoder.text_token match, :comment elsif match = scan(/@@(?>[^@\n]+)@@/) content_scanner.state = :initial unless match?(/\n\+/) content_scanner_entry_state = nil if check(/\n|$/) encoder.begin_line line_kind = :change else encoder.begin_group :change end encoder.text_token match[0,2], :change encoder.text_token match[2...-2], :plain encoder.text_token match[-2,2], :change encoder.end_group :change unless line_kind next unless match = scan(/.+/) if options[:highlight_code] content_scanner.tokenize match, :tokens => encoder else encoder.text_token match, :plain end next elsif match = scan(/\+/) encoder.begin_line line_kind = :insert encoder.text_token match, :insert next unless match = scan(/.+/) if options[:highlight_code] content_scanner.tokenize match, :tokens => encoder else encoder.text_token match, :plain end next elsif match = scan(/-/) deleted_lines_count += 1 if options[:inline_diff] && deleted_lines_count == 1 && (changed_lines_count = 1 + check(/.*(?:\n\-.*)*/).count("\n")) && changed_lines_count <= 100_000 && match?(/(?>.*(?:\n\-.*){#{changed_lines_count - 1}}(?:\n\+.*){#{changed_lines_count}})$(?!\n\+)/) deleted_lines = Array.new(changed_lines_count) { |i| skip(/\n\-/) if i > 0; scan(/.*/) } inserted_lines = Array.new(changed_lines_count) { |i| skip(/\n\+/) ; scan(/.*/) } deleted_lines_tokenized = [] inserted_lines_tokenized = [] for deleted_line, inserted_line in deleted_lines.zip(inserted_lines) pre, deleted_part, inserted_part, post = diff deleted_line, inserted_line content_scanner_entry_state = content_scanner.state deleted_lines_tokenized << content_scanner.tokenize([pre, deleted_part, post], :tokens => Tokens.new) content_scanner.state = content_scanner_entry_state || :initial inserted_lines_tokenized << content_scanner.tokenize([pre, inserted_part, post], :tokens => Tokens.new) end for pre, deleted_part, post in deleted_lines_tokenized encoder.begin_line :delete encoder.text_token '-', :delete encoder.tokens pre unless deleted_part.empty? encoder.begin_group :eyecatcher encoder.tokens deleted_part encoder.end_group :eyecatcher end encoder.tokens post encoder.end_line :delete encoder.text_token "\n", :space end for pre, inserted_part, post in inserted_lines_tokenized encoder.begin_line :insert encoder.text_token '+', :insert encoder.tokens pre unless inserted_part.empty? encoder.begin_group :eyecatcher encoder.tokens inserted_part encoder.end_group :eyecatcher end encoder.tokens post changed_lines_count -= 1 if changed_lines_count > 0 encoder.end_line :insert encoder.text_token "\n", :space end end line_kind = :insert elsif match = scan(/.*/) encoder.begin_line line_kind = :delete encoder.text_token '-', :delete if options[:highlight_code] if deleted_lines_count == 1 content_scanner_entry_state = content_scanner.state end content_scanner.tokenize match, :tokens => encoder unless match.empty? if !match?(/\n-/) if match?(/\n\+/) content_scanner.state = content_scanner_entry_state || :initial end content_scanner_entry_state = nil end else encoder.text_token match, :plain end end next elsif match = scan(/ .*/) if options[:highlight_code] content_scanner.tokenize match, :tokens => encoder else encoder.text_token match, :plain end next elsif match = scan(/.+/) encoder.begin_line line_kind = :comment encoder.text_token match, :plain else raise_inspect 'else case rached' end when :added if match = scan(/ \+/) encoder.begin_line line_kind = :insert encoder.text_token match, :insert next unless match = scan(/.+/) encoder.text_token match, :plain else state = :initial next end end end encoder.end_line line_kind if line_kind encoder end private def diff a, b # i will be the index of the leftmost difference from the left. i_max = [a.size, b.size].min i = 0 i += 1 while i < i_max && a[i] == b[i] # j_min will be the index of the leftmost difference from the right. j_min = i - i_max # j will be the index of the rightmost difference from the right which # does not precede the leftmost one from the left. j = -1 j -= 1 while j >= j_min && a[j] == b[j] return a[0...i], a[i..j], b[i..j], (j < -1) ? a[j+1..-1] : '' end end end end coderay-1.1.1/lib/coderay/scanners/groovy.rb0000644000004100000410000002257012663664402021071 0ustar www-datawww-datamodule CodeRay module Scanners load :java # Scanner for Groovy. class Groovy < Java register_for :groovy # TODO: check list of keywords GROOVY_KEYWORDS = %w[ as assert def in ] # :nodoc: KEYWORDS_EXPECTING_VALUE = WordList.new.add %w[ case instanceof new return throw typeof while as assert in ] # :nodoc: GROOVY_MAGIC_VARIABLES = %w[ it ] # :nodoc: IDENT_KIND = Java::IDENT_KIND.dup. add(GROOVY_KEYWORDS, :keyword). add(GROOVY_MAGIC_VARIABLES, :local_variable) # :nodoc: ESCAPE = / [bfnrtv$\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc: UNICODE_ESCAPE = / u[a-fA-F0-9]{4} /x # :nodoc: no 4-byte unicode chars? U[a-fA-F0-9]{8} REGEXP_ESCAPE = / [bfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} | \d | [bBdDsSwW\/] /x # :nodoc: # TODO: interpretation inside ', ", / STRING_CONTENT_PATTERN = { "'" => /(?>\\[^\\'\n]+|[^\\'\n]+)+/, '"' => /[^\\$"\n]+/, "'''" => /(?>[^\\']+|'(?!''))+/, '"""' => /(?>[^\\$"]+|"(?!""))+/, '/' => /[^\\$\/\n]+/, } # :nodoc: protected def setup @state = :initial end def scan_tokens encoder, options state = options[:state] || @state inline_block_stack = [] inline_block_paren_depth = nil string_delimiter = nil import_clause = class_name_follows = last_token = after_def = false value_expected = true until eos? case state when :initial if match = scan(/ \s+ | \\\n /x) encoder.text_token match, :space if match.index ?\n import_clause = after_def = false value_expected = true unless value_expected end next elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx) value_expected = true after_def = false encoder.text_token match, :comment elsif bol? && match = scan(/ \#!.* /x) encoder.text_token match, :doctype elsif import_clause && match = scan(/ (?!as) #{IDENT} (?: \. #{IDENT} )* (?: \.\* )? /ox) after_def = value_expected = false encoder.text_token match, :include elsif match = scan(/ #{IDENT} | \[\] /ox) kind = IDENT_KIND[match] value_expected = (kind == :keyword) && KEYWORDS_EXPECTING_VALUE[match] if last_token == '.' kind = :ident elsif class_name_follows kind = :class class_name_follows = false elsif after_def && check(/\s*[({]/) kind = :method after_def = false elsif kind == :ident && last_token != '?' && check(/:/) kind = :key else class_name_follows = true if match == 'class' || (import_clause && match == 'as') import_clause = match == 'import' after_def = true if match == 'def' end encoder.text_token match, kind elsif match = scan(/;/) import_clause = after_def = false value_expected = true encoder.text_token match, :operator elsif match = scan(/\{/) class_name_follows = after_def = false value_expected = true encoder.text_token match, :operator if !inline_block_stack.empty? inline_block_paren_depth += 1 end # TODO: ~'...', ~"..." and ~/.../ style regexps elsif match = scan(/ \.\.] | \+\+ | && | \|\| | \*\*=? | ==?~ | <=?>? | [-+*%^~&|>=!]=? | <<>>?=? /x) value_expected = true value_expected = :regexp if match == '~' after_def = false encoder.text_token match, :operator elsif match = scan(/ [)\]}] /x) value_expected = after_def = false if !inline_block_stack.empty? && match == '}' inline_block_paren_depth -= 1 if inline_block_paren_depth == 0 # closing brace of inline block reached encoder.text_token match, :inline_delimiter encoder.end_group :inline state, string_delimiter, inline_block_paren_depth = inline_block_stack.pop next end end encoder.text_token match, :operator elsif check(/[\d.]/) after_def = value_expected = false if match = scan(/0[xX][0-9A-Fa-f]+/) encoder.text_token match, :hex elsif match = scan(/(?>0[0-7]+)(?![89.eEfF])/) encoder.text_token match, :octal elsif match = scan(/\d+[fFdD]|\d*\.\d+(?:[eE][+-]?\d+)?[fFdD]?|\d+[eE][+-]?\d+[fFdD]?/) encoder.text_token match, :float elsif match = scan(/\d+[lLgG]?/) encoder.text_token match, :integer end elsif match = scan(/'''|"""/) after_def = value_expected = false state = :multiline_string encoder.begin_group :string string_delimiter = match encoder.text_token match, :delimiter # TODO: record.'name' syntax elsif match = scan(/["']/) after_def = value_expected = false state = match == '/' ? :regexp : :string encoder.begin_group state string_delimiter = match encoder.text_token match, :delimiter elsif value_expected && match = scan(/\//) after_def = value_expected = false encoder.begin_group :regexp state = :regexp string_delimiter = '/' encoder.text_token match, :delimiter elsif match = scan(/ @ #{IDENT} /ox) after_def = value_expected = false encoder.text_token match, :annotation elsif match = scan(/\//) after_def = false value_expected = true encoder.text_token match, :operator else encoder.text_token getch, :error end when :string, :regexp, :multiline_string if match = scan(STRING_CONTENT_PATTERN[string_delimiter]) encoder.text_token match, :content elsif match = scan(state == :multiline_string ? /'''|"""/ : /["'\/]/) encoder.text_token match, :delimiter if state == :regexp # TODO: regexp modifiers? s, m, x, i? modifiers = scan(/[ix]+/) encoder.text_token modifiers, :modifier if modifiers && !modifiers.empty? end state = :string if state == :multiline_string encoder.end_group state string_delimiter = nil after_def = value_expected = false state = :initial next elsif (state == :string || state == :multiline_string) && (match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)) if string_delimiter[0] == ?' && !(match == "\\\\" || match == "\\'") encoder.text_token match, :content else encoder.text_token match, :char end elsif state == :regexp && match = scan(/ \\ (?: #{REGEXP_ESCAPE} | #{UNICODE_ESCAPE} ) /mox) encoder.text_token match, :char elsif match = scan(/ \$ #{IDENT} /mox) encoder.begin_group :inline encoder.text_token '$', :inline_delimiter match = match[1..-1] encoder.text_token match, IDENT_KIND[match] encoder.end_group :inline next elsif match = scan(/ \$ \{ /x) encoder.begin_group :inline encoder.text_token match, :inline_delimiter inline_block_stack << [state, string_delimiter, inline_block_paren_depth] inline_block_paren_depth = 1 state = :initial next elsif match = scan(/ \$ /mx) encoder.text_token match, :content elsif match = scan(/ \\. /mx) encoder.text_token match, :content # TODO: Shouldn't this be :error? elsif match = scan(/ \\ | \n /x) encoder.end_group state == :regexp ? :regexp : :string encoder.text_token match, :error after_def = value_expected = false state = :initial else raise_inspect "else case \" reached; %p not handled." % peek(1), encoder end else raise_inspect 'Unknown state', encoder end last_token = match unless [:space, :comment, :doctype].include? kind end if [:multiline_string, :string, :regexp].include? state encoder.end_group state == :regexp ? :regexp : :string end if options[:keep_state] @state = state end until inline_block_stack.empty? state, = *inline_block_stack.pop encoder.end_group :inline encoder.end_group state == :regexp ? :regexp : :string end encoder end end end end coderay-1.1.1/lib/coderay/scanners/sql.rb0000644000004100000410000001250412663664402020337 0ustar www-datawww-datamodule CodeRay module Scanners # by Josh Goebel class SQL < Scanner register_for :sql KEYWORDS = %w( all and any as before begin between by case check collate each else end exists for foreign from full group having if in inner is join like not of on or order outer over references then to union using values when where left right distinct ) OBJECTS = %w( database databases table tables column columns fields index constraint constraints transaction function procedure row key view trigger ) COMMANDS = %w( add alter comment create delete drop grant insert into select update set show prompt begin commit rollback replace truncate ) PREDEFINED_TYPES = %w( char varchar varchar2 enum binary text tinytext mediumtext longtext blob tinyblob mediumblob longblob timestamp date time datetime year double decimal float int integer tinyint mediumint bigint smallint unsigned bit bool boolean hex bin oct ) PREDEFINED_FUNCTIONS = %w( sum cast substring abs pi count min max avg now ) DIRECTIVES = %w( auto_increment unique default charset initially deferred deferrable cascade immediate read write asc desc after primary foreign return engine ) PREDEFINED_CONSTANTS = %w( null true false ) IDENT_KIND = WordList::CaseIgnoring.new(:ident). add(KEYWORDS, :keyword). add(OBJECTS, :type). add(COMMANDS, :class). add(PREDEFINED_TYPES, :predefined_type). add(PREDEFINED_CONSTANTS, :predefined_constant). add(PREDEFINED_FUNCTIONS, :predefined). add(DIRECTIVES, :directive) ESCAPE = / [rbfntv\n\\\/'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} | . /mx UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x STRING_PREFIXES = /[xnb]|_\w+/i STRING_CONTENT_PATTERN = { '"' => / (?: [^\\"] | "" )+ /x, "'" => / (?: [^\\'] | '' )+ /x, '`' => / (?: [^\\`] | `` )+ /x, } def scan_tokens encoder, options state = :initial string_type = nil string_content = '' name_expected = false until eos? if state == :initial if match = scan(/ \s+ | \\\n /x) encoder.text_token match, :space elsif match = scan(/(?:--\s?|#).*/) encoder.text_token match, :comment elsif match = scan(%r( /\* (!)? (?: .*? \*/ | .* ) )mx) encoder.text_token match, self[1] ? :directive : :comment elsif match = scan(/ [*\/=<>:;,!&^|()\[\]{}~%] | [-+\.](?!\d) /x) name_expected = true if match == '.' && check(/[A-Za-z_]/) encoder.text_token match, :operator elsif match = scan(/(#{STRING_PREFIXES})?([`"'])/o) prefix = self[1] string_type = self[2] encoder.begin_group :string encoder.text_token prefix, :modifier if prefix match = string_type state = :string encoder.text_token match, :delimiter elsif match = scan(/ @? [A-Za-z_][A-Za-z_0-9\$]* /x) encoder.text_token match, name_expected ? :ident : (match[0] == ?@ ? :variable : IDENT_KIND[match]) name_expected = false elsif match = scan(/0[xX][0-9A-Fa-f]+/) encoder.text_token match, :hex elsif match = scan(/0[0-7]+(?![89.eEfF])/) encoder.text_token match, :octal elsif match = scan(/[-+]?(?>\d+)(?![.eEfF])/) encoder.text_token match, :integer elsif match = scan(/[-+]?(?:\d[fF]|\d*\.\d+(?:[eE][+-]?\d+)?|\d+[eE][+-]?\d+)/) encoder.text_token match, :float elsif match = scan(/\\N/) encoder.text_token match, :predefined_constant else encoder.text_token getch, :error end elsif state == :string if match = scan(STRING_CONTENT_PATTERN[string_type]) encoder.text_token match, :content elsif match = scan(/["'`]/) if string_type == match if peek(1) == string_type # doubling means escape encoder.text_token match + getch, :content else encoder.text_token match, :delimiter encoder.end_group :string state = :initial string_type = nil end else encoder.text_token match, :content end elsif match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox) encoder.text_token match, :char elsif match = scan(/ \\ . /mox) encoder.text_token match, :content elsif match = scan(/ \\ | $ /x) encoder.text_token match, :error unless match.empty? encoder.end_group :string state = :initial else raise "else case \" reached; %p not handled." % peek(1), encoder end else raise 'else-case reached', encoder end end if state == :string encoder.end_group state end encoder end end end end coderay-1.1.1/lib/coderay/scanners/yaml.rb0000644000004100000410000001101612663664402020477 0ustar www-datawww-datamodule CodeRay module Scanners # Scanner for YAML. # # Based on the YAML scanner from Syntax by Jamis Buck. class YAML < Scanner register_for :yaml file_extension 'yml' KINDS_NOT_LOC = :all protected def scan_tokens encoder, options state = :initial key_indent = string_indent = 0 until eos? key_indent = nil if bol? if match = scan(/ +[\t ]*/) encoder.text_token match, :space elsif match = scan(/\n+/) encoder.text_token match, :space state = :initial if match.index(?\n) elsif match = scan(/#.*/) encoder.text_token match, :comment elsif bol? and case when match = scan(/---|\.\.\./) encoder.begin_group :head encoder.text_token match, :head encoder.end_group :head next when match = scan(/%.*/) encoder.text_token match, :doctype next end elsif state == :value and case when !check(/(?:"[^"]*")(?=: |:$)/) && match = scan(/"/) encoder.begin_group :string encoder.text_token match, :delimiter encoder.text_token match, :content if (match = scan(/ [^"\\]* (?: \\. [^"\\]* )* /mx)) && !match.empty? encoder.text_token match, :delimiter if match = scan(/"/) encoder.end_group :string next when match = scan(/[|>][-+]?/) encoder.begin_group :string encoder.text_token match, :delimiter string_indent = key_indent || column(pos - match.size) - 1 encoder.text_token matched, :content if scan(/(?:\n+ {#{string_indent + 1}}.*)+/) encoder.end_group :string next when match = scan(/(?![!"*&]).+?(?=$|\s+#)/) encoder.begin_group :string encoder.text_token match, :content string_indent = key_indent || column(pos - match.size) - 1 encoder.text_token matched, :content if scan(/(?:\n+ {#{string_indent + 1}}.*)+/) encoder.end_group :string next end elsif case when match = scan(/[-:](?= |$)/) state = :value if state == :colon && (match == ':' || match == '-') state = :value if state == :initial && match == '-' encoder.text_token match, :operator next when match = scan(/[,{}\[\]]/) encoder.text_token match, :operator next when state == :initial && match = scan(/[-\w.()\/ ]*\S(?= *:(?: |$))/) encoder.text_token match, :key key_indent = column(pos - match.size) - 1 state = :colon next when match = scan(/(?:"[^"\n]*"|'[^'\n]*')(?= *:(?: |$))/) encoder.begin_group :key encoder.text_token match[0,1], :delimiter encoder.text_token match[1..-2], :content if match.size > 2 encoder.text_token match[-1,1], :delimiter encoder.end_group :key key_indent = column(pos - match.size) - 1 state = :colon next when match = scan(/(![\w\/]+)(:([\w:]+))?/) encoder.text_token self[1], :type if self[2] encoder.text_token ':', :operator encoder.text_token self[3], :class end next when match = scan(/&\S+/) encoder.text_token match, :variable next when match = scan(/\*\w+/) encoder.text_token match, :global_variable next when match = scan(/<[^'\\]*) ')? | " (?:(?>[^"\\\#]*) ")? /mx) if match.size == 1 kind = check(self.class::StringState.simple_key_pattern(match)) ? :key : :string encoder.begin_group kind encoder.text_token match, :delimiter state = self.class::StringState.new kind, match == '"', match # important for streaming else kind = value_expected == true && scan(/:/) ? :key : :string encoder.begin_group kind encoder.text_token match[0,1], :delimiter encoder.text_token match[1..-2], :content if match.size > 2 encoder.text_token match[-1,1], :delimiter encoder.end_group kind encoder.text_token ':', :operator if kind == :key value_expected = false end elsif match = scan(unicode ? /#{patterns::INSTANCE_VARIABLE}/uo : /#{patterns::INSTANCE_VARIABLE}/o) value_expected = false encoder.text_token match, :instance_variable elsif value_expected && match = scan(/\//) encoder.begin_group :regexp encoder.text_token match, :delimiter state = self.class::StringState.new :regexp, true, '/' elsif match = scan(value_expected ? /[-+]?#{patterns::NUMERIC}/o : /#{patterns::NUMERIC}/o) if method_call_expected encoder.text_token match, :error method_call_expected = false else kind = self[1] ? :float : :integer # TODO: send :hex/:octal/:binary match << 'r' if match !~ /e/i && scan(/r/) match << 'i' if scan(/i/) encoder.text_token match, kind end value_expected = false elsif match = scan(/ [-+!~^\/]=? | [:;] | &\. | [*|&]{1,2}=? | >>? /x) value_expected = true encoder.text_token match, :operator elsif value_expected && match = scan(/#{patterns::HEREDOC_OPEN}/o) quote = self[3] delim = self[quote ? 4 : 2] kind = patterns::QUOTE_TO_TYPE[quote] encoder.begin_group kind encoder.text_token match, :delimiter encoder.end_group kind heredocs ||= [] # create heredocs if empty heredocs << self.class::StringState.new(kind, quote != "'", delim, self[1] ? :indented : :linestart) value_expected = false elsif value_expected && match = scan(/#{patterns::FANCY_STRING_START}/o) kind = patterns::FANCY_STRING_KIND[self[1]] encoder.begin_group kind state = self.class::StringState.new kind, patterns::FANCY_STRING_INTERPRETED[self[1]], self[2] encoder.text_token match, :delimiter elsif value_expected && match = scan(/#{patterns::CHARACTER}/o) value_expected = false encoder.text_token match, :integer elsif match = scan(/ %=? | <(?:<|=>?)? | \? /x) value_expected = match == '?' ? :colon_expected : true encoder.text_token match, :operator elsif match = scan(/`/) encoder.begin_group :shell encoder.text_token match, :delimiter state = self.class::StringState.new :shell, true, match elsif match = scan(unicode ? /#{patterns::GLOBAL_VARIABLE}/uo : /#{patterns::GLOBAL_VARIABLE}/o) encoder.text_token match, :global_variable value_expected = false elsif match = scan(unicode ? /#{patterns::CLASS_VARIABLE}/uo : /#{patterns::CLASS_VARIABLE}/o) encoder.text_token match, :class_variable value_expected = false elsif match = scan(/\\\z/) encoder.text_token match, :space else if method_call_expected method_call_expected = false next end unless unicode # check for unicode $DEBUG_BEFORE, $DEBUG = $DEBUG, false begin if check(/./mu).size > 1 # seems like we should try again with unicode unicode = true end rescue # bad unicode char; use getch ensure $DEBUG = $DEBUG_BEFORE end next if unicode end encoder.text_token getch, :error end if last_state state = last_state unless state.is_a?(StringState) # otherwise, a simple 'def"' results in unclosed tokens last_state = nil end elsif state == :def_expected if match = scan(unicode ? /(?>#{patterns::METHOD_NAME_EX})(?!\.|::)/uo : /(?>#{patterns::METHOD_NAME_EX})(?!\.|::)/o) encoder.text_token match, :method state = :initial else last_state = :dot_expected state = :initial end elsif state == :dot_expected if match = scan(/\.|::/) # invalid definition state = :def_expected encoder.text_token match, :operator else state = :initial end elsif state == :module_expected if match = scan(/<#{patterns::METHOD_NAME_EX})(?!\.|::)/uo : /(?>#{patterns::METHOD_NAME_EX})(?!\.|::)/o) encoder.text_token match, :method elsif match = scan(/#{patterns::SYMBOL}/o) case delim = match[1] when ?', ?" encoder.begin_group :symbol encoder.text_token ':', :symbol match = delim.chr encoder.text_token match, :delimiter state = self.class::StringState.new :symbol, delim == ?", match state.next_state = :undef_comma_expected else encoder.text_token match, :symbol end else state = :initial end elsif state == :undef_comma_expected if match = scan(/,/) encoder.text_token match, :operator state = :undef_expected else state = :initial end elsif state == :alias_expected match = scan(unicode ? /(#{patterns::METHOD_NAME_OR_SYMBOL})([ \t]+)(#{patterns::METHOD_NAME_OR_SYMBOL})/uo : /(#{patterns::METHOD_NAME_OR_SYMBOL})([ \t]+)(#{patterns::METHOD_NAME_OR_SYMBOL})/o) if match encoder.text_token self[1], (self[1][0] == ?: ? :symbol : :method) encoder.text_token self[2], :space encoder.text_token self[3], (self[3][0] == ?: ? :symbol : :method) end state = :initial else #:nocov: raise_inspect 'Unknown state: %p' % [state], encoder #:nocov: end else # StringState match = scan_until(state.pattern) || scan_rest unless match.empty? encoder.text_token match, :content break if eos? end if state.heredoc && self[1] # end of heredoc match = getch match << scan_until(/$/) unless eos? encoder.text_token match, :delimiter unless match.empty? encoder.end_group state.type state = state.next_state next end case match = getch when state.delim if state.paren_depth state.paren_depth -= 1 if state.paren_depth > 0 encoder.text_token match, :content next end end encoder.text_token match, :delimiter if state.type == :regexp && !eos? match = scan(/#{patterns::REGEXP_MODIFIERS}/o) encoder.text_token match, :modifier unless match.empty? end encoder.end_group state.type value_expected = false state = state.next_state when '\\' if state.interpreted if esc = scan(/#{patterns::ESCAPE}/o) encoder.text_token match + esc, :char else encoder.text_token match, :error end else case esc = getch when nil encoder.text_token match, :content when state.delim, '\\' encoder.text_token match + esc, :char else encoder.text_token match + esc, :content end end when '#' case peek(1) when '{' inline_block_stack ||= [] inline_block_stack << [state, inline_block_curly_depth, heredocs] value_expected = true state = :initial inline_block_curly_depth = 1 encoder.begin_group :inline encoder.text_token match + getch, :inline_delimiter when '$', '@' encoder.text_token match, :escape last_state = state state = :initial else #:nocov: raise_inspect 'else-case # reached; #%p not handled' % [peek(1)], encoder #:nocov: end when state.opening_paren state.paren_depth += 1 encoder.text_token match, :content else #:nocov raise_inspect 'else-case " reached; %p not handled, state = %p' % [match, state], encoder #:nocov: end end end # cleaning up if state.is_a? StringState encoder.end_group state.type end if options[:keep_state] if state.is_a?(StringState) && state.heredoc (heredocs ||= []).unshift state state = :initial elsif heredocs && heredocs.empty? heredocs = nil end @state = state, heredocs end if inline_block_stack until inline_block_stack.empty? state, = *inline_block_stack.pop encoder.end_group :inline encoder.end_group state.type end end encoder end end end end coderay-1.1.1/lib/coderay/scanners/xml.rb0000644000004100000410000000033012663664402020332 0ustar www-datawww-datamodule CodeRay module Scanners load :html # Scanner for XML. # # Currently this is the same scanner as Scanners::HTML. class XML < HTML register_for :xml file_extension 'xml' end end end coderay-1.1.1/lib/coderay/scanners/text.rb0000644000004100000410000000071412663664402020524 0ustar www-datawww-datamodule CodeRay module Scanners # Scanner for plain text. # # Yields just one token of the kind :plain. # # Alias: +plaintext+, +plain+ class Text < Scanner register_for :text title 'Plain text' KINDS_NOT_LOC = [:plain] # :nodoc: protected def scan_tokens encoder, options encoder.text_token string, :plain encoder end end end end coderay-1.1.1/lib/coderay/scanners/json.rb0000644000004100000410000000525612663664402020517 0ustar www-datawww-datamodule CodeRay module Scanners # Scanner for JSON (JavaScript Object Notation). class JSON < Scanner register_for :json file_extension 'json' KINDS_NOT_LOC = [ :float, :char, :content, :delimiter, :error, :integer, :operator, :value, ] # :nodoc: ESCAPE = / [bfnrt\\"\/] /x # :nodoc: UNICODE_ESCAPE = / u[a-fA-F0-9]{4} /x # :nodoc: KEY = / (?> (?: [^\\"]+ | \\. )* ) " \s* : /x protected def setup @state = :initial end # See http://json.org/ for a definition of the JSON lexic/grammar. def scan_tokens encoder, options state = options[:state] || @state if [:string, :key].include? state encoder.begin_group state end until eos? case state when :initial if match = scan(/ \s+ /x) encoder.text_token match, :space elsif match = scan(/"/) state = check(/#{KEY}/o) ? :key : :string encoder.begin_group state encoder.text_token match, :delimiter elsif match = scan(/ [:,\[{\]}] /x) encoder.text_token match, :operator elsif match = scan(/ true | false | null /x) encoder.text_token match, :value elsif match = scan(/ -? (?: 0 | [1-9]\d* ) /x) if scan(/ \.\d+ (?:[eE][-+]?\d+)? | [eE][-+]? \d+ /x) match << matched encoder.text_token match, :float else encoder.text_token match, :integer end else encoder.text_token getch, :error end when :string, :key if match = scan(/[^\\"]+/) encoder.text_token match, :content elsif match = scan(/"/) encoder.text_token match, :delimiter encoder.end_group state state = :initial elsif match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox) encoder.text_token match, :char elsif match = scan(/\\./m) encoder.text_token match, :content elsif match = scan(/ \\ | $ /x) encoder.end_group state encoder.text_token match, :error unless match.empty? state = :initial else raise_inspect "else case \" reached; %p not handled." % peek(1), encoder end else raise_inspect 'Unknown state: %p' % [state], encoder end end if options[:keep_state] @state = state end if [:string, :key].include? state encoder.end_group state end encoder end end end end coderay-1.1.1/lib/coderay/scanners/java_script.rb0000644000004100000410000001744312663664402022054 0ustar www-datawww-datamodule CodeRay module Scanners # Scanner for JavaScript. # # Aliases: +ecmascript+, +ecma_script+, +javascript+ class JavaScript < Scanner register_for :java_script file_extension 'js' # The actual JavaScript keywords. KEYWORDS = %w[ break case catch continue default delete do else finally for function if in instanceof new return switch throw try typeof var void while with ] # :nodoc: PREDEFINED_CONSTANTS = %w[ false null true undefined NaN Infinity ] # :nodoc: MAGIC_VARIABLES = %w[ this arguments ] # :nodoc: arguments was introduced in JavaScript 1.4 KEYWORDS_EXPECTING_VALUE = WordList.new.add %w[ case delete in instanceof new return throw typeof with ] # :nodoc: # Reserved for future use. RESERVED_WORDS = %w[ abstract boolean byte char class debugger double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile ] # :nodoc: IDENT_KIND = WordList.new(:ident). add(RESERVED_WORDS, :reserved). add(PREDEFINED_CONSTANTS, :predefined_constant). add(MAGIC_VARIABLES, :local_variable). add(KEYWORDS, :keyword) # :nodoc: ESCAPE = / [bfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc: UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x # :nodoc: REGEXP_ESCAPE = / [bBdDsSwW] /x # :nodoc: STRING_CONTENT_PATTERN = { "'" => /[^\\']+/, '"' => /[^\\"]+/, '/' => /[^\\\/]+/, } # :nodoc: KEY_CHECK_PATTERN = { "'" => / (?> [^\\']* (?: \\. [^\\']* )* ) ' \s* : /mx, '"' => / (?> [^\\"]* (?: \\. [^\\"]* )* ) " \s* : /mx, } # :nodoc: protected def setup @state = :initial end def scan_tokens encoder, options state, string_delimiter = options[:state] || @state if string_delimiter encoder.begin_group state end value_expected = true key_expected = false function_expected = false until eos? case state when :initial if match = scan(/ \s+ | \\\n /x) value_expected = true if !value_expected && match.index(?\n) encoder.text_token match, :space elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .*() ) !mx) value_expected = true encoder.text_token match, :comment state = :open_multi_line_comment if self[1] elsif check(/\.?\d/) key_expected = value_expected = false if match = scan(/0[xX][0-9A-Fa-f]+/) encoder.text_token match, :hex elsif match = scan(/(?>0[0-7]+)(?![89.eEfF])/) encoder.text_token match, :octal elsif match = scan(/\d+[fF]|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/) encoder.text_token match, :float elsif match = scan(/\d+/) encoder.text_token match, :integer end elsif value_expected && match = scan(/<([[:alpha:]]\w*) (?: [^\/>]*\/> | .*?<\/\1>)/xim) # TODO: scan over nested tags xml_scanner.tokenize match, :tokens => encoder value_expected = false next elsif match = scan(/ [-+*=<>?:;,!&^|(\[{~%]+ | \.(?!\d) /x) value_expected = true last_operator = match[-1] key_expected = (last_operator == ?{) || (last_operator == ?,) function_expected = false encoder.text_token match, :operator elsif match = scan(/ [)\]}]+ /x) function_expected = key_expected = value_expected = false encoder.text_token match, :operator elsif match = scan(/ [$a-zA-Z_][A-Za-z_0-9$]* /x) kind = IDENT_KIND[match] value_expected = (kind == :keyword) && KEYWORDS_EXPECTING_VALUE[match] # TODO: labels if kind == :ident if match.index(?$) # $ allowed inside an identifier kind = :predefined elsif function_expected kind = :function elsif check(/\s*[=:]\s*function\b/) kind = :function elsif key_expected && check(/\s*:/) kind = :key end end function_expected = (kind == :keyword) && (match == 'function') key_expected = false encoder.text_token match, kind elsif match = scan(/["']/) if key_expected && check(KEY_CHECK_PATTERN[match]) state = :key else state = :string end encoder.begin_group state string_delimiter = match encoder.text_token match, :delimiter elsif value_expected && (match = scan(/\//)) encoder.begin_group :regexp state = :regexp string_delimiter = '/' encoder.text_token match, :delimiter elsif match = scan(/ \/ /x) value_expected = true key_expected = false encoder.text_token match, :operator else encoder.text_token getch, :error end when :string, :regexp, :key if match = scan(STRING_CONTENT_PATTERN[string_delimiter]) encoder.text_token match, :content elsif match = scan(/["'\/]/) encoder.text_token match, :delimiter if state == :regexp modifiers = scan(/[gim]+/) encoder.text_token modifiers, :modifier if modifiers && !modifiers.empty? end encoder.end_group state string_delimiter = nil key_expected = value_expected = false state = :initial elsif state != :regexp && (match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)) if string_delimiter == "'" && !(match == "\\\\" || match == "\\'") encoder.text_token match, :content else encoder.text_token match, :char end elsif state == :regexp && match = scan(/ \\ (?: #{ESCAPE} | #{REGEXP_ESCAPE} | #{UNICODE_ESCAPE} ) /mox) encoder.text_token match, :char elsif match = scan(/\\./m) encoder.text_token match, :content elsif match = scan(/ \\ | $ /x) encoder.end_group state encoder.text_token match, :error unless match.empty? string_delimiter = nil key_expected = value_expected = false state = :initial else raise_inspect "else case #{string_delimiter} reached; %p not handled." % peek(1), encoder end when :open_multi_line_comment if match = scan(%r! .*? \*/ !mx) state = :initial else match = scan(%r! .+ !mx) end value_expected = true encoder.text_token match, :comment if match else #:nocov: raise_inspect 'Unknown state: %p' % [state], encoder #:nocov: end end if options[:keep_state] @state = state, string_delimiter end if [:string, :regexp].include? state encoder.end_group state end encoder end protected def reset_instance super @xml_scanner.reset if defined? @xml_scanner end def xml_scanner @xml_scanner ||= CodeRay.scanner :xml, :tokens => @tokens, :keep_tokens => true, :keep_state => false end end end end coderay-1.1.1/lib/coderay/scanners/delphi.rb0000644000004100000410000001120712663664402021004 0ustar www-datawww-datamodule CodeRay module Scanners # Scanner for the Delphi language (Object Pascal). # # Alias: +pascal+ class Delphi < Scanner register_for :delphi file_extension 'pas' KEYWORDS = [ 'and', 'array', 'as', 'at', 'asm', 'at', 'begin', 'case', 'class', 'const', 'constructor', 'destructor', 'dispinterface', 'div', 'do', 'downto', 'else', 'end', 'except', 'exports', 'file', 'finalization', 'finally', 'for', 'function', 'goto', 'if', 'implementation', 'in', 'inherited', 'initialization', 'inline', 'interface', 'is', 'label', 'library', 'mod', 'nil', 'not', 'object', 'of', 'or', 'out', 'packed', 'procedure', 'program', 'property', 'raise', 'record', 'repeat', 'resourcestring', 'set', 'shl', 'shr', 'string', 'then', 'threadvar', 'to', 'try', 'type', 'unit', 'until', 'uses', 'var', 'while', 'with', 'xor', 'on', ] # :nodoc: DIRECTIVES = [ 'absolute', 'abstract', 'assembler', 'at', 'automated', 'cdecl', 'contains', 'deprecated', 'dispid', 'dynamic', 'export', 'external', 'far', 'forward', 'implements', 'local', 'near', 'nodefault', 'on', 'overload', 'override', 'package', 'pascal', 'platform', 'private', 'protected', 'public', 'published', 'read', 'readonly', 'register', 'reintroduce', 'requires', 'resident', 'safecall', 'stdcall', 'stored', 'varargs', 'virtual', 'write', 'writeonly', ] # :nodoc: IDENT_KIND = WordList::CaseIgnoring.new(:ident). add(KEYWORDS, :keyword). add(DIRECTIVES, :directive) # :nodoc: NAME_FOLLOWS = WordList::CaseIgnoring.new(false). add(%w(procedure function .)) # :nodoc: protected def scan_tokens encoder, options state = :initial last_token = '' until eos? if state == :initial if match = scan(/ \s+ /x) encoder.text_token match, :space next elsif match = scan(%r! \{ \$ [^}]* \}? | \(\* \$ (?: .*? \*\) | .* ) !mx) encoder.text_token match, :preprocessor next elsif match = scan(%r! // [^\n]* | \{ [^}]* \}? | \(\* (?: .*? \*\) | .* ) !mx) encoder.text_token match, :comment next elsif match = scan(/ <[>=]? | >=? | :=? | [-+=*\/;,@\^|\(\)\[\]] | \.\. /x) encoder.text_token match, :operator elsif match = scan(/\./) encoder.text_token match, :operator next if last_token == 'end' elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x) encoder.text_token match, NAME_FOLLOWS[last_token] ? :ident : IDENT_KIND[match] elsif match = skip(/ ' ( [^\n']|'' ) (?:'|$) /x) encoder.begin_group :char encoder.text_token "'", :delimiter encoder.text_token self[1], :content encoder.text_token "'", :delimiter encoder.end_group :char next elsif match = scan(/ ' /x) encoder.begin_group :string encoder.text_token match, :delimiter state = :string elsif match = scan(/ \# (?: \d+ | \$[0-9A-Fa-f]+ ) /x) encoder.text_token match, :char elsif match = scan(/ \$ [0-9A-Fa-f]+ /x) encoder.text_token match, :hex elsif match = scan(/ (?: \d+ ) (?![eE]|\.[^.]) /x) encoder.text_token match, :integer elsif match = scan(/ \d+ (?: \.\d+ (?: [eE][+-]? \d+ )? | [eE][+-]? \d+ ) /x) encoder.text_token match, :float else encoder.text_token getch, :error next end elsif state == :string if match = scan(/[^\n']+/) encoder.text_token match, :content elsif match = scan(/''/) encoder.text_token match, :char elsif match = scan(/'/) encoder.text_token match, :delimiter encoder.end_group :string state = :initial next elsif match = scan(/\n/) encoder.end_group :string encoder.text_token match, :space state = :initial else raise "else case \' reached; %p not handled." % peek(1), encoder end else raise 'else-case reached', encoder end last_token = match end if state == :string encoder.end_group state end encoder end end end end coderay-1.1.1/lib/coderay/scanners/python.rb0000644000004100000410000002360712663664402021067 0ustar www-datawww-datamodule CodeRay module Scanners # Scanner for Python. Supports Python 3. # # Based on pygments' PythonLexer, see # http://dev.pocoo.org/projects/pygments/browser/pygments/lexers/agile.py. class Python < Scanner register_for :python file_extension 'py' KEYWORDS = [ 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield', 'nonlocal', # new in Python 3 ] # :nodoc: OLD_KEYWORDS = [ 'exec', 'print', # gone in Python 3 ] # :nodoc: PREDEFINED_METHODS_AND_TYPES = %w[ __import__ abs all any apply basestring bin bool buffer bytearray bytes callable chr classmethod cmp coerce compile complex delattr dict dir divmod enumerate eval execfile exit file filter float frozenset getattr globals hasattr hash hex id input int intern isinstance issubclass iter len list locals long map max min next object oct open ord pow property range raw_input reduce reload repr reversed round set setattr slice sorted staticmethod str sum super tuple type unichr unicode vars xrange zip ] # :nodoc: PREDEFINED_EXCEPTIONS = %w[ ArithmeticError AssertionError AttributeError BaseException DeprecationWarning EOFError EnvironmentError Exception FloatingPointError FutureWarning GeneratorExit IOError ImportError ImportWarning IndentationError IndexError KeyError KeyboardInterrupt LookupError MemoryError NameError NotImplemented NotImplementedError OSError OverflowError OverflowWarning PendingDeprecationWarning ReferenceError RuntimeError RuntimeWarning StandardError StopIteration SyntaxError SyntaxWarning SystemError SystemExit TabError TypeError UnboundLocalError UnicodeDecodeError UnicodeEncodeError UnicodeError UnicodeTranslateError UnicodeWarning UserWarning ValueError Warning ZeroDivisionError ] # :nodoc: PREDEFINED_VARIABLES_AND_CONSTANTS = [ 'False', 'True', 'None', # "keywords" since Python 3 'self', 'Ellipsis', 'NotImplemented', ] # :nodoc: IDENT_KIND = WordList.new(:ident). add(KEYWORDS, :keyword). add(OLD_KEYWORDS, :old_keyword). add(PREDEFINED_METHODS_AND_TYPES, :predefined). add(PREDEFINED_VARIABLES_AND_CONSTANTS, :predefined_constant). add(PREDEFINED_EXCEPTIONS, :exception) # :nodoc: NAME = / [[:alpha:]_] \w* /x # :nodoc: ESCAPE = / [abfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc: UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} | N\{[-\w ]+\} /x # :nodoc: OPERATOR = / \.\.\. | # ellipsis \.(?!\d) | # dot but not decimal point [,;:()\[\]{}] | # simple delimiters \/\/=? | \*\*=? | # special math [-+*\/%&|^]=? | # ordinary math and binary logic [~`] | # binary complement and inspection <<=? | >>=? | [<>=]=? | != # comparison and assignment /x # :nodoc: STRING_DELIMITER_REGEXP = Hash.new { |h, delimiter| h[delimiter] = Regexp.union delimiter # :nodoc: } STRING_CONTENT_REGEXP = Hash.new { |h, delimiter| h[delimiter] = / [^\\\n]+? (?= \\ | $ | #{Regexp.escape(delimiter)} ) /x # :nodoc: } DEF_NEW_STATE = WordList.new(:initial). add(%w(def), :def_expected). add(%w(import from), :include_expected). add(%w(class), :class_expected) # :nodoc: DESCRIPTOR = / #{NAME} (?: \. #{NAME} )* | \* /x # :nodoc: DOCSTRING_COMING = / [ \t]* u?r? ("""|''') /x # :nodoc: protected def scan_tokens encoder, options state = :initial string_delimiter = nil string_raw = false string_type = nil docstring_coming = match?(/#{DOCSTRING_COMING}/o) last_token_dot = false unicode = string.respond_to?(:encoding) && string.encoding.name == 'UTF-8' from_import_state = [] until eos? if state == :string if match = scan(STRING_DELIMITER_REGEXP[string_delimiter]) encoder.text_token match, :delimiter encoder.end_group string_type string_type = nil state = :initial next elsif string_delimiter.size == 3 && match = scan(/\n/) encoder.text_token match, :content elsif match = scan(STRING_CONTENT_REGEXP[string_delimiter]) encoder.text_token match, :content elsif !string_raw && match = scan(/ \\ #{ESCAPE} /ox) encoder.text_token match, :char elsif match = scan(/ \\ #{UNICODE_ESCAPE} /ox) encoder.text_token match, :char elsif match = scan(/ \\ . /x) encoder.text_token match, :content elsif match = scan(/ \\ | $ /x) encoder.end_group string_type string_type = nil encoder.text_token match, :error unless match.empty? state = :initial else raise_inspect "else case \" reached; %p not handled." % peek(1), encoder, state end elsif match = scan(/ [ \t]+ | \\?\n /x) encoder.text_token match, :space if match == "\n" state = :initial if state == :include_expected docstring_coming = true if match?(/#{DOCSTRING_COMING}/o) end next elsif match = scan(/ \# [^\n]* /mx) encoder.text_token match, :comment next elsif state == :initial if match = scan(/#{OPERATOR}/o) encoder.text_token match, :operator elsif match = scan(/(u?r?|b)?("""|"|'''|')/i) modifiers = self[1] string_delimiter = self[2] string_type = docstring_coming ? :docstring : (modifiers == 'b' ? :binary : :string) docstring_coming = false if docstring_coming encoder.begin_group string_type string_raw = false unless modifiers.empty? string_raw = !!modifiers.index(?r) encoder.text_token modifiers, :modifier match = string_delimiter end state = :string encoder.text_token match, :delimiter # TODO: backticks elsif match = scan(unicode ? /#{NAME}/uo : /#{NAME}/o) kind = IDENT_KIND[match] # TODO: keyword arguments kind = :ident if last_token_dot if kind == :old_keyword kind = check(/\(/) ? :ident : :keyword elsif kind == :predefined && check(/ *=/) kind = :ident elsif kind == :keyword state = DEF_NEW_STATE[match] from_import_state << match.to_sym if state == :include_expected end encoder.text_token match, kind elsif match = scan(/@[a-zA-Z0-9_.]+[lL]?/) encoder.text_token match, :decorator elsif match = scan(/0[xX][0-9A-Fa-f]+[lL]?/) encoder.text_token match, :hex elsif match = scan(/0[bB][01]+[lL]?/) encoder.text_token match, :binary elsif match = scan(/(?:\d*\.\d+|\d+\.\d*)(?:[eE][+-]?\d+)?|\d+[eE][+-]?\d+/) if scan(/[jJ]/) match << matched encoder.text_token match, :imaginary else encoder.text_token match, :float end elsif match = scan(/0[oO][0-7]+|0[0-7]+(?![89.eE])[lL]?/) encoder.text_token match, :octal elsif match = scan(/\d+([lL])?/) if self[1] == nil && scan(/[jJ]/) match << matched encoder.text_token match, :imaginary else encoder.text_token match, :integer end else encoder.text_token getch, :error end elsif state == :def_expected state = :initial if match = scan(unicode ? /#{NAME}/uo : /#{NAME}/o) encoder.text_token match, :method else next end elsif state == :class_expected state = :initial if match = scan(unicode ? /#{NAME}/uo : /#{NAME}/o) encoder.text_token match, :class else next end elsif state == :include_expected if match = scan(unicode ? /#{DESCRIPTOR}/uo : /#{DESCRIPTOR}/o) if match == 'as' encoder.text_token match, :keyword from_import_state << :as elsif from_import_state.first == :from && match == 'import' encoder.text_token match, :keyword from_import_state << :import elsif from_import_state.last == :as # encoder.text_token match, match[0,1][unicode ? /[[:upper:]]/u : /[[:upper:]]/] ? :class : :method encoder.text_token match, :ident from_import_state.pop elsif IDENT_KIND[match] == :keyword unscan match = nil state = :initial next else encoder.text_token match, :include end elsif match = scan(/,/) from_import_state.pop if from_import_state.last == :as encoder.text_token match, :operator else from_import_state = [] state = :initial next end else raise_inspect 'Unknown state', encoder, state end last_token_dot = match == '.' end if state == :string encoder.end_group string_type end encoder end end end end coderay-1.1.1/lib/coderay/scanners/go.rb0000644000004100000410000001500012663664402020137 0ustar www-datawww-datamodule CodeRay module Scanners class Go < Scanner register_for :go file_extension 'go' # http://golang.org/ref/spec#Keywords KEYWORDS = [ 'break', 'default', 'func', 'interface', 'select', 'case', 'defer', 'go', 'map', 'struct', 'chan', 'else', 'goto', 'package', 'switch', 'const', 'fallthrough', 'if', 'range', 'type', 'continue', 'for', 'import', 'return', 'var', ] # :nodoc: # http://golang.org/ref/spec#Types PREDEFINED_TYPES = [ 'bool', 'uint8', 'uint16', 'uint32', 'uint64', 'int8', 'int16', 'int32', 'int64', 'float32', 'float64', 'complex64', 'complex128', 'byte', 'rune', 'string', 'error', 'uint', 'int', 'uintptr', ] # :nodoc: PREDEFINED_CONSTANTS = [ 'nil', 'iota', 'true', 'false', ] # :nodoc: PREDEFINED_FUNCTIONS = %w[ append cap close complex copy delete imag len make new panic print println real recover ] # :nodoc: IDENT_KIND = WordList.new(:ident). add(KEYWORDS, :keyword). add(PREDEFINED_TYPES, :predefined_type). add(PREDEFINED_CONSTANTS, :predefined_constant). add(PREDEFINED_FUNCTIONS, :predefined) # :nodoc: ESCAPE = / [rbfntv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc: UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x # :nodoc: protected def scan_tokens encoder, options state = :initial label_expected = true case_expected = false label_expected_before_preproc_line = nil in_preproc_line = false until eos? case state when :initial if match = scan(/ \s+ | \\\n /x) if in_preproc_line && match != "\\\n" && match.index(?\n) in_preproc_line = false case_expected = false label_expected = label_expected_before_preproc_line end encoder.text_token match, :space elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx) encoder.text_token match, :comment elsif match = scan(/ ?:;,!&^|()\[\]{}~%]+ | \/=? | \.(?!\d) /x) if case_expected label_expected = true if match == ':' case_expected = false end encoder.text_token match, :operator elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x) kind = IDENT_KIND[match] if kind == :ident && label_expected && !in_preproc_line && scan(/:(?!:)/) kind = :label label_expected = false match << matched else label_expected = false if kind == :keyword case match when 'case', 'default' case_expected = true end end end encoder.text_token match, kind elsif match = scan(/L?"/) encoder.begin_group :string if match[0] == ?L encoder.text_token 'L', :modifier match = '"' end encoder.text_token match, :delimiter state = :string elsif match = scan(/ ` ([^`]+)? (`)? /x) encoder.begin_group :shell encoder.text_token '`', :delimiter encoder.text_token self[1], :content if self[1] encoder.text_token self[2], :delimiter if self[2] encoder.end_group :shell elsif match = scan(/ \# \s* if \s* 0 /x) match << scan_until(/ ^\# (?:elif|else|endif) .*? $ | \z /xm) unless eos? encoder.text_token match, :comment elsif match = scan(/#[ \t]*(\w*)/) encoder.text_token match, :preprocessor in_preproc_line = true label_expected_before_preproc_line = label_expected state = :include_expected if self[1] == 'include' elsif match = scan(/ L?' (?: [^\'\n\\] | \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) )? '? /ox) label_expected = false encoder.text_token match, :char elsif match = scan(/\$/) encoder.text_token match, :ident elsif match = scan(/-?\d*(\.\d*)?([eE][+-]?\d+)?i/) label_expected = false encoder.text_token match, :imaginary elsif match = scan(/-?0[xX][0-9A-Fa-f]+/) label_expected = false encoder.text_token match, :hex elsif match = scan(/-?(?:0[0-7]+)(?![89.eEfF])/) label_expected = false encoder.text_token match, :octal elsif match = scan(/-?(?:\d*\.\d+|\d+\.)(?:[eE][+-]?\d+)?|\d+[eE][+-]?\d+/) label_expected = false encoder.text_token match, :float elsif match = scan(/-?(?:\d+)(?![.eEfF])L?L?/) label_expected = false encoder.text_token match, :integer else encoder.text_token getch, :error end when :string if match = scan(/[^\\\n"]+/) encoder.text_token match, :content elsif match = scan(/"/) encoder.text_token match, :delimiter encoder.end_group :string state = :initial label_expected = false elsif match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox) encoder.text_token match, :char elsif match = scan(/ \\ /x) encoder.text_token match, :error elsif match = scan(/$/) encoder.end_group :string state = :initial label_expected = false else raise_inspect "else case \" reached; %p not handled." % peek(1), encoder end when :include_expected if match = scan(/<[^>\n]+>?|"[^"\n\\]*(?:\\.[^"\n\\]*)*"?/) encoder.text_token match, :include state = :initial elsif match = scan(/\s+/) encoder.text_token match, :space state = :initial if match.index ?\n else state = :initial end else raise_inspect 'Unknown state', encoder end end if state == :string encoder.end_group :string end encoder end end end end coderay-1.1.1/lib/coderay/scanners/php.rb0000644000004100000410000006055212663664402020335 0ustar www-datawww-data# encoding: utf-8 module CodeRay module Scanners load :html # Scanner for PHP. # # Original by Stefan Walk. class PHP < Scanner register_for :php file_extension 'php' KINDS_NOT_LOC = HTML::KINDS_NOT_LOC protected def setup @html_scanner = CodeRay.scanner :html, :tokens => @tokens, :keep_tokens => true, :keep_state => true end def reset_instance super @html_scanner.reset end module Words # :nodoc: # according to http://www.php.net/manual/en/reserved.keywords.php KEYWORDS = %w[ abstract and array as break case catch class clone const continue declare default do else elseif enddeclare endfor endforeach endif endswitch endwhile extends final for foreach function global goto if implements interface instanceof namespace new or private protected public static switch throw try use var while xor cfunction old_function ] TYPES = %w[ int integer float double bool boolean string array object resource ] LANGUAGE_CONSTRUCTS = %w[ die echo empty exit eval include include_once isset list require require_once return print unset ] CLASSES = %w[ Directory stdClass __PHP_Incomplete_Class exception php_user_filter Closure ] # according to http://php.net/quickref.php on 2009-04-21; # all functions with _ excluded (module functions) and selected additional functions BUILTIN_FUNCTIONS = %w[ abs acos acosh addcslashes addslashes aggregate array arsort ascii2ebcdic asin asinh asort assert atan atan2 atanh basename bcadd bccomp bcdiv bcmod bcmul bcpow bcpowmod bcscale bcsqrt bcsub bin2hex bindec bindtextdomain bzclose bzcompress bzdecompress bzerrno bzerror bzerrstr bzflush bzopen bzread bzwrite calculhmac ceil chdir checkdate checkdnsrr chgrp chmod chop chown chr chroot clearstatcache closedir closelog compact constant copy cos cosh count crc32 crypt current date dcgettext dcngettext deaggregate decbin dechex decoct define defined deg2rad delete dgettext die dirname diskfreespace dl dngettext doubleval each ebcdic2ascii echo empty end ereg eregi escapeshellarg escapeshellcmd eval exec exit exp explode expm1 extract fclose feof fflush fgetc fgetcsv fgets fgetss file fileatime filectime filegroup fileinode filemtime fileowner fileperms filepro filesize filetype floatval flock floor flush fmod fnmatch fopen fpassthru fprintf fputcsv fputs fread frenchtojd fscanf fseek fsockopen fstat ftell ftok ftruncate fwrite getallheaders getcwd getdate getenv gethostbyaddr gethostbyname gethostbynamel getimagesize getlastmod getmxrr getmygid getmyinode getmypid getmyuid getopt getprotobyname getprotobynumber getrandmax getrusage getservbyname getservbyport gettext gettimeofday gettype glob gmdate gmmktime gmstrftime gregoriantojd gzclose gzcompress gzdecode gzdeflate gzencode gzeof gzfile gzgetc gzgets gzgetss gzinflate gzopen gzpassthru gzputs gzread gzrewind gzseek gztell gzuncompress gzwrite hash header hebrev hebrevc hexdec htmlentities htmlspecialchars hypot iconv idate implode include intval ip2long iptcembed iptcparse isset jddayofweek jdmonthname jdtofrench jdtogregorian jdtojewish jdtojulian jdtounix jewishtojd join jpeg2wbmp juliantojd key krsort ksort lcfirst lchgrp lchown levenshtein link linkinfo list localeconv localtime log log10 log1p long2ip lstat ltrim mail main max md5 metaphone mhash microtime min mkdir mktime msql natcasesort natsort next ngettext nl2br nthmac octdec opendir openlog ord overload pack passthru pathinfo pclose pfsockopen phpcredits phpinfo phpversion pi png2wbmp popen pos pow prev print printf putenv quotemeta rad2deg rand range rawurldecode rawurlencode readdir readfile readgzfile readline readlink realpath recode rename require reset rewind rewinddir rmdir round rsort rtrim scandir serialize setcookie setlocale setrawcookie settype sha1 shuffle signeurlpaiement sin sinh sizeof sleep snmpget snmpgetnext snmprealwalk snmpset snmpwalk snmpwalkoid sort soundex split spliti sprintf sqrt srand sscanf stat strcasecmp strchr strcmp strcoll strcspn strftime stripcslashes stripos stripslashes stristr strlen strnatcasecmp strnatcmp strncasecmp strncmp strpbrk strpos strptime strrchr strrev strripos strrpos strspn strstr strtok strtolower strtotime strtoupper strtr strval substr symlink syslog system tan tanh tempnam textdomain time tmpfile touch trim uasort ucfirst ucwords uksort umask uniqid unixtojd unlink unpack unserialize unset urldecode urlencode usleep usort vfprintf virtual vprintf vsprintf wordwrap array_change_key_case array_chunk array_combine array_count_values array_diff array_diff_assoc array_diff_key array_diff_uassoc array_diff_ukey array_fill array_fill_keys array_filter array_flip array_intersect array_intersect_assoc array_intersect_key array_intersect_uassoc array_intersect_ukey array_key_exists array_keys array_map array_merge array_merge_recursive array_multisort array_pad array_pop array_product array_push array_rand array_reduce array_reverse array_search array_shift array_slice array_splice array_sum array_udiff array_udiff_assoc array_udiff_uassoc array_uintersect array_uintersect_assoc array_uintersect_uassoc array_unique array_unshift array_values array_walk array_walk_recursive assert_options base_convert base64_decode base64_encode chunk_split class_exists class_implements class_parents count_chars debug_backtrace debug_print_backtrace debug_zval_dump error_get_last error_log error_reporting extension_loaded file_exists file_get_contents file_put_contents load_file func_get_arg func_get_args func_num_args function_exists get_browser get_called_class get_cfg_var get_class get_class_methods get_class_vars get_current_user get_declared_classes get_declared_interfaces get_defined_constants get_defined_functions get_defined_vars get_extension_funcs get_headers get_html_translation_table get_include_path get_included_files get_loaded_extensions get_magic_quotes_gpc get_magic_quotes_runtime get_meta_tags get_object_vars get_parent_class get_required_filesget_resource_type gc_collect_cycles gc_disable gc_enable gc_enabled halt_compiler headers_list headers_sent highlight_file highlight_string html_entity_decode htmlspecialchars_decode in_array include_once inclued_get_data is_a is_array is_binary is_bool is_buffer is_callable is_dir is_double is_executable is_file is_finite is_float is_infinite is_int is_integer is_link is_long is_nan is_null is_numeric is_object is_readable is_real is_resource is_scalar is_soap_fault is_string is_subclass_of is_unicode is_uploaded_file is_writable is_writeable locale_get_default locale_set_default number_format override_function parse_str parse_url php_check_syntax php_ini_loaded_file php_ini_scanned_files php_logo_guid php_sapi_name php_strip_whitespace php_uname preg_filter preg_grep preg_last_error preg_match preg_match_all preg_quote preg_replace preg_replace_callback preg_split print_r require_once register_shutdown_function register_tick_function set_error_handler set_exception_handler set_file_buffer set_include_path set_magic_quotes_runtime set_time_limit shell_exec str_getcsv str_ireplace str_pad str_repeat str_replace str_rot13 str_shuffle str_split str_word_count strip_tags substr_compare substr_count substr_replace time_nanosleep time_sleep_until token_get_all token_name trigger_error unregister_tick_function use_soap_error_handler user_error utf8_decode utf8_encode var_dump var_export version_compare zend_logo_guid zend_thread_id zend_version create_function call_user_func_array posix_access posix_ctermid posix_get_last_error posix_getcwd posix_getegid posix_geteuid posix_getgid posix_getgrgid posix_getgrnam posix_getgroups posix_getlogin posix_getpgid posix_getpgrp posix_getpid posix_getppid posix_getpwnam posix_getpwuid posix_getrlimit posix_getsid posix_getuid posix_initgroups posix_isatty posix_kill posix_mkfifo posix_mknod posix_setegid posix_seteuid posix_setgid posix_setpgid posix_setsid posix_setuid posix_strerror posix_times posix_ttyname posix_uname pcntl_alarm pcntl_exec pcntl_fork pcntl_getpriority pcntl_setpriority pcntl_signal pcntl_signal_dispatch pcntl_sigprocmask pcntl_sigtimedwait pcntl_sigwaitinfo pcntl_wait pcntl_waitpid pcntl_wexitstatus pcntl_wifexited pcntl_wifsignaled pcntl_wifstopped pcntl_wstopsig pcntl_wtermsig ] # TODO: more built-in PHP functions? EXCEPTIONS = %w[ E_ERROR E_WARNING E_PARSE E_NOTICE E_CORE_ERROR E_CORE_WARNING E_COMPILE_ERROR E_COMPILE_WARNING E_USER_ERROR E_USER_WARNING E_USER_NOTICE E_DEPRECATED E_USER_DEPRECATED E_ALL E_STRICT ] CONSTANTS = %w[ null true false self parent __LINE__ __DIR__ __FILE__ __LINE__ __CLASS__ __NAMESPACE__ __METHOD__ __FUNCTION__ PHP_VERSION PHP_MAJOR_VERSION PHP_MINOR_VERSION PHP_RELEASE_VERSION PHP_VERSION_ID PHP_EXTRA_VERSION PHP_ZTS PHP_DEBUG PHP_MAXPATHLEN PHP_OS PHP_SAPI PHP_EOL PHP_INT_MAX PHP_INT_SIZE DEFAULT_INCLUDE_PATH PEAR_INSTALL_DIR PEAR_EXTENSION_DIR PHP_EXTENSION_DIR PHP_PREFIX PHP_BINDIR PHP_LIBDIR PHP_DATADIR PHP_SYSCONFDIR PHP_LOCALSTATEDIR PHP_CONFIG_FILE_PATH PHP_CONFIG_FILE_SCAN_DIR PHP_SHLIB_SUFFIX PHP_OUTPUT_HANDLER_START PHP_OUTPUT_HANDLER_CONT PHP_OUTPUT_HANDLER_END __COMPILER_HALT_OFFSET__ EXTR_OVERWRITE EXTR_SKIP EXTR_PREFIX_SAME EXTR_PREFIX_ALL EXTR_PREFIX_INVALID EXTR_PREFIX_IF_EXISTS EXTR_IF_EXISTS SORT_ASC SORT_DESC SORT_REGULAR SORT_NUMERIC SORT_STRING CASE_LOWER CASE_UPPER COUNT_NORMAL COUNT_RECURSIVE ASSERT_ACTIVE ASSERT_CALLBACK ASSERT_BAIL ASSERT_WARNING ASSERT_QUIET_EVAL CONNECTION_ABORTED CONNECTION_NORMAL CONNECTION_TIMEOUT INI_USER INI_PERDIR INI_SYSTEM INI_ALL M_E M_LOG2E M_LOG10E M_LN2 M_LN10 M_PI M_PI_2 M_PI_4 M_1_PI M_2_PI M_2_SQRTPI M_SQRT2 M_SQRT1_2 CRYPT_SALT_LENGTH CRYPT_STD_DES CRYPT_EXT_DES CRYPT_MD5 CRYPT_BLOWFISH DIRECTORY_SEPARATOR SEEK_SET SEEK_CUR SEEK_END LOCK_SH LOCK_EX LOCK_UN LOCK_NB HTML_SPECIALCHARS HTML_ENTITIES ENT_COMPAT ENT_QUOTES ENT_NOQUOTES INFO_GENERAL INFO_CREDITS INFO_CONFIGURATION INFO_MODULES INFO_ENVIRONMENT INFO_VARIABLES INFO_LICENSE INFO_ALL CREDITS_GROUP CREDITS_GENERAL CREDITS_SAPI CREDITS_MODULES CREDITS_DOCS CREDITS_FULLPAGE CREDITS_QA CREDITS_ALL STR_PAD_LEFT STR_PAD_RIGHT STR_PAD_BOTH PATHINFO_DIRNAME PATHINFO_BASENAME PATHINFO_EXTENSION PATH_SEPARATOR CHAR_MAX LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_ALL LC_MESSAGES ABDAY_1 ABDAY_2 ABDAY_3 ABDAY_4 ABDAY_5 ABDAY_6 ABDAY_7 DAY_1 DAY_2 DAY_3 DAY_4 DAY_5 DAY_6 DAY_7 ABMON_1 ABMON_2 ABMON_3 ABMON_4 ABMON_5 ABMON_6 ABMON_7 ABMON_8 ABMON_9 ABMON_10 ABMON_11 ABMON_12 MON_1 MON_2 MON_3 MON_4 MON_5 MON_6 MON_7 MON_8 MON_9 MON_10 MON_11 MON_12 AM_STR PM_STR D_T_FMT D_FMT T_FMT T_FMT_AMPM ERA ERA_YEAR ERA_D_T_FMT ERA_D_FMT ERA_T_FMT ALT_DIGITS INT_CURR_SYMBOL CURRENCY_SYMBOL CRNCYSTR MON_DECIMAL_POINT MON_THOUSANDS_SEP MON_GROUPING POSITIVE_SIGN NEGATIVE_SIGN INT_FRAC_DIGITS FRAC_DIGITS P_CS_PRECEDES P_SEP_BY_SPACE N_CS_PRECEDES N_SEP_BY_SPACE P_SIGN_POSN N_SIGN_POSN DECIMAL_POINT RADIXCHAR THOUSANDS_SEP THOUSEP GROUPING YESEXPR NOEXPR YESSTR NOSTR CODESET LOG_EMERG LOG_ALERT LOG_CRIT LOG_ERR LOG_WARNING LOG_NOTICE LOG_INFO LOG_DEBUG LOG_KERN LOG_USER LOG_MAIL LOG_DAEMON LOG_AUTH LOG_SYSLOG LOG_LPR LOG_NEWS LOG_UUCP LOG_CRON LOG_AUTHPRIV LOG_LOCAL0 LOG_LOCAL1 LOG_LOCAL2 LOG_LOCAL3 LOG_LOCAL4 LOG_LOCAL5 LOG_LOCAL6 LOG_LOCAL7 LOG_PID LOG_CONS LOG_ODELAY LOG_NDELAY LOG_NOWAIT LOG_PERROR ] PREDEFINED = %w[ $GLOBALS $_SERVER $_GET $_POST $_FILES $_REQUEST $_SESSION $_ENV $_COOKIE $php_errormsg $HTTP_RAW_POST_DATA $http_response_header $argc $argv ] IDENT_KIND = WordList::CaseIgnoring.new(:ident). add(KEYWORDS, :keyword). add(TYPES, :predefined_type). add(LANGUAGE_CONSTRUCTS, :keyword). add(BUILTIN_FUNCTIONS, :predefined). add(CLASSES, :predefined_constant). add(EXCEPTIONS, :exception). add(CONSTANTS, :predefined_constant) VARIABLE_KIND = WordList.new(:local_variable). add(PREDEFINED, :predefined) end module RE # :nodoc: PHP_START = / ]*?language\s*=\s*"php"[^>]*?> | ]*?language\s*=\s*'php'[^>]*?> | <\?php\d? | <\?(?!xml) /xi PHP_END = %r! | \?> !xi HTML_INDICATOR = / ]/i IDENTIFIER = 'ä'[/[[:alpha:]]/] == 'ä' ? Regexp.new('[[:alpha:]_[^\0-\177]][[:alnum:]_[^\0-\177]]*') : Regexp.new('[a-z_\x7f-\xFF][a-z0-9_\x7f-\xFF]*', true) VARIABLE = /\$#{IDENTIFIER}/ OPERATOR = / \.(?!\d)=? | # dot that is not decimal point, string concatenation && | \|\| | # logic :: | -> | => | # scope, member, dictionary \\(?!\n) | # namespace \+\+ | -- | # increment, decrement [,;?:()\[\]{}] | # simple delimiters [-+*\/%&|^]=? | # ordinary math, binary logic, assignment shortcuts [~$] | # whatever =& | # reference assignment [=!]=?=? | <> | # comparison and assignment <<=? | >>=? | [<>]=? # comparison and shift /x end protected def scan_tokens encoder, options if check(RE::PHP_START) || # starts with #{RE::IDENTIFIER}/o) encoder.begin_group :inline encoder.text_token match, :local_variable encoder.text_token scan(/->/), :operator encoder.text_token scan(/#{RE::IDENTIFIER}/o), :ident encoder.end_group :inline elsif check(/->/) match << scan(/->/) encoder.text_token match, :error else encoder.text_token match, :local_variable end elsif match = scan(/\{/) if check(/\$/) encoder.begin_group :inline states[-1] = [states.last, delimiter] delimiter = nil states.push :php_inline encoder.text_token match, :delimiter else encoder.text_token match, :content end elsif match = scan(/\$\{#{RE::IDENTIFIER}\}/o) encoder.text_token match, :local_variable elsif match = scan(/\$/) encoder.text_token match, :content else encoder.end_group :string states.pop end when :class_expected if match = scan(/\s+/) encoder.text_token match, :space elsif match = scan(/#{RE::IDENTIFIER}/o) encoder.text_token match, :class states.pop else states.pop end when :function_expected if match = scan(/\s+/) encoder.text_token match, :space elsif match = scan(/&/) encoder.text_token match, :operator elsif match = scan(/#{RE::IDENTIFIER}/o) encoder.text_token match, :function states.pop else states.pop end else raise_inspect 'Unknown state!', encoder, states end end while state = states.pop encoder.end_group :string if [:sqstring, :dqstring].include? state if state.is_a? Array encoder.end_group :inline encoder.end_group :string if [:sqstring, :dqstring].include? state.first end end encoder end end end end coderay-1.1.1/lib/coderay/scanners/sass.rb0000644000004100000410000001720012663664402020507 0ustar www-datawww-datamodule CodeRay module Scanners # A scanner for Sass. class Sass < CSS register_for :sass file_extension 'sass' protected def setup @state = :initial end def scan_tokens encoder, options states = Array(options[:state] || @state).dup encoder.begin_group :string if states.last == :sqstring || states.last == :dqstring until eos? if bol? && (match = scan(/(?>( +)?(\/[\*\/])(.+)?)(?=\n)/)) encoder.text_token self[1], :space if self[1] encoder.begin_group :comment encoder.text_token self[2], :delimiter encoder.text_token self[3], :content if self[3] if match = scan(/(?:\n+#{self[1]} .*)+/) encoder.text_token match, :content end encoder.end_group :comment elsif match = scan(/\n|[^\n\S]+\n?/) encoder.text_token match, :space if match.index(/\n/) value_expected = false states.pop if states.last == :include end elsif states.last == :sass_inline && (match = scan(/\}/)) encoder.text_token match, :inline_delimiter encoder.end_group :inline states.pop elsif case states.last when :initial, :media, :sass_inline if match = scan(/(?>#{RE::Ident})(?!\()/ox) encoder.text_token match, value_expected ? :value : (check(/.*:(?![a-z])/) ? :key : :tag) next elsif !value_expected && (match = scan(/\*/)) encoder.text_token match, :tag next elsif match = scan(RE::Class) encoder.text_token match, :class next elsif match = scan(RE::Id) encoder.text_token match, :id next elsif match = scan(RE::PseudoClass) encoder.text_token match, :pseudo_class next elsif match = scan(RE::AttributeSelector) # TODO: Improve highlighting inside of attribute selectors. encoder.text_token match[0,1], :operator encoder.text_token match[1..-2], :attribute_name if match.size > 2 encoder.text_token match[-1,1], :operator if match[-1] == ?] next elsif match = scan(/(\=|@mixin +)#{RE::Ident}/o) encoder.text_token match, :function next elsif match = scan(/@import\b/) encoder.text_token match, :directive states << :include next elsif match = scan(/@media\b/) encoder.text_token match, :directive # states.push :media_before_name next end when :block if match = scan(/(?>#{RE::Ident})(?!\()/ox) if value_expected encoder.text_token match, :value else encoder.text_token match, :key end next end when :sqstring, :dqstring if match = scan(states.last == :sqstring ? /(?:[^\n\'\#]+|\\\n|#{RE::Escape}|#(?!\{))+/o : /(?:[^\n\"\#]+|\\\n|#{RE::Escape}|#(?!\{))+/o) encoder.text_token match, :content elsif match = scan(/['"]/) encoder.text_token match, :delimiter encoder.end_group :string states.pop elsif match = scan(/#\{/) encoder.begin_group :inline encoder.text_token match, :inline_delimiter states.push :sass_inline elsif match = scan(/ \\ | $ /x) encoder.end_group states.last encoder.text_token match, :error unless match.empty? states.pop else raise_inspect "else case #{states.last} reached; %p not handled." % peek(1), encoder end when :include if match = scan(/[^\s'",]+/) encoder.text_token match, :include next end else #:nocov: raise_inspect 'Unknown state: %p' % [states.last], encoder #:nocov: end elsif match = scan(/\$#{RE::Ident}/o) encoder.text_token match, :variable next elsif match = scan(/&/) encoder.text_token match, :local_variable elsif match = scan(/\+#{RE::Ident}/o) encoder.text_token match, :include value_expected = true elsif match = scan(/\/\*(?:.*?\*\/|.*)|\/\/.*/) encoder.text_token match, :comment elsif match = scan(/#\{/) encoder.begin_group :inline encoder.text_token match, :inline_delimiter states.push :sass_inline elsif match = scan(/\{/) value_expected = false encoder.text_token match, :operator states.push :block elsif match = scan(/\}/) value_expected = false encoder.text_token match, :operator if states.last == :block || states.last == :media states.pop end elsif match = scan(/['"]/) encoder.begin_group :string encoder.text_token match, :delimiter if states.include? :sass_inline # no nesting, just scan the string until delimiter content = scan_until(/(?=#{match}|\}|\z)/) encoder.text_token content, :content unless content.empty? encoder.text_token match, :delimiter if scan(/#{match}/) encoder.end_group :string else states.push match == "'" ? :sqstring : :dqstring end elsif match = scan(/#{RE::Function}/o) encoder.begin_group :function start = match[/^[-\w]+\(/] encoder.text_token start, :delimiter if match[-1] == ?) encoder.text_token match[start.size..-2], :content encoder.text_token ')', :delimiter else encoder.text_token match[start.size..-1], :content if start.size < match.size end encoder.end_group :function elsif match = scan(/[a-z][-a-z_]*(?=\()/o) encoder.text_token match, :predefined elsif match = scan(/(?: #{RE::Dimension} | #{RE::Percentage} | #{RE::Num} )/ox) encoder.text_token match, :float elsif match = scan(/#{RE::HexColor}/o) encoder.text_token match, :color elsif match = scan(/! *(?:important|optional)/) encoder.text_token match, :important elsif match = scan(/(?:rgb|hsl)a?\([^()\n]*\)?/) encoder.text_token match, :color elsif match = scan(/@else if\b|#{RE::AtKeyword}/o) encoder.text_token match, :directive value_expected = true elsif match = scan(/ == | != | [-+*\/>~:;,.=()] /x) if match == ':' value_expected = true elsif match == ';' value_expected = false end encoder.text_token match, :operator else encoder.text_token getch, :error end end states.pop if states.last == :include if options[:keep_state] @state = states.dup end while state = states.pop if state == :sass_inline encoder.end_group :inline elsif state == :sqstring || state == :dqstring encoder.end_group :string end end encoder end end end end coderay-1.1.1/lib/coderay/scanners/_map.rb0000644000004100000410000000076612663664402020463 0ustar www-datawww-datamodule CodeRay module Scanners map \ :'c++' => :cpp, :cplusplus => :cpp, :ecmascript => :java_script, :ecma_script => :java_script, :rhtml => :erb, :eruby => :erb, :irb => :ruby, :javascript => :java_script, :js => :java_script, :pascal => :delphi, :patch => :diff, :plain => :text, :plaintext => :text, :xhtml => :html, :yml => :yaml default :text end end coderay-1.1.1/lib/coderay/scanners/debug.rb0000644000004100000410000000337212663664402020631 0ustar www-datawww-datarequire 'set' module CodeRay module Scanners # = Debug Scanner # # Interprets the output of the Encoders::Debug encoder (basically the inverse function). class Debug < Scanner register_for :debug title 'CodeRay Token Dump Import' protected def setup super @known_token_kinds = TokenKinds.keys.map(&:to_s).to_set end def scan_tokens encoder, options opened_tokens = [] until eos? if match = scan(/\s+/) encoder.text_token match, :space elsif match = scan(/ (\w+) \( ( [^\)\\]* ( \\. [^\)\\]* )* ) \)? /x) if @known_token_kinds.include? self[1] encoder.text_token self[2].gsub(/\\(.)/m, '\1'), self[1].to_sym else encoder.text_token matched, :unknown end elsif match = scan(/ (\w+) ([<\[]) /x) if @known_token_kinds.include? self[1] kind = self[1].to_sym else kind = :unknown end opened_tokens << kind case self[2] when '<' encoder.begin_group kind when '[' encoder.begin_line kind else raise 'CodeRay bug: This case should not be reached.' end elsif !opened_tokens.empty? && match = scan(/ > /x) encoder.end_group opened_tokens.pop elsif !opened_tokens.empty? && match = scan(/ \] /x) encoder.end_line opened_tokens.pop else encoder.text_token getch, :space end end encoder.end_group opened_tokens.pop until opened_tokens.empty? encoder end end end end coderay-1.1.1/lib/coderay/scanners/css.rb0000644000004100000410000001357512663664402020341 0ustar www-datawww-datamodule CodeRay module Scanners class CSS < Scanner register_for :css KINDS_NOT_LOC = [ :comment, :class, :pseudo_class, :tag, :id, :directive, :key, :value, :operator, :color, :float, :string, :error, :important, :type, ] # :nodoc: module RE # :nodoc: Hex = /[0-9a-fA-F]/ Unicode = /\\#{Hex}{1,6}\b/ # differs from standard because it allows uppercase hex too Escape = /#{Unicode}|\\[^\n0-9a-fA-F]/ NMChar = /[-_a-zA-Z0-9]/ NMStart = /[_a-zA-Z]/ String1 = /"(?:[^\n\\"]+|\\\n|#{Escape})*"?/ # TODO: buggy regexp String2 = /'(?:[^\n\\']+|\\\n|#{Escape})*'?/ # TODO: buggy regexp String = /#{String1}|#{String2}/ HexColor = /#(?:#{Hex}{6}|#{Hex}{3})/ Num = /-?(?:[0-9]*\.[0-9]+|[0-9]+)n?/ Name = /#{NMChar}+/ Ident = /-?#{NMStart}#{NMChar}*/ AtKeyword = /@#{Ident}/ Percentage = /#{Num}%/ reldimensions = %w[em ex px] absdimensions = %w[in cm mm pt pc] Unit = Regexp.union(*(reldimensions + absdimensions + %w[s dpi dppx deg])) Dimension = /#{Num}#{Unit}/ Function = /(?:url|alpha|attr|counters?)\((?:[^)\n]|\\\))*\)?/ Id = /(?!#{HexColor}\b(?!-))##{Name}/ Class = /\.#{Name}/ PseudoClass = /::?#{Ident}/ AttributeSelector = /\[[^\]]*\]?/ end protected def setup @state = :initial @value_expected = false end def scan_tokens encoder, options states = Array(options[:state] || @state).dup value_expected = @value_expected until eos? if match = scan(/\s+/) encoder.text_token match, :space elsif case states.last when :initial, :media if match = scan(/(?>#{RE::Ident})(?!\()|\*/ox) encoder.text_token match, :tag next elsif match = scan(RE::Class) encoder.text_token match, :class next elsif match = scan(RE::Id) encoder.text_token match, :id next elsif match = scan(RE::PseudoClass) encoder.text_token match, :pseudo_class next elsif match = scan(RE::AttributeSelector) # TODO: Improve highlighting inside of attribute selectors. encoder.text_token match[0,1], :operator encoder.text_token match[1..-2], :attribute_name if match.size > 2 encoder.text_token match[-1,1], :operator if match[-1] == ?] next elsif match = scan(/@media/) encoder.text_token match, :directive states.push :media_before_name next end when :block if match = scan(/(?>#{RE::Ident})(?!\()/ox) if value_expected encoder.text_token match, :value else encoder.text_token match, :key end next end when :media_before_name if match = scan(RE::Ident) encoder.text_token match, :type states[-1] = :media_after_name next end when :media_after_name if match = scan(/\{/) encoder.text_token match, :operator states[-1] = :media next end else #:nocov: raise_inspect 'Unknown state', encoder #:nocov: end elsif match = scan(/\/\*(?:.*?\*\/|\z)/m) encoder.text_token match, :comment elsif match = scan(/\{/) value_expected = false encoder.text_token match, :operator states.push :block elsif match = scan(/\}/) value_expected = false encoder.text_token match, :operator if states.last == :block || states.last == :media states.pop end elsif match = scan(/#{RE::String}/o) encoder.begin_group :string encoder.text_token match[0, 1], :delimiter encoder.text_token match[1..-2], :content if match.size > 2 encoder.text_token match[-1, 1], :delimiter if match.size >= 2 encoder.end_group :string elsif match = scan(/#{RE::Function}/o) encoder.begin_group :function start = match[/^\w+\(/] encoder.text_token start, :delimiter if match[-1] == ?) encoder.text_token match[start.size..-2], :content if match.size > start.size + 1 encoder.text_token ')', :delimiter else encoder.text_token match[start.size..-1], :content if match.size > start.size end encoder.end_group :function elsif match = scan(/(?: #{RE::Dimension} | #{RE::Percentage} | #{RE::Num} )/ox) encoder.text_token match, :float elsif match = scan(/#{RE::HexColor}/o) encoder.text_token match, :color elsif match = scan(/! *important/) encoder.text_token match, :important elsif match = scan(/(?:rgb|hsl)a?\([^()\n]*\)?/) encoder.text_token match, :color elsif match = scan(RE::AtKeyword) encoder.text_token match, :directive elsif match = scan(/ [+>~:;,.=()\/] /x) if match == ':' value_expected = true elsif match == ';' value_expected = false end encoder.text_token match, :operator else encoder.text_token getch, :error end end if options[:keep_state] @state = states @value_expected = value_expected end encoder end end end end coderay-1.1.1/lib/coderay/scanners/scanner.rb0000644000004100000410000002253012663664402021171 0ustar www-datawww-data# encoding: utf-8 module CodeRay module Scanners # = Scanner # # The base class for all Scanners. # # It is a subclass of Ruby's great +StringScanner+, which # makes it easy to access the scanning methods inside. # # It is also +Enumerable+, so you can use it like an Array of # Tokens: # # require 'coderay' # # c_scanner = CodeRay::Scanners[:c].new "if (*p == '{') nest++;" # # for text, kind in c_scanner # puts text if kind == :operator # end # # # prints: (*==)++; # # OK, this is a very simple example :) # You can also use +map+, +any?+, +find+ and even +sort_by+, # if you want. class Scanner < StringScanner extend Plugin plugin_host Scanners # Raised if a Scanner fails while scanning ScanError = Class.new StandardError # The default options for all scanner classes. # # Define @default_options for subclasses. DEFAULT_OPTIONS = { } KINDS_NOT_LOC = [:comment, :doctype, :docstring] attr_accessor :state class << self # Normalizes the given code into a string with UNIX newlines, in the # scanner's internal encoding, with invalid and undefined charachters # replaced by placeholders. Always returns a new object. def normalize code # original = code code = code.to_s unless code.is_a? ::String return code if code.empty? if code.respond_to? :encoding code = encode_with_encoding code, self.encoding else code = to_unix code end # code = code.dup if code.eql? original code end # The typical filename suffix for this scanner's language. def file_extension extension = lang @file_extension ||= extension.to_s end # The encoding used internally by this scanner. def encoding name = 'UTF-8' @encoding ||= defined?(Encoding.find) && Encoding.find(name) end # The lang of this Scanner class, which is equal to its Plugin ID. def lang @plugin_id end protected def encode_with_encoding code, target_encoding if code.encoding == target_encoding if code.valid_encoding? return to_unix(code) else source_encoding = guess_encoding code end else source_encoding = code.encoding end # print "encode_with_encoding from #{source_encoding} to #{target_encoding}" code.encode target_encoding, source_encoding, :universal_newline => true, :undef => :replace, :invalid => :replace end def to_unix code code.index(?\r) ? code.gsub(/\r\n?/, "\n") : code end def guess_encoding s #:nocov: IO.popen("file -b --mime -", "w+") do |file| file.write s[0, 1024] file.close_write begin Encoding.find file.gets[/charset=([-\w]+)/, 1] rescue ArgumentError Encoding::BINARY end end #:nocov: end end # Create a new Scanner. # # * +code+ is the input String and is handled by the superclass # StringScanner. # * +options+ is a Hash with Symbols as keys. # It is merged with the default options of the class (you can # overwrite default options here.) # # Else, a Tokens object is used. def initialize code = '', options = {} if self.class == Scanner raise NotImplementedError, "I am only the basic Scanner class. I can't scan anything. :( Use my subclasses." end @options = self.class::DEFAULT_OPTIONS.merge options super self.class.normalize(code) @tokens = options[:tokens] || Tokens.new @tokens.scanner = self if @tokens.respond_to? :scanner= setup end # Sets back the scanner. Subclasses should redefine the reset_instance # method instead of this one. def reset super reset_instance end # Set a new string to be scanned. def string= code code = self.class.normalize(code) super code reset_instance end # the Plugin ID for this scanner def lang self.class.lang end # the default file extension for this scanner def file_extension self.class.file_extension end # Scan the code and returns all tokens in a Tokens object. def tokenize source = nil, options = {} options = @options.merge(options) set_tokens_from_options options set_string_from_source source begin scan_tokens @tokens, options rescue => e message = "Error in %s#scan_tokens, initial state was: %p" % [self.class, defined?(state) && state] raise_inspect e.message, @tokens, message, 30, e.backtrace end @cached_tokens = @tokens if source.is_a? Array @tokens.split_into_parts(*source.map { |part| part.size }) else @tokens end end # Cache the result of tokenize. def tokens @cached_tokens ||= tokenize end # Traverse the tokens. def each &block tokens.each(&block) end include Enumerable # The current line position of the scanner, starting with 1. # See also: #column. # # Beware, this is implemented inefficiently. It should be used # for debugging only. def line pos = self.pos return 1 if pos <= 0 binary_string[0...pos].count("\n") + 1 end # The current column position of the scanner, starting with 1. # See also: #line. def column pos = self.pos return 1 if pos <= 0 pos - (binary_string.rindex(?\n, pos - 1) || -1) end # The string in binary encoding. # # To be used with #pos, which is the index of the byte the scanner # will scan next. def binary_string @binary_string ||= if string.respond_to?(:bytesize) && string.bytesize != string.size #:nocov: string.dup.force_encoding('binary') #:nocov: else string end end protected # Can be implemented by subclasses to do some initialization # that has to be done once per instance. # # Use reset for initialization that has to be done once per # scan. def setup # :doc: end def set_string_from_source source case source when Array self.string = self.class.normalize(source.join) when nil reset else self.string = self.class.normalize(source) end end def set_tokens_from_options options @tokens = options[:tokens] || @tokens || Tokens.new @tokens.scanner = self if @tokens.respond_to? :scanner= end # This is the central method, and commonly the only one a # subclass implements. # # Subclasses must implement this method; it must return +tokens+ # and must only use Tokens#<< for storing scanned tokens! def scan_tokens tokens, options # :doc: raise NotImplementedError, "#{self.class}#scan_tokens not implemented." end # Resets the scanner. def reset_instance @tokens.clear if @tokens.respond_to?(:clear) && !@options[:keep_tokens] @cached_tokens = nil @binary_string = nil if defined? @binary_string end SCAN_ERROR_MESSAGE = <<-MESSAGE ***ERROR in %s: %s (after %s tokens) tokens: %s %s surrounding code: %p ~~ %p ***ERROR*** MESSAGE def raise_inspect_arguments message, tokens, state, ambit return File.basename(caller[0]), message, tokens_size(tokens), tokens_last(tokens, 10).map(&:inspect).join("\n"), scanner_state_info(state), binary_string[pos - ambit, ambit], binary_string[pos, ambit] end SCANNER_STATE_INFO = <<-INFO current line: %d column: %d pos: %d matched: %p state: %p bol?: %p, eos?: %p INFO def scanner_state_info state SCANNER_STATE_INFO % [ line, column, pos, matched, state || 'No state given!', bol?, eos?, ] end # Scanner error with additional status information def raise_inspect message, tokens, state = self.state, ambit = 30, backtrace = caller raise ScanError, SCAN_ERROR_MESSAGE % raise_inspect_arguments(message, tokens, state, ambit), backtrace end def tokens_size tokens tokens.size if tokens.respond_to?(:size) end def tokens_last tokens, n tokens.respond_to?(:last) ? tokens.last(n) : [] end # Shorthand for scan_until(/\z/). # This method also avoids a JRuby 1.9 mode bug. def scan_rest rest = self.rest terminate rest end end end end coderay-1.1.1/lib/coderay/scanners/c.rb0000644000004100000410000001300412663664402017756 0ustar www-datawww-datamodule CodeRay module Scanners # Scanner for C. class C < Scanner register_for :c file_extension 'c' KEYWORDS = [ 'asm', 'break', 'case', 'continue', 'default', 'do', 'else', 'enum', 'for', 'goto', 'if', 'return', 'sizeof', 'struct', 'switch', 'typedef', 'union', 'while', 'restrict', # added in C99 ] # :nodoc: PREDEFINED_TYPES = [ 'int', 'long', 'short', 'char', 'signed', 'unsigned', 'float', 'double', 'bool', 'complex', # added in C99 ] # :nodoc: PREDEFINED_CONSTANTS = [ 'EOF', 'NULL', 'true', 'false', # added in C99 ] # :nodoc: DIRECTIVES = [ 'auto', 'extern', 'register', 'static', 'void', 'const', 'volatile', # added in C89 'inline', # added in C99 ] # :nodoc: IDENT_KIND = WordList.new(:ident). add(KEYWORDS, :keyword). add(PREDEFINED_TYPES, :predefined_type). add(DIRECTIVES, :directive). add(PREDEFINED_CONSTANTS, :predefined_constant) # :nodoc: ESCAPE = / [rbfntv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc: UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x # :nodoc: protected def scan_tokens encoder, options state = :initial label_expected = true case_expected = false label_expected_before_preproc_line = nil in_preproc_line = false until eos? case state when :initial if match = scan(/ \s+ | \\\n /x) if in_preproc_line && match != "\\\n" && match.index(?\n) in_preproc_line = false label_expected = label_expected_before_preproc_line end encoder.text_token match, :space elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx) encoder.text_token match, :comment elsif match = scan(/ [-+*=<>?:;,!&^|()\[\]{}~%]+ | \/=? | \.(?!\d) /x) label_expected = match =~ /[;\{\}]/ if case_expected label_expected = true if match == ':' case_expected = false end encoder.text_token match, :operator elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x) kind = IDENT_KIND[match] if kind == :ident && label_expected && !in_preproc_line && scan(/:(?!:)/) kind = :label match << matched else label_expected = false if kind == :keyword case match when 'case', 'default' case_expected = true end end end encoder.text_token match, kind elsif match = scan(/L?"/) encoder.begin_group :string if match[0] == ?L encoder.text_token 'L', :modifier match = '"' end encoder.text_token match, :delimiter state = :string elsif match = scan(/ \# \s* if \s* 0 /x) match << scan_until(/ ^\# (?:elif|else|endif) .*? $ | \z /xm) unless eos? encoder.text_token match, :comment elsif match = scan(/#[ \t]*(\w*)/) encoder.text_token match, :preprocessor in_preproc_line = true label_expected_before_preproc_line = label_expected state = :include_expected if self[1] == 'include' elsif match = scan(/ L?' (?: [^\'\n\\] | \\ #{ESCAPE} )? '? /ox) label_expected = false encoder.text_token match, :char elsif match = scan(/\$/) encoder.text_token match, :ident elsif match = scan(/0[xX][0-9A-Fa-f]+/) label_expected = false encoder.text_token match, :hex elsif match = scan(/(?:0[0-7]+)(?![89.eEfF])/) label_expected = false encoder.text_token match, :octal elsif match = scan(/(?:\d+)(?![.eEfF])L?L?/) label_expected = false encoder.text_token match, :integer elsif match = scan(/\d[fF]?|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/) label_expected = false encoder.text_token match, :float else encoder.text_token getch, :error end when :string if match = scan(/[^\\\n"]+/) encoder.text_token match, :content elsif match = scan(/"/) encoder.text_token match, :delimiter encoder.end_group :string state = :initial label_expected = false elsif match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox) encoder.text_token match, :char elsif match = scan(/ \\ | $ /x) encoder.end_group :string encoder.text_token match, :error unless match.empty? state = :initial label_expected = false else raise_inspect "else case \" reached; %p not handled." % peek(1), encoder end when :include_expected if match = scan(/<[^>\n]+>?|"[^"\n\\]*(?:\\.[^"\n\\]*)*"?/) encoder.text_token match, :include state = :initial elsif match = scan(/\s+/) encoder.text_token match, :space state = :initial if match.index ?\n else state = :initial end else raise_inspect 'Unknown state', encoder end end if state == :string encoder.end_group :string end encoder end end end end coderay-1.1.1/lib/coderay/scanners/erb.rb0000644000004100000410000000341612663664402020312 0ustar www-datawww-datamodule CodeRay module Scanners load :html load :ruby # Scanner for HTML ERB templates. class ERB < Scanner register_for :erb title 'HTML ERB Template' KINDS_NOT_LOC = HTML::KINDS_NOT_LOC ERB_RUBY_BLOCK = / (<%(?!%)[-=\#]?) ((?> [^\-%]* # normal* (?> # special (?: %(?!>) | -(?!%>) ) [^\-%]* # normal* )* )) ((?: -?%> )?) /x # :nodoc: START_OF_ERB = / <%(?!%) /x # :nodoc: protected def setup @ruby_scanner = CodeRay.scanner :ruby, :tokens => @tokens, :keep_tokens => true @html_scanner = CodeRay.scanner :html, :tokens => @tokens, :keep_tokens => true, :keep_state => true end def reset_instance super @html_scanner.reset end def scan_tokens encoder, options until eos? if (match = scan_until(/(?=#{START_OF_ERB})/o) || scan_rest) and not match.empty? @html_scanner.tokenize match, :tokens => encoder elsif match = scan(/#{ERB_RUBY_BLOCK}/o) start_tag = self[1] code = self[2] end_tag = self[3] encoder.begin_group :inline encoder.text_token start_tag, :inline_delimiter if start_tag == '<%#' encoder.text_token code, :comment else @ruby_scanner.tokenize code, :tokens => encoder end unless code.empty? encoder.text_token end_tag, :inline_delimiter unless end_tag.empty? encoder.end_group :inline else raise_inspect 'else-case reached!', encoder end end encoder end end end end coderay-1.1.1/lib/coderay/scanners/java.rb0000644000004100000410000001274312663664402020466 0ustar www-datawww-datamodule CodeRay module Scanners # Scanner for Java. class Java < Scanner register_for :java autoload :BuiltinTypes, CodeRay.coderay_path('scanners', 'java', 'builtin_types') # http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html KEYWORDS = %w[ assert break case catch continue default do else finally for if instanceof import new package return switch throw try typeof while debugger export ] # :nodoc: RESERVED = %w[ const goto ] # :nodoc: CONSTANTS = %w[ false null true ] # :nodoc: MAGIC_VARIABLES = %w[ this super ] # :nodoc: TYPES = %w[ boolean byte char class double enum float int interface long short void ] << '[]' # :nodoc: because int[] should be highlighted as a type DIRECTIVES = %w[ abstract extends final implements native private protected public static strictfp synchronized throws transient volatile ] # :nodoc: IDENT_KIND = WordList.new(:ident). add(KEYWORDS, :keyword). add(RESERVED, :reserved). add(CONSTANTS, :predefined_constant). add(MAGIC_VARIABLES, :local_variable). add(TYPES, :type). add(BuiltinTypes::List, :predefined_type). add(BuiltinTypes::List.select { |builtin| builtin[/(Error|Exception)$/] }, :exception). add(DIRECTIVES, :directive) # :nodoc: ESCAPE = / [bfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc: UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x # :nodoc: STRING_CONTENT_PATTERN = { "'" => /[^\\']+/, '"' => /[^\\"]+/, '/' => /[^\\\/]+/, } # :nodoc: IDENT = /[a-zA-Z_][A-Za-z_0-9]*/ # :nodoc: protected def scan_tokens encoder, options state = :initial string_delimiter = nil package_name_expected = false class_name_follows = false last_token_dot = false until eos? case state when :initial if match = scan(/ \s+ | \\\n /x) encoder.text_token match, :space next elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx) encoder.text_token match, :comment next elsif package_name_expected && match = scan(/ #{IDENT} (?: \. #{IDENT} )* /ox) encoder.text_token match, package_name_expected elsif match = scan(/ #{IDENT} | \[\] /ox) kind = IDENT_KIND[match] if last_token_dot kind = :ident elsif class_name_follows kind = :class class_name_follows = false else case match when 'import' package_name_expected = :include when 'package' package_name_expected = :namespace when 'class', 'interface' class_name_follows = true end end encoder.text_token match, kind elsif match = scan(/ \.(?!\d) | [,?:()\[\]}] | -- | \+\+ | && | \|\| | \*\*=? | [-+*\/%^~&|<>=!]=? | <<>>?=? /x) encoder.text_token match, :operator elsif match = scan(/;/) package_name_expected = false encoder.text_token match, :operator elsif match = scan(/\{/) class_name_follows = false encoder.text_token match, :operator elsif check(/[\d.]/) if match = scan(/0[xX][0-9A-Fa-f]+/) encoder.text_token match, :hex elsif match = scan(/(?>0[0-7]+)(?![89.eEfF])/) encoder.text_token match, :octal elsif match = scan(/\d+[fFdD]|\d*\.\d+(?:[eE][+-]?\d+)?[fFdD]?|\d+[eE][+-]?\d+[fFdD]?/) encoder.text_token match, :float elsif match = scan(/\d+[lL]?/) encoder.text_token match, :integer end elsif match = scan(/["']/) state = :string encoder.begin_group state string_delimiter = match encoder.text_token match, :delimiter elsif match = scan(/ @ #{IDENT} /ox) encoder.text_token match, :annotation else encoder.text_token getch, :error end when :string if match = scan(STRING_CONTENT_PATTERN[string_delimiter]) encoder.text_token match, :content elsif match = scan(/["'\/]/) encoder.text_token match, :delimiter encoder.end_group state state = :initial string_delimiter = nil elsif state == :string && (match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)) if string_delimiter == "'" && !(match == "\\\\" || match == "\\'") encoder.text_token match, :content else encoder.text_token match, :char end elsif match = scan(/\\./m) encoder.text_token match, :content elsif match = scan(/ \\ | $ /x) encoder.end_group state state = :initial encoder.text_token match, :error unless match.empty? else raise_inspect "else case \" reached; %p not handled." % peek(1), encoder end else raise_inspect 'Unknown state', encoder end last_token_dot = match == '.' end if state == :string encoder.end_group state end encoder end end end end coderay-1.1.1/lib/coderay/scanners/java/0000755000004100000410000000000012663664402020132 5ustar www-datawww-datacoderay-1.1.1/lib/coderay/scanners/java/builtin_types.rb0000644000004100000410000012150212663664402023352 0ustar www-datawww-datamodule CodeRay module Scanners module Java::BuiltinTypes # :nodoc: #:nocov: List = %w[ AbstractAction AbstractBorder AbstractButton AbstractCellEditor AbstractCollection AbstractColorChooserPanel AbstractDocument AbstractExecutorService AbstractInterruptibleChannel AbstractLayoutCache AbstractList AbstractListModel AbstractMap AbstractMethodError AbstractPreferences AbstractQueue AbstractQueuedSynchronizer AbstractSelectableChannel AbstractSelectionKey AbstractSelector AbstractSequentialList AbstractSet AbstractSpinnerModel AbstractTableModel AbstractUndoableEdit AbstractWriter AccessControlContext AccessControlException AccessController AccessException Accessible AccessibleAction AccessibleAttributeSequence AccessibleBundle AccessibleComponent AccessibleContext AccessibleEditableText AccessibleExtendedComponent AccessibleExtendedTable AccessibleExtendedText AccessibleHyperlink AccessibleHypertext AccessibleIcon AccessibleKeyBinding AccessibleObject AccessibleRelation AccessibleRelationSet AccessibleResourceBundle AccessibleRole AccessibleSelection AccessibleState AccessibleStateSet AccessibleStreamable AccessibleTable AccessibleTableModelChange AccessibleText AccessibleTextSequence AccessibleValue AccountException AccountExpiredException AccountLockedException AccountNotFoundException Acl AclEntry AclNotFoundException Action ActionEvent ActionListener ActionMap ActionMapUIResource Activatable ActivateFailedException ActivationDesc ActivationException ActivationGroup ActivationGroupDesc ActivationGroupID ActivationGroup_Stub ActivationID ActivationInstantiator ActivationMonitor ActivationSystem Activator ActiveEvent ActivityCompletedException ActivityRequiredException Adjustable AdjustmentEvent AdjustmentListener Adler32 AffineTransform AffineTransformOp AlgorithmParameterGenerator AlgorithmParameterGeneratorSpi AlgorithmParameters AlgorithmParameterSpec AlgorithmParametersSpi AllPermission AlphaComposite AlreadyBoundException AlreadyConnectedException AncestorEvent AncestorListener AnnotatedElement Annotation AnnotationFormatError AnnotationTypeMismatchException AppConfigurationEntry Appendable Applet AppletContext AppletInitializer AppletStub Arc2D Area AreaAveragingScaleFilter ArithmeticException Array ArrayBlockingQueue ArrayIndexOutOfBoundsException ArrayList Arrays ArrayStoreException ArrayType AssertionError AsyncBoxView AsynchronousCloseException AtomicBoolean AtomicInteger AtomicIntegerArray AtomicIntegerFieldUpdater AtomicLong AtomicLongArray AtomicLongFieldUpdater AtomicMarkableReference AtomicReference AtomicReferenceArray AtomicReferenceFieldUpdater AtomicStampedReference Attribute AttributeChangeNotification AttributeChangeNotificationFilter AttributedCharacterIterator AttributedString AttributeException AttributeInUseException AttributeList AttributeModificationException AttributeNotFoundException Attributes AttributeSet AttributeSetUtilities AttributeValueExp AudioClip AudioFileFormat AudioFileReader AudioFileWriter AudioFormat AudioInputStream AudioPermission AudioSystem AuthenticationException AuthenticationNotSupportedException Authenticator AuthorizeCallback AuthPermission AuthProvider Autoscroll AWTError AWTEvent AWTEventListener AWTEventListenerProxy AWTEventMulticaster AWTException AWTKeyStroke AWTPermission BackingStoreException BadAttributeValueExpException BadBinaryOpValueExpException BadLocationException BadPaddingException BadStringOperationException BandCombineOp BandedSampleModel BaseRowSet BasicArrowButton BasicAttribute BasicAttributes BasicBorders BasicButtonListener BasicButtonUI BasicCheckBoxMenuItemUI BasicCheckBoxUI BasicColorChooserUI BasicComboBoxEditor BasicComboBoxRenderer BasicComboBoxUI BasicComboPopup BasicControl BasicDesktopIconUI BasicDesktopPaneUI BasicDirectoryModel BasicEditorPaneUI BasicFileChooserUI BasicFormattedTextFieldUI BasicGraphicsUtils BasicHTML BasicIconFactory BasicInternalFrameTitlePane BasicInternalFrameUI BasicLabelUI BasicListUI BasicLookAndFeel BasicMenuBarUI BasicMenuItemUI BasicMenuUI BasicOptionPaneUI BasicPanelUI BasicPasswordFieldUI BasicPermission BasicPopupMenuSeparatorUI BasicPopupMenuUI BasicProgressBarUI BasicRadioButtonMenuItemUI BasicRadioButtonUI BasicRootPaneUI BasicScrollBarUI BasicScrollPaneUI BasicSeparatorUI BasicSliderUI BasicSpinnerUI BasicSplitPaneDivider BasicSplitPaneUI BasicStroke BasicTabbedPaneUI BasicTableHeaderUI BasicTableUI BasicTextAreaUI BasicTextFieldUI BasicTextPaneUI BasicTextUI BasicToggleButtonUI BasicToolBarSeparatorUI BasicToolBarUI BasicToolTipUI BasicTreeUI BasicViewportUI BatchUpdateException BeanContext BeanContextChild BeanContextChildComponentProxy BeanContextChildSupport BeanContextContainerProxy BeanContextEvent BeanContextMembershipEvent BeanContextMembershipListener BeanContextProxy BeanContextServiceAvailableEvent BeanContextServiceProvider BeanContextServiceProviderBeanInfo BeanContextServiceRevokedEvent BeanContextServiceRevokedListener BeanContextServices BeanContextServicesListener BeanContextServicesSupport BeanContextSupport BeanDescriptor BeanInfo Beans BevelBorder Bidi BigDecimal BigInteger BinaryRefAddr BindException Binding BitSet Blob BlockingQueue BlockView BMPImageWriteParam Book Boolean BooleanControl Border BorderFactory BorderLayout BorderUIResource BoundedRangeModel Box BoxLayout BoxView BreakIterator BrokenBarrierException Buffer BufferCapabilities BufferedImage BufferedImageFilter BufferedImageOp BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter BufferOverflowException BufferStrategy BufferUnderflowException Button ButtonGroup ButtonModel ButtonUI Byte ByteArrayInputStream ByteArrayOutputStream ByteBuffer ByteChannel ByteLookupTable ByteOrder CachedRowSet CacheRequest CacheResponse Calendar Callable CallableStatement Callback CallbackHandler CancelablePrintJob CancellationException CancelledKeyException CannotProceedException CannotRedoException CannotUndoException Canvas CardLayout Caret CaretEvent CaretListener CellEditor CellEditorListener CellRendererPane Certificate CertificateEncodingException CertificateException CertificateExpiredException CertificateFactory CertificateFactorySpi CertificateNotYetValidException CertificateParsingException CertPath CertPathBuilder CertPathBuilderException CertPathBuilderResult CertPathBuilderSpi CertPathParameters CertPathTrustManagerParameters CertPathValidator CertPathValidatorException CertPathValidatorResult CertPathValidatorSpi CertSelector CertStore CertStoreException CertStoreParameters CertStoreSpi ChangedCharSetException ChangeEvent ChangeListener Channel Channels Character CharacterCodingException CharacterIterator CharArrayReader CharArrayWriter CharBuffer CharConversionException CharSequence Charset CharsetDecoder CharsetEncoder CharsetProvider Checkbox CheckboxGroup CheckboxMenuItem CheckedInputStream CheckedOutputStream Checksum Choice ChoiceCallback ChoiceFormat Chromaticity Cipher CipherInputStream CipherOutputStream CipherSpi Class ClassCastException ClassCircularityError ClassDefinition ClassDesc ClassFileTransformer ClassFormatError ClassLoader ClassLoaderRepository ClassLoadingMXBean ClassNotFoundException Clip Clipboard ClipboardOwner Clob Cloneable CloneNotSupportedException Closeable ClosedByInterruptException ClosedChannelException ClosedSelectorException CMMException CoderMalfunctionError CoderResult CodeSigner CodeSource CodingErrorAction CollationElementIterator CollationKey Collator Collection CollectionCertStoreParameters Collections Color ColorChooserComponentFactory ColorChooserUI ColorConvertOp ColorModel ColorSelectionModel ColorSpace ColorSupported ColorType ColorUIResource ComboBoxEditor ComboBoxModel ComboBoxUI ComboPopup CommunicationException Comparable Comparator CompilationMXBean Compiler CompletionService Component ComponentAdapter ComponentColorModel ComponentEvent ComponentInputMap ComponentInputMapUIResource ComponentListener ComponentOrientation ComponentSampleModel ComponentUI ComponentView Composite CompositeContext CompositeData CompositeDataSupport CompositeName CompositeType CompositeView CompoundBorder CompoundControl CompoundEdit CompoundName Compression ConcurrentHashMap ConcurrentLinkedQueue ConcurrentMap ConcurrentModificationException Condition Configuration ConfigurationException ConfirmationCallback ConnectException ConnectIOException Connection ConnectionEvent ConnectionEventListener ConnectionPendingException ConnectionPoolDataSource ConsoleHandler Constructor Container ContainerAdapter ContainerEvent ContainerListener ContainerOrderFocusTraversalPolicy ContentHandler ContentHandlerFactory ContentModel Context ContextNotEmptyException ContextualRenderedImageFactory Control ControlFactory ControllerEventListener ConvolveOp CookieHandler Copies CopiesSupported CopyOnWriteArrayList CopyOnWriteArraySet CountDownLatch CounterMonitor CounterMonitorMBean CRC32 CredentialException CredentialExpiredException CredentialNotFoundException CRL CRLException CRLSelector CropImageFilter CSS CubicCurve2D Currency Cursor Customizer CyclicBarrier DatabaseMetaData DataBuffer DataBufferByte DataBufferDouble DataBufferFloat DataBufferInt DataBufferShort DataBufferUShort DataFlavor DataFormatException DatagramChannel DatagramPacket DatagramSocket DatagramSocketImpl DatagramSocketImplFactory DataInput DataInputStream DataLine DataOutput DataOutputStream DataSource DataTruncation DatatypeConfigurationException DatatypeConstants DatatypeFactory Date DateFormat DateFormatSymbols DateFormatter DateTimeAtCompleted DateTimeAtCreation DateTimeAtProcessing DateTimeSyntax DebugGraphics DecimalFormat DecimalFormatSymbols DefaultBoundedRangeModel DefaultButtonModel DefaultCaret DefaultCellEditor DefaultColorSelectionModel DefaultComboBoxModel DefaultDesktopManager DefaultEditorKit DefaultFocusManager DefaultFocusTraversalPolicy DefaultFormatter DefaultFormatterFactory DefaultHighlighter DefaultKeyboardFocusManager DefaultListCellRenderer DefaultListModel DefaultListSelectionModel DefaultLoaderRepository DefaultMenuLayout DefaultMetalTheme DefaultMutableTreeNode DefaultPersistenceDelegate DefaultSingleSelectionModel DefaultStyledDocument DefaultTableCellRenderer DefaultTableColumnModel DefaultTableModel DefaultTextUI DefaultTreeCellEditor DefaultTreeCellRenderer DefaultTreeModel DefaultTreeSelectionModel Deflater DeflaterOutputStream Delayed DelayQueue DelegationPermission Deprecated Descriptor DescriptorAccess DescriptorSupport DESedeKeySpec DesignMode DESKeySpec DesktopIconUI DesktopManager DesktopPaneUI Destination Destroyable DestroyFailedException DGC DHGenParameterSpec DHKey DHParameterSpec DHPrivateKey DHPrivateKeySpec DHPublicKey DHPublicKeySpec Dialog Dictionary DigestException DigestInputStream DigestOutputStream Dimension Dimension2D DimensionUIResource DirContext DirectColorModel DirectoryManager DirObjectFactory DirStateFactory DisplayMode DnDConstants Doc DocAttribute DocAttributeSet DocFlavor DocPrintJob Document DocumentBuilder DocumentBuilderFactory Documented DocumentEvent DocumentFilter DocumentListener DocumentName DocumentParser DomainCombiner DOMLocator DOMResult DOMSource Double DoubleBuffer DragGestureEvent DragGestureListener DragGestureRecognizer DragSource DragSourceAdapter DragSourceContext DragSourceDragEvent DragSourceDropEvent DragSourceEvent DragSourceListener DragSourceMotionListener Driver DriverManager DriverPropertyInfo DropTarget DropTargetAdapter DropTargetContext DropTargetDragEvent DropTargetDropEvent DropTargetEvent DropTargetListener DSAKey DSAKeyPairGenerator DSAParameterSpec DSAParams DSAPrivateKey DSAPrivateKeySpec DSAPublicKey DSAPublicKeySpec DTD DTDConstants DuplicateFormatFlagsException Duration DynamicMBean ECField ECFieldF2m ECFieldFp ECGenParameterSpec ECKey ECParameterSpec ECPoint ECPrivateKey ECPrivateKeySpec ECPublicKey ECPublicKeySpec EditorKit Element ElementIterator ElementType Ellipse2D EllipticCurve EmptyBorder EmptyStackException EncodedKeySpec Encoder EncryptedPrivateKeyInfo Entity Enum EnumConstantNotPresentException EnumControl Enumeration EnumMap EnumSet EnumSyntax EOFException Error ErrorListener ErrorManager EtchedBorder Event EventContext EventDirContext EventHandler EventListener EventListenerList EventListenerProxy EventObject EventQueue EventSetDescriptor Exception ExceptionInInitializerError ExceptionListener Exchanger ExecutionException Executor ExecutorCompletionService Executors ExecutorService ExemptionMechanism ExemptionMechanismException ExemptionMechanismSpi ExpandVetoException ExportException Expression ExtendedRequest ExtendedResponse Externalizable FactoryConfigurationError FailedLoginException FeatureDescriptor Fidelity Field FieldPosition FieldView File FileCacheImageInputStream FileCacheImageOutputStream FileChannel FileChooserUI FileDescriptor FileDialog FileFilter FileHandler FileImageInputStream FileImageOutputStream FileInputStream FileLock FileLockInterruptionException FilenameFilter FileNameMap FileNotFoundException FileOutputStream FilePermission FileReader FileSystemView FileView FileWriter Filter FilteredImageSource FilteredRowSet FilterInputStream FilterOutputStream FilterReader FilterWriter Finishings FixedHeightLayoutCache FlatteningPathIterator FlavorEvent FlavorException FlavorListener FlavorMap FlavorTable Float FloatBuffer FloatControl FlowLayout FlowView Flushable FocusAdapter FocusEvent FocusListener FocusManager FocusTraversalPolicy Font FontFormatException FontMetrics FontRenderContext FontUIResource Format FormatConversionProvider FormatFlagsConversionMismatchException Formattable FormattableFlags Formatter FormatterClosedException FormSubmitEvent FormView Frame Future FutureTask GapContent GarbageCollectorMXBean GatheringByteChannel GaugeMonitor GaugeMonitorMBean GeneralPath GeneralSecurityException GenericArrayType GenericDeclaration GenericSignatureFormatError GlyphJustificationInfo GlyphMetrics GlyphVector GlyphView GradientPaint GraphicAttribute Graphics Graphics2D GraphicsConfigTemplate GraphicsConfiguration GraphicsDevice GraphicsEnvironment GrayFilter GregorianCalendar GridBagConstraints GridBagLayout GridLayout Group Guard GuardedObject GZIPInputStream GZIPOutputStream Handler HandshakeCompletedEvent HandshakeCompletedListener HasControls HashAttributeSet HashDocAttributeSet HashMap HashPrintJobAttributeSet HashPrintRequestAttributeSet HashPrintServiceAttributeSet HashSet Hashtable HeadlessException HierarchyBoundsAdapter HierarchyBoundsListener HierarchyEvent HierarchyListener Highlighter HostnameVerifier HTML HTMLDocument HTMLEditorKit HTMLFrameHyperlinkEvent HTMLWriter HttpRetryException HttpsURLConnection HttpURLConnection HyperlinkEvent HyperlinkListener ICC_ColorSpace ICC_Profile ICC_ProfileGray ICC_ProfileRGB Icon IconUIResource IconView Identity IdentityHashMap IdentityScope IIOByteBuffer IIOException IIOImage IIOInvalidTreeException IIOMetadata IIOMetadataController IIOMetadataFormat IIOMetadataFormatImpl IIOMetadataNode IIOParam IIOParamController IIOReadProgressListener IIOReadUpdateListener IIOReadWarningListener IIORegistry IIOServiceProvider IIOWriteProgressListener IIOWriteWarningListener IllegalAccessError IllegalAccessException IllegalArgumentException IllegalBlockingModeException IllegalBlockSizeException IllegalCharsetNameException IllegalClassFormatException IllegalComponentStateException IllegalFormatCodePointException IllegalFormatConversionException IllegalFormatException IllegalFormatFlagsException IllegalFormatPrecisionException IllegalFormatWidthException IllegalMonitorStateException IllegalPathStateException IllegalSelectorException IllegalStateException IllegalThreadStateException Image ImageCapabilities ImageConsumer ImageFilter ImageGraphicAttribute ImageIcon ImageInputStream ImageInputStreamImpl ImageInputStreamSpi ImageIO ImageObserver ImageOutputStream ImageOutputStreamImpl ImageOutputStreamSpi ImageProducer ImageReader ImageReaderSpi ImageReaderWriterSpi ImageReadParam ImageTranscoder ImageTranscoderSpi ImageTypeSpecifier ImageView ImageWriteParam ImageWriter ImageWriterSpi ImagingOpException IncompatibleClassChangeError IncompleteAnnotationException IndexColorModel IndexedPropertyChangeEvent IndexedPropertyDescriptor IndexOutOfBoundsException Inet4Address Inet6Address InetAddress InetSocketAddress Inflater InflaterInputStream InheritableThreadLocal Inherited InitialContext InitialContextFactory InitialContextFactoryBuilder InitialDirContext InitialLdapContext InlineView InputContext InputEvent InputMap InputMapUIResource InputMethod InputMethodContext InputMethodDescriptor InputMethodEvent InputMethodHighlight InputMethodListener InputMethodRequests InputMismatchException InputStream InputStreamReader InputSubset InputVerifier Insets InsetsUIResource InstanceAlreadyExistsException InstanceNotFoundException InstantiationError InstantiationException Instrument Instrumentation InsufficientResourcesException IntBuffer Integer IntegerSyntax InternalError InternalFrameAdapter InternalFrameEvent InternalFrameFocusTraversalPolicy InternalFrameListener InternalFrameUI InternationalFormatter InterruptedException InterruptedIOException InterruptedNamingException InterruptibleChannel IntrospectionException Introspector InvalidActivityException InvalidAlgorithmParameterException InvalidApplicationException InvalidAttributeIdentifierException InvalidAttributesException InvalidAttributeValueException InvalidClassException InvalidDnDOperationException InvalidKeyException InvalidKeySpecException InvalidMarkException InvalidMidiDataException InvalidNameException InvalidObjectException InvalidOpenTypeException InvalidParameterException InvalidParameterSpecException InvalidPreferencesFormatException InvalidPropertiesFormatException InvalidRelationIdException InvalidRelationServiceException InvalidRelationTypeException InvalidRoleInfoException InvalidRoleValueException InvalidSearchControlsException InvalidSearchFilterException InvalidTargetObjectTypeException InvalidTransactionException InvocationEvent InvocationHandler InvocationTargetException IOException ItemEvent ItemListener ItemSelectable Iterable Iterator IvParameterSpec JApplet JarEntry JarException JarFile JarInputStream JarOutputStream JarURLConnection JButton JCheckBox JCheckBoxMenuItem JColorChooser JComboBox JComponent JdbcRowSet JDesktopPane JDialog JEditorPane JFileChooser JFormattedTextField JFrame JInternalFrame JLabel JLayeredPane JList JMenu JMenuBar JMenuItem JMException JMRuntimeException JMXAuthenticator JMXConnectionNotification JMXConnector JMXConnectorFactory JMXConnectorProvider JMXConnectorServer JMXConnectorServerFactory JMXConnectorServerMBean JMXConnectorServerProvider JMXPrincipal JMXProviderException JMXServerErrorException JMXServiceURL JobAttributes JobHoldUntil JobImpressions JobImpressionsCompleted JobImpressionsSupported JobKOctets JobKOctetsProcessed JobKOctetsSupported JobMediaSheets JobMediaSheetsCompleted JobMediaSheetsSupported JobMessageFromOperator JobName JobOriginatingUserName JobPriority JobPrioritySupported JobSheets JobState JobStateReason JobStateReasons Joinable JoinRowSet JOptionPane JPanel JPasswordField JPEGHuffmanTable JPEGImageReadParam JPEGImageWriteParam JPEGQTable JPopupMenu JProgressBar JRadioButton JRadioButtonMenuItem JRootPane JScrollBar JScrollPane JSeparator JSlider JSpinner JSplitPane JTabbedPane JTable JTableHeader JTextArea JTextComponent JTextField JTextPane JToggleButton JToolBar JToolTip JTree JViewport JWindow KerberosKey KerberosPrincipal KerberosTicket Kernel Key KeyAdapter KeyAgreement KeyAgreementSpi KeyAlreadyExistsException KeyboardFocusManager KeyEvent KeyEventDispatcher KeyEventPostProcessor KeyException KeyFactory KeyFactorySpi KeyGenerator KeyGeneratorSpi KeyListener KeyManagementException KeyManager KeyManagerFactory KeyManagerFactorySpi Keymap KeyPair KeyPairGenerator KeyPairGeneratorSpi KeyRep KeySpec KeyStore KeyStoreBuilderParameters KeyStoreException KeyStoreSpi KeyStroke Label LabelUI LabelView LanguageCallback LastOwnerException LayeredHighlighter LayoutFocusTraversalPolicy LayoutManager LayoutManager2 LayoutQueue LDAPCertStoreParameters LdapContext LdapName LdapReferralException Lease Level LimitExceededException Line Line2D LineBorder LineBreakMeasurer LineEvent LineListener LineMetrics LineNumberInputStream LineNumberReader LineUnavailableException LinkageError LinkedBlockingQueue LinkedHashMap LinkedHashSet LinkedList LinkException LinkLoopException LinkRef List ListCellRenderer ListDataEvent ListDataListener ListenerNotFoundException ListIterator ListModel ListResourceBundle ListSelectionEvent ListSelectionListener ListSelectionModel ListUI ListView LoaderHandler Locale LocateRegistry Lock LockSupport Logger LoggingMXBean LoggingPermission LoginContext LoginException LoginModule LogManager LogRecord LogStream Long LongBuffer LookAndFeel LookupOp LookupTable Mac MacSpi MalformedInputException MalformedLinkException MalformedObjectNameException MalformedParameterizedTypeException MalformedURLException ManagementFactory ManagementPermission ManageReferralControl ManagerFactoryParameters Manifest Map MappedByteBuffer MarshalException MarshalledObject MaskFormatter Matcher MatchResult Math MathContext MatteBorder MBeanAttributeInfo MBeanConstructorInfo MBeanException MBeanFeatureInfo MBeanInfo MBeanNotificationInfo MBeanOperationInfo MBeanParameterInfo MBeanPermission MBeanRegistration MBeanRegistrationException MBeanServer MBeanServerBuilder MBeanServerConnection MBeanServerDelegate MBeanServerDelegateMBean MBeanServerFactory MBeanServerForwarder MBeanServerInvocationHandler MBeanServerNotification MBeanServerNotificationFilter MBeanServerPermission MBeanTrustPermission Media MediaName MediaPrintableArea MediaSize MediaSizeName MediaTracker MediaTray Member MemoryCacheImageInputStream MemoryCacheImageOutputStream MemoryHandler MemoryImageSource MemoryManagerMXBean MemoryMXBean MemoryNotificationInfo MemoryPoolMXBean MemoryType MemoryUsage Menu MenuBar MenuBarUI MenuComponent MenuContainer MenuDragMouseEvent MenuDragMouseListener MenuElement MenuEvent MenuItem MenuItemUI MenuKeyEvent MenuKeyListener MenuListener MenuSelectionManager MenuShortcut MessageDigest MessageDigestSpi MessageFormat MetaEventListener MetalBorders MetalButtonUI MetalCheckBoxIcon MetalCheckBoxUI MetalComboBoxButton MetalComboBoxEditor MetalComboBoxIcon MetalComboBoxUI MetalDesktopIconUI MetalFileChooserUI MetalIconFactory MetalInternalFrameTitlePane MetalInternalFrameUI MetalLabelUI MetalLookAndFeel MetalMenuBarUI MetalPopupMenuSeparatorUI MetalProgressBarUI MetalRadioButtonUI MetalRootPaneUI MetalScrollBarUI MetalScrollButton MetalScrollPaneUI MetalSeparatorUI MetalSliderUI MetalSplitPaneUI MetalTabbedPaneUI MetalTextFieldUI MetalTheme MetalToggleButtonUI MetalToolBarUI MetalToolTipUI MetalTreeUI MetaMessage Method MethodDescriptor MGF1ParameterSpec MidiChannel MidiDevice MidiDeviceProvider MidiEvent MidiFileFormat MidiFileReader MidiFileWriter MidiMessage MidiSystem MidiUnavailableException MimeTypeParseException MinimalHTMLWriter MissingFormatArgumentException MissingFormatWidthException MissingResourceException Mixer MixerProvider MLet MLetMBean ModelMBean ModelMBeanAttributeInfo ModelMBeanConstructorInfo ModelMBeanInfo ModelMBeanInfoSupport ModelMBeanNotificationBroadcaster ModelMBeanNotificationInfo ModelMBeanOperationInfo ModificationItem Modifier Monitor MonitorMBean MonitorNotification MonitorSettingException MouseAdapter MouseDragGestureRecognizer MouseEvent MouseInfo MouseInputAdapter MouseInputListener MouseListener MouseMotionAdapter MouseMotionListener MouseWheelEvent MouseWheelListener MultiButtonUI MulticastSocket MultiColorChooserUI MultiComboBoxUI MultiDesktopIconUI MultiDesktopPaneUI MultiDoc MultiDocPrintJob MultiDocPrintService MultiFileChooserUI MultiInternalFrameUI MultiLabelUI MultiListUI MultiLookAndFeel MultiMenuBarUI MultiMenuItemUI MultiOptionPaneUI MultiPanelUI MultiPixelPackedSampleModel MultipleDocumentHandling MultipleMaster MultiPopupMenuUI MultiProgressBarUI MultiRootPaneUI MultiScrollBarUI MultiScrollPaneUI MultiSeparatorUI MultiSliderUI MultiSpinnerUI MultiSplitPaneUI MultiTabbedPaneUI MultiTableHeaderUI MultiTableUI MultiTextUI MultiToolBarUI MultiToolTipUI MultiTreeUI MultiViewportUI MutableAttributeSet MutableComboBoxModel MutableTreeNode Name NameAlreadyBoundException NameCallback NameClassPair NameNotFoundException NameParser NamespaceChangeListener NamespaceContext Naming NamingEnumeration NamingEvent NamingException NamingExceptionEvent NamingListener NamingManager NamingSecurityException NavigationFilter NegativeArraySizeException NetPermission NetworkInterface NoClassDefFoundError NoConnectionPendingException NodeChangeEvent NodeChangeListener NoInitialContextException NoninvertibleTransformException NonReadableChannelException NonWritableChannelException NoPermissionException NoRouteToHostException NoSuchAlgorithmException NoSuchAttributeException NoSuchElementException NoSuchFieldError NoSuchFieldException NoSuchMethodError NoSuchMethodException NoSuchObjectException NoSuchPaddingException NoSuchProviderException NotActiveException NotBoundException NotCompliantMBeanException NotContextException Notification NotificationBroadcaster NotificationBroadcasterSupport NotificationEmitter NotificationFilter NotificationFilterSupport NotificationListener NotificationResult NotOwnerException NotSerializableException NotYetBoundException NotYetConnectedException NullCipher NullPointerException Number NumberFormat NumberFormatException NumberFormatter NumberOfDocuments NumberOfInterveningJobs NumberUp NumberUpSupported NumericShaper OAEPParameterSpec Object ObjectChangeListener ObjectFactory ObjectFactoryBuilder ObjectInput ObjectInputStream ObjectInputValidation ObjectInstance ObjectName ObjectOutput ObjectOutputStream ObjectStreamClass ObjectStreamConstants ObjectStreamException ObjectStreamField ObjectView ObjID Observable Observer OceanTheme OpenDataException OpenMBeanAttributeInfo OpenMBeanAttributeInfoSupport OpenMBeanConstructorInfo OpenMBeanConstructorInfoSupport OpenMBeanInfo OpenMBeanInfoSupport OpenMBeanOperationInfo OpenMBeanOperationInfoSupport OpenMBeanParameterInfo OpenMBeanParameterInfoSupport OpenType OperatingSystemMXBean Operation OperationNotSupportedException OperationsException Option OptionalDataException OptionPaneUI OrientationRequested OutOfMemoryError OutputDeviceAssigned OutputKeys OutputStream OutputStreamWriter OverlappingFileLockException OverlayLayout Override Owner Pack200 Package PackedColorModel Pageable PageAttributes PagedResultsControl PagedResultsResponseControl PageFormat PageRanges PagesPerMinute PagesPerMinuteColor Paint PaintContext PaintEvent Panel PanelUI Paper ParagraphView ParameterBlock ParameterDescriptor ParameterizedType ParameterMetaData ParseException ParsePosition Parser ParserConfigurationException ParserDelegator PartialResultException PasswordAuthentication PasswordCallback PasswordView Patch PathIterator Pattern PatternSyntaxException PBEKey PBEKeySpec PBEParameterSpec PDLOverrideSupported Permission PermissionCollection Permissions PersistenceDelegate PersistentMBean PhantomReference Pipe PipedInputStream PipedOutputStream PipedReader PipedWriter PixelGrabber PixelInterleavedSampleModel PKCS8EncodedKeySpec PKIXBuilderParameters PKIXCertPathBuilderResult PKIXCertPathChecker PKIXCertPathValidatorResult PKIXParameters PlainDocument PlainView Point Point2D PointerInfo Policy PolicyNode PolicyQualifierInfo Polygon PooledConnection Popup PopupFactory PopupMenu PopupMenuEvent PopupMenuListener PopupMenuUI Port PortableRemoteObject PortableRemoteObjectDelegate PortUnreachableException Position Predicate PreferenceChangeEvent PreferenceChangeListener Preferences PreferencesFactory PreparedStatement PresentationDirection Principal Printable PrinterAbortException PrinterException PrinterGraphics PrinterInfo PrinterIOException PrinterIsAcceptingJobs PrinterJob PrinterLocation PrinterMakeAndModel PrinterMessageFromOperator PrinterMoreInfo PrinterMoreInfoManufacturer PrinterName PrinterResolution PrinterState PrinterStateReason PrinterStateReasons PrinterURI PrintEvent PrintException PrintGraphics PrintJob PrintJobAdapter PrintJobAttribute PrintJobAttributeEvent PrintJobAttributeListener PrintJobAttributeSet PrintJobEvent PrintJobListener PrintQuality PrintRequestAttribute PrintRequestAttributeSet PrintService PrintServiceAttribute PrintServiceAttributeEvent PrintServiceAttributeListener PrintServiceAttributeSet PrintServiceLookup PrintStream PrintWriter PriorityBlockingQueue PriorityQueue PrivateClassLoader PrivateCredentialPermission PrivateKey PrivateMLet PrivilegedAction PrivilegedActionException PrivilegedExceptionAction Process ProcessBuilder ProfileDataException ProgressBarUI ProgressMonitor ProgressMonitorInputStream Properties PropertyChangeEvent PropertyChangeListener PropertyChangeListenerProxy PropertyChangeSupport PropertyDescriptor PropertyEditor PropertyEditorManager PropertyEditorSupport PropertyPermission PropertyResourceBundle PropertyVetoException ProtectionDomain ProtocolException Provider ProviderException Proxy ProxySelector PSource PSSParameterSpec PublicKey PushbackInputStream PushbackReader QName QuadCurve2D Query QueryEval QueryExp Queue QueuedJobCount Random RandomAccess RandomAccessFile Raster RasterFormatException RasterOp RC2ParameterSpec RC5ParameterSpec Rdn Readable ReadableByteChannel Reader ReadOnlyBufferException ReadWriteLock RealmCallback RealmChoiceCallback Receiver Rectangle Rectangle2D RectangularShape ReentrantLock ReentrantReadWriteLock Ref RefAddr Reference Referenceable ReferenceQueue ReferenceUriSchemesSupported ReferralException ReflectionException ReflectPermission Refreshable RefreshFailedException Region RegisterableService Registry RegistryHandler RejectedExecutionException RejectedExecutionHandler Relation RelationException RelationNotFoundException RelationNotification RelationService RelationServiceMBean RelationServiceNotRegisteredException RelationSupport RelationSupportMBean RelationType RelationTypeNotFoundException RelationTypeSupport Remote RemoteCall RemoteException RemoteObject RemoteObjectInvocationHandler RemoteRef RemoteServer RemoteStub RenderableImage RenderableImageOp RenderableImageProducer RenderContext RenderedImage RenderedImageFactory Renderer RenderingHints RepaintManager ReplicateScaleFilter RequestingUserName RequiredModelMBean RescaleOp ResolutionSyntax Resolver ResolveResult ResourceBundle ResponseCache Result ResultSet ResultSetMetaData Retention RetentionPolicy ReverbType RGBImageFilter RMIClassLoader RMIClassLoaderSpi RMIClientSocketFactory RMIConnection RMIConnectionImpl RMIConnectionImpl_Stub RMIConnector RMIConnectorServer RMIFailureHandler RMIIIOPServerImpl RMIJRMPServerImpl RMISecurityException RMISecurityManager RMIServer RMIServerImpl RMIServerImpl_Stub RMIServerSocketFactory RMISocketFactory Robot Role RoleInfo RoleInfoNotFoundException RoleList RoleNotFoundException RoleResult RoleStatus RoleUnresolved RoleUnresolvedList RootPaneContainer RootPaneUI RoundingMode RoundRectangle2D RowMapper RowSet RowSetEvent RowSetInternal RowSetListener RowSetMetaData RowSetMetaDataImpl RowSetReader RowSetWarning RowSetWriter RSAKey RSAKeyGenParameterSpec RSAMultiPrimePrivateCrtKey RSAMultiPrimePrivateCrtKeySpec RSAOtherPrimeInfo RSAPrivateCrtKey RSAPrivateCrtKeySpec RSAPrivateKey RSAPrivateKeySpec RSAPublicKey RSAPublicKeySpec RTFEditorKit RuleBasedCollator Runnable Runtime RuntimeErrorException RuntimeException RuntimeMBeanException RuntimeMXBean RuntimeOperationsException RuntimePermission SampleModel Sasl SaslClient SaslClientFactory SaslException SaslServer SaslServerFactory Savepoint SAXParser SAXParserFactory SAXResult SAXSource SAXTransformerFactory Scanner ScatteringByteChannel ScheduledExecutorService ScheduledFuture ScheduledThreadPoolExecutor Schema SchemaFactory SchemaFactoryLoader SchemaViolationException Scrollable Scrollbar ScrollBarUI ScrollPane ScrollPaneAdjustable ScrollPaneConstants ScrollPaneLayout ScrollPaneUI SealedObject SearchControls SearchResult SecretKey SecretKeyFactory SecretKeyFactorySpi SecretKeySpec SecureCacheResponse SecureClassLoader SecureRandom SecureRandomSpi Security SecurityException SecurityManager SecurityPermission Segment SelectableChannel SelectionKey Selector SelectorProvider Semaphore SeparatorUI Sequence SequenceInputStream Sequencer SerialArray SerialBlob SerialClob SerialDatalink SerialException Serializable SerializablePermission SerialJavaObject SerialRef SerialStruct ServerCloneException ServerError ServerException ServerNotActiveException ServerRef ServerRuntimeException ServerSocket ServerSocketChannel ServerSocketFactory ServiceNotFoundException ServicePermission ServiceRegistry ServiceUI ServiceUIFactory ServiceUnavailableException Set SetOfIntegerSyntax Severity Shape ShapeGraphicAttribute SheetCollate Short ShortBuffer ShortBufferException ShortLookupTable ShortMessage Sides Signature SignatureException SignatureSpi SignedObject Signer SimpleAttributeSet SimpleBeanInfo SimpleDateFormat SimpleDoc SimpleFormatter SimpleTimeZone SimpleType SinglePixelPackedSampleModel SingleSelectionModel Size2DSyntax SizeLimitExceededException SizeRequirements SizeSequence Skeleton SkeletonMismatchException SkeletonNotFoundException SliderUI Socket SocketAddress SocketChannel SocketException SocketFactory SocketHandler SocketImpl SocketImplFactory SocketOptions SocketPermission SocketSecurityException SocketTimeoutException SoftBevelBorder SoftReference SortControl SortedMap SortedSet SortingFocusTraversalPolicy SortKey SortResponseControl Soundbank SoundbankReader SoundbankResource Source SourceDataLine SourceLocator SpinnerDateModel SpinnerListModel SpinnerModel SpinnerNumberModel SpinnerUI SplitPaneUI Spring SpringLayout SQLData SQLException SQLInput SQLInputImpl SQLOutput SQLOutputImpl SQLPermission SQLWarning SSLContext SSLContextSpi SSLEngine SSLEngineResult SSLException SSLHandshakeException SSLKeyException SSLPeerUnverifiedException SSLPermission SSLProtocolException SslRMIClientSocketFactory SslRMIServerSocketFactory SSLServerSocket SSLServerSocketFactory SSLSession SSLSessionBindingEvent SSLSessionBindingListener SSLSessionContext SSLSocket SSLSocketFactory Stack StackOverflowError StackTraceElement StandardMBean StartTlsRequest StartTlsResponse StateEdit StateEditable StateFactory Statement StreamCorruptedException StreamHandler StreamPrintService StreamPrintServiceFactory StreamResult StreamSource StreamTokenizer StrictMath String StringBuffer StringBufferInputStream StringBuilder StringCharacterIterator StringContent StringIndexOutOfBoundsException StringMonitor StringMonitorMBean StringReader StringRefAddr StringSelection StringTokenizer StringValueExp StringWriter Stroke Struct Stub StubDelegate StubNotFoundException Style StyleConstants StyleContext StyledDocument StyledEditorKit StyleSheet Subject SubjectDelegationPermission SubjectDomainCombiner SupportedValuesAttribute SuppressWarnings SwingConstants SwingPropertyChangeSupport SwingUtilities SyncFactory SyncFactoryException SyncFailedException SynchronousQueue SyncProvider SyncProviderException SyncResolver SynthConstants SynthContext Synthesizer SynthGraphicsUtils SynthLookAndFeel SynthPainter SynthStyle SynthStyleFactory SysexMessage System SystemColor SystemFlavorMap TabableView TabbedPaneUI TabExpander TableCellEditor TableCellRenderer TableColumn TableColumnModel TableColumnModelEvent TableColumnModelListener TableHeaderUI TableModel TableModelEvent TableModelListener TableUI TableView TabSet TabStop TabularData TabularDataSupport TabularType TagElement Target TargetDataLine TargetedNotification Templates TemplatesHandler TextAction TextArea TextAttribute TextComponent TextEvent TextField TextHitInfo TextInputCallback TextLayout TextListener TextMeasurer TextOutputCallback TextSyntax TextUI TexturePaint Thread ThreadDeath ThreadFactory ThreadGroup ThreadInfo ThreadLocal ThreadMXBean ThreadPoolExecutor Throwable Tie TileObserver Time TimeLimitExceededException TimeoutException Timer TimerAlarmClockNotification TimerMBean TimerNotification TimerTask Timestamp TimeUnit TimeZone TitledBorder ToolBarUI Toolkit ToolTipManager ToolTipUI TooManyListenersException Track TransactionalWriter TransactionRequiredException TransactionRolledbackException Transferable TransferHandler TransformAttribute Transformer TransformerConfigurationException TransformerException TransformerFactory TransformerFactoryConfigurationError TransformerHandler Transmitter Transparency TreeCellEditor TreeCellRenderer TreeExpansionEvent TreeExpansionListener TreeMap TreeModel TreeModelEvent TreeModelListener TreeNode TreePath TreeSelectionEvent TreeSelectionListener TreeSelectionModel TreeSet TreeUI TreeWillExpandListener TrustAnchor TrustManager TrustManagerFactory TrustManagerFactorySpi Type TypeInfoProvider TypeNotPresentException Types TypeVariable UID UIDefaults UIManager UIResource UndeclaredThrowableException UndoableEdit UndoableEditEvent UndoableEditListener UndoableEditSupport UndoManager UnexpectedException UnicastRemoteObject UnknownError UnknownFormatConversionException UnknownFormatFlagsException UnknownGroupException UnknownHostException UnknownObjectException UnknownServiceException UnmappableCharacterException UnmarshalException UnmodifiableClassException UnmodifiableSetException UnrecoverableEntryException UnrecoverableKeyException Unreferenced UnresolvedAddressException UnresolvedPermission UnsatisfiedLinkError UnsolicitedNotification UnsolicitedNotificationEvent UnsolicitedNotificationListener UnsupportedAddressTypeException UnsupportedAudioFileException UnsupportedCallbackException UnsupportedCharsetException UnsupportedClassVersionError UnsupportedEncodingException UnsupportedFlavorException UnsupportedLookAndFeelException UnsupportedOperationException URI URIException URIResolver URISyntax URISyntaxException URL URLClassLoader URLConnection URLDecoder URLEncoder URLStreamHandler URLStreamHandlerFactory UTFDataFormatException Util UtilDelegate Utilities UUID Validator ValidatorHandler ValueExp ValueHandler ValueHandlerMultiFormat VariableHeightLayoutCache Vector VerifyError VetoableChangeListener VetoableChangeListenerProxy VetoableChangeSupport View ViewFactory ViewportLayout ViewportUI VirtualMachineError Visibility VMID VoiceStatus Void VolatileImage WeakHashMap WeakReference WebRowSet WildcardType Window WindowAdapter WindowConstants WindowEvent WindowFocusListener WindowListener WindowStateListener WrappedPlainView WritableByteChannel WritableRaster WritableRenderedImage WriteAbortedException Writer X500Principal X500PrivateCredential X509Certificate X509CertSelector X509CRL X509CRLEntry X509CRLSelector X509EncodedKeySpec X509ExtendedKeyManager X509Extension X509KeyManager X509TrustManager XAConnection XADataSource XAException XAResource Xid XMLConstants XMLDecoder XMLEncoder XMLFormatter XMLGregorianCalendar XMLParseException XmlReader XmlWriter XPath XPathConstants XPathException XPathExpression XPathExpressionException XPathFactory XPathFactoryConfigurationException XPathFunction XPathFunctionException XPathFunctionResolver XPathVariableResolver ZipEntry ZipException ZipFile ZipInputStream ZipOutputStream ZoneView ] #:nocov: end end end coderay-1.1.1/lib/coderay/scanners/lua.rb0000644000004100000410000002571112663664402020325 0ustar www-datawww-data# encoding: utf-8 module CodeRay module Scanners # Scanner for the Lua[http://lua.org] programming lanuage. # # The language’s complete syntax is defined in # {the Lua manual}[http://www.lua.org/manual/5.2/manual.html], # which is what this scanner tries to conform to. class Lua < Scanner register_for :lua file_extension 'lua' title 'Lua' # Keywords used in Lua. KEYWORDS = %w[and break do else elseif end for function goto if in local not or repeat return then until while ] # Constants set by the Lua core. PREDEFINED_CONSTANTS = %w[false true nil] # The expressions contained in this array are parts of Lua’s `basic' # library. Although it’s not entirely necessary to load that library, # it is highly recommended and one would have to provide own implementations # of some of these expressions if one does not do so. They however aren’t # keywords, neither are they constants, but nearly predefined, so they # get tagged as `predefined' rather than anything else. # # This list excludes values of form `_UPPERCASE' because the Lua manual # requires such identifiers to be reserved by Lua anyway and they are # highlighted directly accordingly, without the need for specific # identifiers to be listed here. PREDEFINED_EXPRESSIONS = %w[ assert collectgarbage dofile error getmetatable ipairs load loadfile next pairs pcall print rawequal rawget rawlen rawset select setmetatable tonumber tostring type xpcall ] # Automatic token kind selection for normal words. IDENT_KIND = CodeRay::WordList.new(:ident). add(KEYWORDS, :keyword). add(PREDEFINED_CONSTANTS, :predefined_constant). add(PREDEFINED_EXPRESSIONS, :predefined) protected # Scanner initialization. def setup @state = :initial @brace_depth = 0 end # CodeRay entry hook. Starts parsing. def scan_tokens(encoder, options) state = options[:state] || @state brace_depth = @brace_depth num_equals = nil until eos? case state when :initial if match = scan(/\-\-\[\=*\[/) #--[[ long (possibly multiline) comment ]] num_equals = match.count("=") # Number must match for comment end encoder.begin_group(:comment) encoder.text_token(match, :delimiter) state = :long_comment elsif match = scan(/--.*$/) # --Lua comment encoder.text_token(match, :comment) elsif match = scan(/\[=*\[/) # [[ long (possibly multiline) string ]] num_equals = match.count("=") # Number must match for comment end encoder.begin_group(:string) encoder.text_token(match, :delimiter) state = :long_string elsif match = scan(/::\s*[a-zA-Z_][a-zA-Z0-9_]+\s*::/) # ::goto_label:: encoder.text_token(match, :label) elsif match = scan(/_[A-Z]+/) # _UPPERCASE are names reserved for Lua encoder.text_token(match, :predefined) elsif match = scan(/[a-zA-Z_][a-zA-Z0-9_]*/) # Normal letters (or letters followed by digits) kind = IDENT_KIND[match] # Extra highlighting for entities following certain keywords if kind == :keyword and match == "function" state = :function_expected elsif kind == :keyword and match == "goto" state = :goto_label_expected elsif kind == :keyword and match == "local" state = :local_var_expected end encoder.text_token(match, kind) elsif match = scan(/\{/) # Opening table brace { encoder.begin_group(:map) encoder.text_token(match, brace_depth >= 1 ? :inline_delimiter : :delimiter) brace_depth += 1 state = :map elsif match = scan(/\}/) # Closing table brace } if brace_depth == 1 brace_depth = 0 encoder.text_token(match, :delimiter) encoder.end_group(:map) elsif brace_depth == 0 # Mismatched brace encoder.text_token(match, :error) else brace_depth -= 1 encoder.text_token(match, :inline_delimiter) encoder.end_group(:map) state = :map end elsif match = scan(/["']/) # String delimiters " and ' encoder.begin_group(:string) encoder.text_token(match, :delimiter) start_delim = match state = :string # ↓Prefix hex number ←|→ decimal number elsif match = scan(/-? (?:0x\h* \. \h+ (?:p[+\-]?\d+)? | \d*\.\d+ (?:e[+\-]?\d+)?)/ix) # hexadecimal constants have no E power, decimal ones no P power encoder.text_token(match, :float) # ↓Prefix hex number ←|→ decimal number elsif match = scan(/-? (?:0x\h+ (?:p[+\-]?\d+)? | \d+ (?:e[+\-]?\d+)?)/ix) # hexadecimal constants have no E power, decimal ones no P power encoder.text_token(match, :integer) elsif match = scan(/[\+\-\*\/%^\#=~<>\(\)\[\]:;,] | \.(?!\d)/x) # Operators encoder.text_token(match, :operator) elsif match = scan(/\s+/) # Space encoder.text_token(match, :space) else # Invalid stuff. Note that Lua doesn’t accept multibyte chars outside of strings, hence these are also errors. encoder.text_token(getch, :error) end # It may be that we’re scanning a full-blown subexpression of a table # (tables can contain full expressions in parts). # If this is the case, return to :map scanning state. state = :map if state == :initial && brace_depth >= 1 when :function_expected if match = scan(/\(.*?\)/m) # x = function() # "Anonymous" function without explicit name encoder.text_token(match, :operator) state = :initial elsif match = scan(/[a-zA-Z_] (?:[a-zA-Z0-9_\.] (?!\.\d))* [\.\:]/x) # function tbl.subtbl.foo() | function tbl:foo() # Colon only allowed as last separator encoder.text_token(match, :ident) elsif match = scan(/[a-zA-Z_][a-zA-Z0-9_]*/) # function foo() encoder.text_token(match, :function) state = :initial elsif match = scan(/\s+/) # Between the `function' keyword and the ident may be any amount of whitespace encoder.text_token(match, :space) else encoder.text_token(getch, :error) state = :initial end when :goto_label_expected if match = scan(/[a-zA-Z_][a-zA-Z0-9_]*/) encoder.text_token(match, :label) state = :initial elsif match = scan(/\s+/) # Between the `goto' keyword and the label may be any amount of whitespace encoder.text_token(match, :space) else encoder.text_token(getch, :error) end when :local_var_expected if match = scan(/function/) # local function ... encoder.text_token(match, :keyword) state = :function_expected elsif match = scan(/[a-zA-Z_][a-zA-Z0-9_]*/) encoder.text_token(match, :local_variable) elsif match = scan(/,/) encoder.text_token(match, :operator) elsif match = scan(/\=/) encoder.text_token(match, :operator) # After encountering the equal sign, arbitrary expressions are # allowed again, so just return to the main state for further # parsing. state = :initial elsif match = scan(/\n/) encoder.text_token(match, :space) state = :initial elsif match = scan(/\s+/) encoder.text_token(match, :space) else encoder.text_token(getch, :error) end when :long_comment if match = scan(/.*?(?=\]={#{num_equals}}\])/m) encoder.text_token(match, :content) delim = scan(/\]={#{num_equals}}\]/) encoder.text_token(delim, :delimiter) else # No terminator found till EOF encoder.text_token(rest, :error) terminate end encoder.end_group(:comment) state = :initial when :long_string if match = scan(/.*?(?=\]={#{num_equals}}\])/m) # Long strings do not interpret any escape sequences encoder.text_token(match, :content) delim = scan(/\]={#{num_equals}}\]/) encoder.text_token(delim, :delimiter) else # No terminator found till EOF encoder.text_token(rest, :error) terminate end encoder.end_group(:string) state = :initial when :string if match = scan(/[^\\#{start_delim}\n]+/) # Everything except \ and the start delimiter character is string content (newlines are only allowed if preceeded by \ or \z) encoder.text_token(match, :content) elsif match = scan(/\\(?:['"abfnrtv\\]|z\s*|x\h\h|\d{1,3}|\n)/m) encoder.text_token(match, :char) elsif match = scan(Regexp.compile(start_delim)) encoder.text_token(match, :delimiter) encoder.end_group(:string) state = :initial elsif match = scan(/\n/) # Lua forbids unescaped newlines in normal non-long strings encoder.text_token("\\n\n", :error) # Visually appealing error indicator--otherwise users may wonder whether the highlighter cannot highlight multine strings encoder.end_group(:string) state = :initial else encoder.text_token(getch, :error) end when :map if match = scan(/[,;]/) encoder.text_token(match, :operator) elsif match = scan(/[a-zA-Z_][a-zA-Z0-9_]* (?=\s*=)/x) encoder.text_token(match, :key) encoder.text_token(scan(/\s+/), :space) if check(/\s+/) encoder.text_token(scan(/\=/), :operator) state = :initial elsif match = scan(/\s+/m) encoder.text_token(match, :space) else # Note this clause doesn’t advance the scan pointer, it’s a kind of # "retry with other options" (the :initial state then of course # advances the pointer). state = :initial end else raise end end if options[:keep_state] @state = state end encoder.end_group :string if [:string].include? state brace_depth.times { encoder.end_group :map } encoder end end end end coderay-1.1.1/lib/coderay/scanners/haml.rb0000644000004100000410000001207312663664402020462 0ustar www-datawww-datamodule CodeRay module Scanners load :ruby load :html load :java_script class HAML < Scanner register_for :haml title 'HAML Template' KINDS_NOT_LOC = HTML::KINDS_NOT_LOC protected def setup super @ruby_scanner = CodeRay.scanner :ruby, :tokens => @tokens, :keep_tokens => true @embedded_ruby_scanner = CodeRay.scanner :ruby, :tokens => @tokens, :keep_tokens => true, :state => @ruby_scanner.interpreted_string_state @html_scanner = CodeRay.scanner :html, :tokens => @tokens, :keep_tokens => true end def scan_tokens encoder, options match = nil code = '' until eos? if bol? if match = scan(/!!!.*/) encoder.text_token match, :doctype next end if match = scan(/(?>( *)(\/(?!\[if)|-\#|:javascript|:ruby|:\w+) *)(?=\n)/) encoder.text_token match, :comment code = self[2] if match = scan(/(?:\n+#{self[1]} .*)+/) case code when '/', '-#' encoder.text_token match, :comment when ':javascript' # TODO: recognize #{...} snippets inside JavaScript @java_script_scanner ||= CodeRay.scanner :java_script, :tokens => @tokens, :keep_tokens => true @java_script_scanner.tokenize match, :tokens => encoder when ':ruby' @ruby_scanner.tokenize match, :tokens => encoder when /:\w+/ encoder.text_token match, :comment else raise 'else-case reached: %p' % [code] end end end if match = scan(/ +/) encoder.text_token match, :space end if match = scan(/\/.*/) encoder.text_token match, :comment next end if match = scan(/\\/) encoder.text_token match, :plain if match = scan(/.+/) @html_scanner.tokenize match, :tokens => encoder end next end tag = false if match = scan(/%[\w:]+\/?/) encoder.text_token match, :tag # if match = scan(/( +)(.+)/) # encoder.text_token self[1], :space # @embedded_ruby_scanner.tokenize self[2], :tokens => encoder # end tag = true end while match = scan(/([.#])[-\w]*\w/) encoder.text_token match, self[1] == '#' ? :constant : :class tag = true end if tag && match = scan(/(\()([^)]+)?(\))?/) # TODO: recognize title=@title, class="widget_#{@widget.number}" encoder.text_token self[1], :plain @html_scanner.tokenize self[2], :tokens => encoder, :state => :attribute if self[2] encoder.text_token self[3], :plain if self[3] end if tag && match = scan(/\{/) encoder.text_token match, :plain code = '' level = 1 while true code << scan(/([^\{\},\n]|, *\n?)*/) case match = getch when '{' level += 1 code << match when '}' level -= 1 if level > 0 code << match else break end when "\n", ",", nil break end end @ruby_scanner.tokenize code, :tokens => encoder unless code.empty? encoder.text_token match, :plain if match end if tag && match = scan(/(\[)([^\]\n]+)?(\])?/) encoder.text_token self[1], :plain @ruby_scanner.tokenize self[2], :tokens => encoder if self[2] encoder.text_token self[3], :plain if self[3] end if tag && match = scan(/\//) encoder.text_token match, :tag end if scan(/(>? encoder else @ruby_scanner.tokenize self[4], :tokens => encoder end end elsif match = scan(/((?:<|> encoder if self[2] end elsif match = scan(/.+/) @html_scanner.tokenize match, :tokens => encoder end if match = scan(/\n/) encoder.text_token match, :space end end encoder end end end end coderay-1.1.1/lib/coderay/scanners/cpp.rb0000644000004100000410000001474012663664402020326 0ustar www-datawww-datamodule CodeRay module Scanners # Scanner for C++. # # Aliases: +cplusplus+, c++ class CPlusPlus < Scanner register_for :cpp file_extension 'cpp' title 'C++' #-- http://www.cppreference.com/wiki/keywords/start KEYWORDS = [ 'and', 'and_eq', 'asm', 'bitand', 'bitor', 'break', 'case', 'catch', 'class', 'compl', 'const_cast', 'continue', 'default', 'delete', 'do', 'dynamic_cast', 'else', 'enum', 'export', 'for', 'goto', 'if', 'namespace', 'new', 'not', 'not_eq', 'or', 'or_eq', 'reinterpret_cast', 'return', 'sizeof', 'static_cast', 'struct', 'switch', 'template', 'throw', 'try', 'typedef', 'typeid', 'typename', 'union', 'while', 'xor', 'xor_eq', ] # :nodoc: PREDEFINED_TYPES = [ 'bool', 'char', 'double', 'float', 'int', 'long', 'short', 'signed', 'unsigned', 'wchar_t', 'string', ] # :nodoc: PREDEFINED_CONSTANTS = [ 'false', 'true', 'EOF', 'NULL', ] # :nodoc: PREDEFINED_VARIABLES = [ 'this', ] # :nodoc: DIRECTIVES = [ 'auto', 'const', 'explicit', 'extern', 'friend', 'inline', 'mutable', 'operator', 'private', 'protected', 'public', 'register', 'static', 'using', 'virtual', 'void', 'volatile', ] # :nodoc: IDENT_KIND = WordList.new(:ident). add(KEYWORDS, :keyword). add(PREDEFINED_TYPES, :predefined_type). add(PREDEFINED_VARIABLES, :local_variable). add(DIRECTIVES, :directive). add(PREDEFINED_CONSTANTS, :predefined_constant) # :nodoc: ESCAPE = / [rbfntv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc: UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x # :nodoc: protected def scan_tokens encoder, options state = :initial label_expected = true case_expected = false label_expected_before_preproc_line = nil in_preproc_line = false until eos? case state when :initial if match = scan(/ \s+ | \\\n /x) if in_preproc_line && match != "\\\n" && match.index(?\n) in_preproc_line = false label_expected = label_expected_before_preproc_line end encoder.text_token match, :space elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx) encoder.text_token match, :comment elsif match = scan(/ \# \s* if \s* 0 /x) match << scan_until(/ ^\# (?:elif|else|endif) .*? $ | \z /xm) unless eos? encoder.text_token match, :comment elsif match = scan(/ [-+*=<>?:;,!&^|()\[\]{}~%]+ | \/=? | \.(?!\d) /x) label_expected = match =~ /[;\{\}]/ if case_expected label_expected = true if match == ':' case_expected = false end encoder.text_token match, :operator elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x) kind = IDENT_KIND[match] if kind == :ident && label_expected && !in_preproc_line && scan(/:(?!:)/) kind = :label match << matched else label_expected = false if kind == :keyword case match when 'class' state = :class_name_expected when 'case', 'default' case_expected = true end end end encoder.text_token match, kind elsif match = scan(/\$/) encoder.text_token match, :ident elsif match = scan(/L?"/) encoder.begin_group :string if match[0] == ?L encoder.text_token match, 'L', :modifier match = '"' end state = :string encoder.text_token match, :delimiter elsif match = scan(/#[ \t]*(\w*)/) encoder.text_token match, :preprocessor in_preproc_line = true label_expected_before_preproc_line = label_expected state = :include_expected if self[1] == 'include' elsif match = scan(/ L?' (?: [^\'\n\\] | \\ #{ESCAPE} )? '? /ox) label_expected = false encoder.text_token match, :char elsif match = scan(/0[xX][0-9A-Fa-f]+/) label_expected = false encoder.text_token match, :hex elsif match = scan(/(?:0[0-7]+)(?![89.eEfF])/) label_expected = false encoder.text_token match, :octal elsif match = scan(/(?:\d+)(?![.eEfF])L?L?/) label_expected = false encoder.text_token match, :integer elsif match = scan(/\d[fF]?|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/) label_expected = false encoder.text_token match, :float else encoder.text_token getch, :error end when :string if match = scan(/[^\\"]+/) encoder.text_token match, :content elsif match = scan(/"/) encoder.text_token match, :delimiter encoder.end_group :string state = :initial label_expected = false elsif match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox) encoder.text_token match, :char elsif match = scan(/ \\ | $ /x) encoder.end_group :string encoder.text_token match, :error unless match.empty? state = :initial label_expected = false else raise_inspect "else case \" reached; %p not handled." % peek(1), encoder end when :include_expected if match = scan(/<[^>\n]+>?|"[^"\n\\]*(?:\\.[^"\n\\]*)*"?/) encoder.text_token match, :include state = :initial elsif match = scan(/\s+/) encoder.text_token match, :space state = :initial if match.index ?\n else state = :initial end when :class_name_expected if match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x) encoder.text_token match, :class state = :initial elsif match = scan(/\s+/) encoder.text_token match, :space else encoder.text_token getch, :error state = :initial end else raise_inspect 'Unknown state', encoder end end if state == :string encoder.end_group :string end encoder end end end end coderay-1.1.1/lib/coderay/scanners/raydebug.rb0000644000004100000410000000344412663664402021345 0ustar www-datawww-datarequire 'set' module CodeRay module Scanners # = Raydebug Scanner # # Highlights the output of the Encoders::Debug encoder. class Raydebug < Scanner register_for :raydebug file_extension 'raydebug' title 'CodeRay Token Dump' protected def setup super @known_token_kinds = TokenKinds.keys.map(&:to_s).to_set end def scan_tokens encoder, options opened_tokens = [] until eos? if match = scan(/\s+/) encoder.text_token match, :space elsif match = scan(/ (\w+) \( ( [^\)\\]* ( \\. [^\)\\]* )* ) /x) kind = self[1] encoder.text_token kind, :class encoder.text_token '(', :operator match = self[2] unless match.empty? if @known_token_kinds.include? kind encoder.text_token match, kind.to_sym else encoder.text_token match, :plain end end encoder.text_token match, :operator if match = scan(/\)/) elsif match = scan(/ (\w+) ([<\[]) /x) encoder.text_token self[1], :class if @known_token_kinds.include? self[1] kind = self[1].to_sym else kind = :unknown end opened_tokens << kind encoder.begin_group kind encoder.text_token self[2], :operator elsif !opened_tokens.empty? && match = scan(/ [>\]] /x) encoder.text_token match, :operator encoder.end_group opened_tokens.pop else encoder.text_token getch, :space end end encoder.end_group opened_tokens.pop until opened_tokens.empty? encoder end end end end coderay-1.1.1/lib/coderay/scanners/clojure.rb0000644000004100000410000002441512663664402021207 0ustar www-datawww-data# encoding: utf-8 module CodeRay module Scanners # Clojure scanner by Licenser. class Clojure < Scanner register_for :clojure file_extension 'clj' SPECIAL_FORMS = %w[ def if do let quote var fn loop recur throw try catch monitor-enter monitor-exit . new ] # :nodoc: CORE_FORMS = %w[ + - -> ->> .. / * <= < = == >= > accessor aclone add-classpath add-watch agent agent-error agent-errors aget alength alias all-ns alter alter-meta! alter-var-root amap ancestors and apply areduce array-map aset aset-boolean aset-byte aset-char aset-double aset-float aset-int aset-long aset-short assert assoc assoc! assoc-in associative? atom await await-for bases bean bigdec bigint binding bit-and bit-and-not bit-clear bit-flip bit-not bit-or bit-set bit-shift-left bit-shift-right bit-test bit-xor boolean boolean-array booleans bound-fn bound-fn* bound? butlast byte byte-array bytes case cast char char-array char-escape-string char-name-string char? chars class class? clear-agent-errors clojure-version coll? comment commute comp comparator compare compare-and-set! compile complement concat cond condp conj conj! cons constantly construct-proxy contains? count counted? create-ns create-struct cycle dec decimal? declare definline defmacro defmethod defmulti defn defn- defonce defprotocol defrecord defstruct deftype delay delay? deliver denominator deref derive descendants disj disj! dissoc dissoc! distinct distinct? doall doc dorun doseq dosync dotimes doto double double-array doubles drop drop-last drop-while empty empty? ensure enumeration-seq error-handler error-mode eval even? every? extend extend-protocol extend-type extenders extends? false? ffirst file-seq filter find find-doc find-ns find-var first float float-array float? floats flush fn fn? fnext for force format future future-call future-cancel future-cancelled? future-done? future? gen-class gen-interface gensym get get-in get-method get-proxy-class get-thread-bindings get-validator hash hash-map hash-set identical? identity if-let if-not ifn? import in-ns inc init-proxy instance? int int-array integer? interleave intern interpose into into-array ints io! isa? iterate iterator-seq juxt key keys keyword keyword? last lazy-cat lazy-seq let letfn line-seq list list* list? load load-file load-reader load-string loaded-libs locking long long-array longs loop macroexpand macroexpand-1 make-array make-hierarchy map map? mapcat max max-key memfn memoize merge merge-with meta methods min min-key mod name namespace neg? newline next nfirst nil? nnext not not-any? not-empty not-every? not= ns ns-aliases ns-imports ns-interns ns-map ns-name ns-publics ns-refers ns-resolve ns-unalias ns-unmap nth nthnext num number? numerator object-array odd? or parents partial partition pcalls peek persistent! pmap pop pop! pop-thread-bindings pos? pr pr-str prefer-method prefers print print-namespace-doc print-str printf println println-str prn prn-str promise proxy proxy-mappings proxy-super push-thread-bindings pvalues quot rand rand-int range ratio? rationalize re-find re-groups re-matcher re-matches re-pattern re-seq read read-line read-string reduce ref ref-history-count ref-max-history ref-min-history ref-set refer refer-clojure reify release-pending-sends rem remove remove-all-methods remove-method remove-ns remove-watch repeat repeatedly replace replicate require reset! reset-meta! resolve rest restart-agent resultset-seq reverse reversible? rseq rsubseq satisfies? second select-keys send send-off seq seq? seque sequence sequential? set set-error-handler! set-error-mode! set-validator! set? short short-array shorts shutdown-agents slurp some sort sort-by sorted-map sorted-map-by sorted-set sorted-set-by sorted? special-form-anchor special-symbol? split-at split-with str string? struct struct-map subs subseq subvec supers swap! symbol symbol? sync syntax-symbol-anchor take take-last take-nth take-while test the-ns thread-bound? time to-array to-array-2d trampoline transient tree-seq true? type unchecked-add unchecked-dec unchecked-divide unchecked-inc unchecked-multiply unchecked-negate unchecked-remainder unchecked-subtract underive update-in update-proxy use val vals var-get var-set var? vary-meta vec vector vector-of vector? when when-first when-let when-not while with-bindings with-bindings* with-in-str with-local-vars with-meta with-open with-out-str with-precision xml-seq zero? zipmap ] # :nodoc: PREDEFINED_CONSTANTS = %w[ true false nil *1 *2 *3 *agent* *clojure-version* *command-line-args* *compile-files* *compile-path* *e *err* *file* *flush-on-newline* *in* *ns* *out* *print-dup* *print-length* *print-level* *print-meta* *print-readably* *read-eval* *warn-on-reflection* ] # :nodoc: IDENT_KIND = WordList.new(:ident). add(SPECIAL_FORMS, :keyword). add(CORE_FORMS, :keyword). add(PREDEFINED_CONSTANTS, :predefined_constant) KEYWORD_NEXT_TOKEN_KIND = WordList.new(nil). add(%w[ def defn defn- definline defmacro defmulti defmethod defstruct defonce declare ], :function). add(%w[ ns ], :namespace). add(%w[ defprotocol defrecord ], :class) BASIC_IDENTIFIER = /[a-zA-Z$%*\/_+!?&<>\-=]=?[a-zA-Z0-9$&*+!\/_?<>\-\#]*/ IDENTIFIER = /(?!-\d)(?:(?:#{BASIC_IDENTIFIER}\.)*#{BASIC_IDENTIFIER}(?:\/#{BASIC_IDENTIFIER})?\.?)|\.\.?/ SYMBOL = /::?#{IDENTIFIER}/o DIGIT = /\d/ DIGIT10 = DIGIT DIGIT16 = /[0-9a-f]/i DIGIT8 = /[0-7]/ DIGIT2 = /[01]/ RADIX16 = /\#x/i RADIX8 = /\#o/i RADIX2 = /\#b/i RADIX10 = /\#d/i EXACTNESS = /#i|#e/i SIGN = /[\+-]?/ EXP_MARK = /[esfdl]/i EXP = /#{EXP_MARK}#{SIGN}#{DIGIT}+/ SUFFIX = /#{EXP}?/ PREFIX10 = /#{RADIX10}?#{EXACTNESS}?|#{EXACTNESS}?#{RADIX10}?/ PREFIX16 = /#{RADIX16}#{EXACTNESS}?|#{EXACTNESS}?#{RADIX16}/ PREFIX8 = /#{RADIX8}#{EXACTNESS}?|#{EXACTNESS}?#{RADIX8}/ PREFIX2 = /#{RADIX2}#{EXACTNESS}?|#{EXACTNESS}?#{RADIX2}/ UINT10 = /#{DIGIT10}+#*/ UINT16 = /#{DIGIT16}+#*/ UINT8 = /#{DIGIT8}+#*/ UINT2 = /#{DIGIT2}+#*/ DECIMAL = /#{DIGIT10}+#+\.#*#{SUFFIX}|#{DIGIT10}+\.#{DIGIT10}*#*#{SUFFIX}|\.#{DIGIT10}+#*#{SUFFIX}|#{UINT10}#{EXP}/ UREAL10 = /#{UINT10}\/#{UINT10}|#{DECIMAL}|#{UINT10}/ UREAL16 = /#{UINT16}\/#{UINT16}|#{UINT16}/ UREAL8 = /#{UINT8}\/#{UINT8}|#{UINT8}/ UREAL2 = /#{UINT2}\/#{UINT2}|#{UINT2}/ REAL10 = /#{SIGN}#{UREAL10}/ REAL16 = /#{SIGN}#{UREAL16}/ REAL8 = /#{SIGN}#{UREAL8}/ REAL2 = /#{SIGN}#{UREAL2}/ IMAG10 = /i|#{UREAL10}i/ IMAG16 = /i|#{UREAL16}i/ IMAG8 = /i|#{UREAL8}i/ IMAG2 = /i|#{UREAL2}i/ COMPLEX10 = /#{REAL10}@#{REAL10}|#{REAL10}\+#{IMAG10}|#{REAL10}-#{IMAG10}|\+#{IMAG10}|-#{IMAG10}|#{REAL10}/ COMPLEX16 = /#{REAL16}@#{REAL16}|#{REAL16}\+#{IMAG16}|#{REAL16}-#{IMAG16}|\+#{IMAG16}|-#{IMAG16}|#{REAL16}/ COMPLEX8 = /#{REAL8}@#{REAL8}|#{REAL8}\+#{IMAG8}|#{REAL8}-#{IMAG8}|\+#{IMAG8}|-#{IMAG8}|#{REAL8}/ COMPLEX2 = /#{REAL2}@#{REAL2}|#{REAL2}\+#{IMAG2}|#{REAL2}-#{IMAG2}|\+#{IMAG2}|-#{IMAG2}|#{REAL2}/ NUM10 = /#{PREFIX10}?#{COMPLEX10}/ NUM16 = /#{PREFIX16}#{COMPLEX16}/ NUM8 = /#{PREFIX8}#{COMPLEX8}/ NUM2 = /#{PREFIX2}#{COMPLEX2}/ NUM = /#{NUM10}|#{NUM16}|#{NUM8}|#{NUM2}/ protected def scan_tokens encoder, options state = :initial kind = nil until eos? case state when :initial if match = scan(/ \s+ | \\\n | , /x) encoder.text_token match, :space elsif match = scan(/['`\(\[\)\]\{\}]|\#[({]|~@?|[@\^]/) encoder.text_token match, :operator elsif match = scan(/;.*/) encoder.text_token match, :comment # TODO: recognize (comment ...) too elsif match = scan(/\#?\\(?:newline|space|.?)/) encoder.text_token match, :char elsif match = scan(/\#[ft]/) encoder.text_token match, :predefined_constant elsif match = scan(/#{IDENTIFIER}/o) kind = IDENT_KIND[match] encoder.text_token match, kind if rest? && kind == :keyword if kind = KEYWORD_NEXT_TOKEN_KIND[match] encoder.text_token match, :space if match = scan(/\s+/o) encoder.text_token match, kind if match = scan(/#{IDENTIFIER}/o) end end elsif match = scan(/#{SYMBOL}/o) encoder.text_token match, :symbol elsif match = scan(/\./) encoder.text_token match, :operator elsif match = scan(/ \# \^ #{IDENTIFIER} /ox) encoder.text_token match, :type elsif match = scan(/ (\#)? " /x) state = self[1] ? :regexp : :string encoder.begin_group state encoder.text_token match, :delimiter elsif match = scan(/#{NUM}/o) and not matched.empty? encoder.text_token match, match[/[.e\/]/i] ? :float : :integer else encoder.text_token getch, :error end when :string, :regexp if match = scan(/[^"\\]+|\\.?/) encoder.text_token match, :content elsif match = scan(/"/) encoder.text_token match, :delimiter encoder.end_group state state = :initial else raise_inspect "else case \" reached; %p not handled." % peek(1), encoder, state end else raise 'else case reached' end end if [:string, :regexp].include? state encoder.end_group state end encoder end end end endcoderay-1.1.1/lib/coderay/scanners/ruby/0000755000004100000410000000000012663664402020172 5ustar www-datawww-datacoderay-1.1.1/lib/coderay/scanners/ruby/patterns.rb0000644000004100000410000001155712663664402022370 0ustar www-datawww-data# encoding: utf-8 module CodeRay module Scanners module Ruby::Patterns # :nodoc: all KEYWORDS = %w[ and def end in or unless begin defined? ensure module redo super until BEGIN break do next rescue then when END case else for retry while alias class elsif if not return undef yield ] # See http://murfy.de/ruby-constants. PREDEFINED_CONSTANTS = %w[ nil true false self DATA ARGV ARGF ENV FALSE TRUE NIL STDERR STDIN STDOUT TOPLEVEL_BINDING RUBY_COPYRIGHT RUBY_DESCRIPTION RUBY_ENGINE RUBY_PATCHLEVEL RUBY_PLATFORM RUBY_RELEASE_DATE RUBY_REVISION RUBY_VERSION __FILE__ __LINE__ __ENCODING__ ] IDENT_KIND = WordList.new(:ident). add(KEYWORDS, :keyword). add(PREDEFINED_CONSTANTS, :predefined_constant) KEYWORD_NEW_STATE = WordList.new(:initial). add(%w[ def ], :def_expected). add(%w[ undef ], :undef_expected). add(%w[ alias ], :alias_expected). add(%w[ class module ], :module_expected) IDENT = 'ä'[/[[:alpha:]]/] == 'ä' ? Regexp.new('[[:alpha:]_[^\0-\177]][[:alnum:]_[^\0-\177]]*') : /[^\W\d]\w*/ METHOD_NAME = / #{IDENT} [?!]? /ox METHOD_NAME_OPERATOR = / \*\*? # multiplication and power | [-+~]@? # plus, minus, tilde with and without at sign | [\/%&|^`] # division, modulo or format strings, and, or, xor, system | \[\]=? # array getter and setter | << | >> # append or shift left, shift right | <=?>? | >=? # comparison, rocket operator | ===? | =~ # simple equality, case equality, match | ![~=@]? # negation with and without at sign, not-equal and not-match /ox METHOD_SUFFIX = / (?: [?!] | = (?![~>]|=(?!>)) ) /x METHOD_NAME_EX = / #{IDENT} #{METHOD_SUFFIX}? | #{METHOD_NAME_OPERATOR} /ox METHOD_AFTER_DOT = / #{IDENT} [?!]? | #{METHOD_NAME_OPERATOR} /ox INSTANCE_VARIABLE = / @ #{IDENT} /ox CLASS_VARIABLE = / @@ #{IDENT} /ox OBJECT_VARIABLE = / @@? #{IDENT} /ox GLOBAL_VARIABLE = / \$ (?: #{IDENT} | [1-9]\d* | 0\w* | [~&+`'=\/,;_.<>!@$?*":\\] | -[a-zA-Z_0-9] ) /ox PREFIX_VARIABLE = / #{GLOBAL_VARIABLE} | #{OBJECT_VARIABLE} /ox VARIABLE = / @?@? #{IDENT} | #{GLOBAL_VARIABLE} /ox QUOTE_TO_TYPE = { '`' => :shell, '/'=> :regexp, } QUOTE_TO_TYPE.default = :string REGEXP_MODIFIERS = /[mousenix]*/ DECIMAL = /\d+(?:_\d+)*/ OCTAL = /0_?[0-7]+(?:_[0-7]+)*/ HEXADECIMAL = /0x[0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*/ BINARY = /0b[01]+(?:_[01]+)*/ EXPONENT = / [eE] [+-]? #{DECIMAL} /ox FLOAT_SUFFIX = / #{EXPONENT} | \. #{DECIMAL} #{EXPONENT}? /ox FLOAT_OR_INT = / #{DECIMAL} (?: #{FLOAT_SUFFIX} () )? /ox NUMERIC = / (?: (?=0) (?: #{OCTAL} | #{HEXADECIMAL} | #{BINARY} ) | #{FLOAT_OR_INT} ) /ox SYMBOL = / : (?: #{METHOD_NAME_EX} | #{PREFIX_VARIABLE} | ['"] ) /ox METHOD_NAME_OR_SYMBOL = / #{METHOD_NAME_EX} | #{SYMBOL} /ox SIMPLE_ESCAPE = / [abefnrstv] | [0-7]{1,3} | x[0-9A-Fa-f]{1,2} | . /mx CONTROL_META_ESCAPE = / (?: M-|C-|c ) (?: \\ (?: M-|C-|c ) )* (?: [^\\] | \\ #{SIMPLE_ESCAPE} )? /mox ESCAPE = / #{CONTROL_META_ESCAPE} | #{SIMPLE_ESCAPE} /mox CHARACTER = / \? (?: [^\s\\] | \\ #{ESCAPE} ) /mox # NOTE: This is not completely correct, but # nobody needs heredoc delimiters ending with \n. HEREDOC_OPEN = / << ([-~])? # $1 = float (?: ( [A-Za-z_0-9]+ ) # $2 = delim | ( ["'`\/] ) # $3 = quote, type ( [^\n]*? ) \3 # $4 = delim ) /mx RUBYDOC = / =begin (?!\S) .*? (?: \Z | ^=end (?!\S) [^\n]* ) /mx DATA = / __END__$ .*? (?: \Z | (?=^\#CODE) ) /mx RUBYDOC_OR_DATA = / #{RUBYDOC} | #{DATA} /xo # Checks for a valid value to follow. This enables # value_expected in method calls without parentheses. VALUE_FOLLOWS = / (?>[ \t\f\v]+) (?: [%\/][^\s=] | <<-?\S | [-+] \d | #{CHARACTER} ) /ox KEYWORDS_EXPECTING_VALUE = WordList.new.add(%w[ and end in or unless begin defined? ensure redo super until break do next rescue then when case else for retry while elsif if not return yield ]) FANCY_STRING_START = / % ( [iIqQrswWx] | (?![a-zA-Z0-9]) ) ([^a-zA-Z0-9]) /x FANCY_STRING_KIND = Hash.new(:string).merge({ 'i' => :symbol, 'I' => :symbol, 'r' => :regexp, 's' => :symbol, 'x' => :shell, }) FANCY_STRING_INTERPRETED = Hash.new(true).merge({ 'i' => false, 'q' => false, 's' => false, 'w' => false, }) end end end coderay-1.1.1/lib/coderay/scanners/ruby/string_state.rb0000644000004100000410000000452712663664402023235 0ustar www-datawww-data# encoding: utf-8 module CodeRay module Scanners class Ruby class StringState < Struct.new :type, :interpreted, :delim, :heredoc, :opening_paren, :paren_depth, :pattern, :next_state # :nodoc: all CLOSING_PAREN = Hash[ *%w[ ( ) [ ] < > { } ] ].each { |k,v| k.freeze; v.freeze } # debug, if I try to change it with << STRING_PATTERN = Hash.new do |h, k| delim, interpreted = *k delim_pattern = Regexp.escape(delim) if closing_paren = CLOSING_PAREN[delim] delim_pattern << Regexp.escape(closing_paren) end delim_pattern << '\\\\' unless delim == '\\' # special_escapes = # case interpreted # when :regexp_symbols # '| [|?*+(){}\[\].^$]' # end if interpreted && delim != '#' / (?= [#{delim_pattern}] | \# [{$@] ) /mx else / (?= [#{delim_pattern}] ) /mx end.tap do |pattern| h[k] = pattern if (delim.respond_to?(:ord) ? delim.ord : delim[0]) < 256 end end def self.simple_key_pattern delim if delim == "'" / (?> (?: [^\\']+ | \\. )* ) ' : /mx else / (?> (?: [^\\"\#]+ | \\. | \#\$[\\"] | \#\{[^\{\}]+\} | \#(?!\{) )* ) " : /mx end end def initialize kind, interpreted, delim, heredoc = false if heredoc pattern = heredoc_pattern delim, interpreted, heredoc == :indented delim = nil else pattern = STRING_PATTERN[ [delim, interpreted] ] if closing_paren = CLOSING_PAREN[delim] opening_paren = delim delim = closing_paren paren_depth = 1 end end super kind, interpreted, delim, heredoc, opening_paren, paren_depth, pattern, :initial end def heredoc_pattern delim, interpreted, indented # delim = delim.dup # workaround for old Ruby delim_pattern = Regexp.escape(delim) delim_pattern = / (?:\A|\n) #{ '(?>[ \t]*)' if indented } #{ Regexp.new delim_pattern } $ /x if interpreted / (?= #{delim_pattern}() | \\ | \# [{$@] ) /mx # $1 set == end of heredoc else / (?= #{delim_pattern}() | \\ ) /mx end end end end end end coderay-1.1.1/lib/coderay/scanners/taskpaper.rb0000644000004100000410000000201012663664402021521 0ustar www-datawww-datamodule CodeRay module Scanners class Taskpaper < Scanner register_for :taskpaper file_extension 'taskpaper' protected def scan_tokens encoder, options until eos? if match = scan(/\S.*:.*$/) # project encoder.text_token(match, :namespace) elsif match = scan(/-.+@done.*/) # completed task encoder.text_token(match, :done) elsif match = scan(/-(?:[^@\n]+|@(?!due))*/) # task encoder.text_token(match, :plain) elsif match = scan(/@due.*/) # comment encoder.text_token(match, :important) elsif match = scan(/.+/) # comment encoder.text_token(match, :comment) elsif match = scan(/\s+/) # space encoder.text_token(match, :space) else # other encoder.text_token getch, :error end end encoder end end end end coderay-1.1.1/lib/coderay/scanners/html.rb0000644000004100000410000002127712663664402020513 0ustar www-datawww-datamodule CodeRay module Scanners # HTML Scanner # # Alias: +xhtml+ # # See also: Scanners::XML class HTML < Scanner register_for :html KINDS_NOT_LOC = [ :comment, :doctype, :preprocessor, :tag, :attribute_name, :operator, :attribute_value, :string, :plain, :entity, :error, ] # :nodoc: EVENT_ATTRIBUTES = %w( onabort onafterprint onbeforeprint onbeforeunload onblur oncanplay oncanplaythrough onchange onclick oncontextmenu oncuechange ondblclick ondrag ondragdrop ondragend ondragenter ondragleave ondragover ondragstart ondrop ondurationchange onemptied onended onerror onfocus onformchange onforminput onhashchange oninput oninvalid onkeydown onkeypress onkeyup onload onloadeddata onloadedmetadata onloadstart onmessage onmousedown onmousemove onmouseout onmouseover onmouseup onmousewheel onmove onoffline ononline onpagehide onpageshow onpause onplay onplaying onpopstate onprogress onratechange onreadystatechange onredo onreset onresize onscroll onseeked onseeking onselect onshow onstalled onstorage onsubmit onsuspend ontimeupdate onundo onunload onvolumechange onwaiting ) IN_ATTRIBUTE = WordList::CaseIgnoring.new(nil). add(EVENT_ATTRIBUTES, :script). add(['style'], :style) ATTR_NAME = /[\w.:-]+/ # :nodoc: TAG_END = /\/?>/ # :nodoc: HEX = /[0-9a-fA-F]/ # :nodoc: ENTITY = / & (?: \w+ | \# (?: \d+ | x#{HEX}+ ) ) ; /ox # :nodoc: PLAIN_STRING_CONTENT = { "'" => /[^&'>\n]+/, '"' => /[^&">\n]+/, } # :nodoc: def reset super @state = :initial @plain_string_content = nil end protected def setup @state = :initial @plain_string_content = nil @in_tag = nil end def scan_java_script encoder, code if code && !code.empty? @java_script_scanner ||= Scanners::JavaScript.new '', :keep_tokens => true @java_script_scanner.tokenize code, :tokens => encoder end end def scan_css encoder, code, state = [:initial] if code && !code.empty? @css_scanner ||= Scanners::CSS.new '', :keep_tokens => true @css_scanner.tokenize code, :tokens => encoder, :state => state end end def scan_tokens encoder, options state = options[:state] || @state plain_string_content = @plain_string_content in_tag = @in_tag in_attribute = nil encoder.begin_group :string if state == :attribute_value_string until eos? if state != :in_special_tag && match = scan(/\s+/m) encoder.text_token match, :space else case state when :initial if match = scan(//m) encoder.text_token match[0..-4], :plain encoder.text_token ']]>', :inline_delimiter elsif match = scan(/.+/) encoder.text_token match, :error end elsif match = scan(/|.*)/m) encoder.text_token match, :comment elsif match = scan(/|.*)|\]>/m) encoder.text_token match, :doctype elsif match = scan(/<\?xml(?:.*?\?>|.*)/m) encoder.text_token match, :preprocessor elsif match = scan(/<\?(?:.*?\?>|.*)/m) encoder.text_token match, :comment elsif match = scan(/<\/[-\w.:]*>?/m) in_tag = nil encoder.text_token match, :tag elsif match = scan(/<(?:(script|style)|[-\w.:]+)(>)?/m) encoder.text_token match, :tag in_tag = self[1] if self[2] state = :in_special_tag if in_tag else state = :attribute end elsif match = scan(/[^<>&]+/) encoder.text_token match, :plain elsif match = scan(/#{ENTITY}/ox) encoder.text_token match, :entity elsif match = scan(/[<>&]/) in_tag = nil encoder.text_token match, :error else raise_inspect '[BUG] else-case reached with state %p' % [state], encoder end when :attribute if match = scan(/#{TAG_END}/o) encoder.text_token match, :tag in_attribute = nil if in_tag state = :in_special_tag else state = :initial end elsif match = scan(/#{ATTR_NAME}/o) in_attribute = IN_ATTRIBUTE[match] encoder.text_token match, :attribute_name state = :attribute_equal else in_tag = nil encoder.text_token getch, :error end when :attribute_equal if match = scan(/=/) #/ encoder.text_token match, :operator state = :attribute_value else state = :attribute next end when :attribute_value if match = scan(/#{ATTR_NAME}/o) encoder.text_token match, :attribute_value state = :attribute elsif match = scan(/["']/) if in_attribute == :script || in_attribute == :style encoder.begin_group :string encoder.text_token match, :delimiter if scan(/javascript:[ \t]*/) encoder.text_token matched, :comment end code = scan_until(match == '"' ? /(?="|\z)/ : /(?='|\z)/) if in_attribute == :script scan_java_script encoder, code else scan_css encoder, code, [:block] end match = scan(/["']/) encoder.text_token match, :delimiter if match encoder.end_group :string state = :attribute in_attribute = nil else encoder.begin_group :string state = :attribute_value_string plain_string_content = PLAIN_STRING_CONTENT[match] encoder.text_token match, :delimiter end elsif match = scan(/#{TAG_END}/o) encoder.text_token match, :tag state = :initial else encoder.text_token getch, :error end when :attribute_value_string if match = scan(plain_string_content) encoder.text_token match, :content elsif match = scan(/['"]/) encoder.text_token match, :delimiter encoder.end_group :string state = :attribute elsif match = scan(/#{ENTITY}/ox) encoder.text_token match, :entity elsif match = scan(/&/) encoder.text_token match, :content elsif match = scan(/[\n>]/) encoder.end_group :string state = :initial encoder.text_token match, :error end when :in_special_tag case in_tag when 'script', 'style' encoder.text_token match, :space if match = scan(/[ \t]*\n/) if scan(/(\s*)|(.*))/m) code = self[2] || self[4] closing = self[3] encoder.text_token self[1], :comment else code = scan_until(/(?=(?:\n\s*)?<\/#{in_tag}>)|\z/) closing = false end unless code.empty? encoder.begin_group :inline if in_tag == 'script' scan_java_script encoder, code else scan_css encoder, code end encoder.end_group :inline end encoder.text_token closing, :comment if closing state = :initial else raise 'unknown special tag: %p' % [in_tag] end else raise_inspect 'Unknown state: %p' % [state], encoder end end end if options[:keep_state] @state = state @plain_string_content = plain_string_content @in_tag = in_tag end encoder.end_group :string if state == :attribute_value_string encoder end end end end coderay-1.1.1/lib/coderay/helpers/0000755000004100000410000000000012663664402017037 5ustar www-datawww-datacoderay-1.1.1/lib/coderay/helpers/plugin_host.rb0000644000004100000410000001252712663664402021726 0ustar www-datawww-datamodule CodeRay # = PluginHost # # A simple subclass/subfolder plugin system. # # Example: # class Generators # extend PluginHost # plugin_path 'app/generators' # end # # class Generator # extend Plugin # PLUGIN_HOST = Generators # end # # class FancyGenerator < Generator # register_for :fancy # end # # Generators[:fancy] #-> FancyGenerator # # or # CodeRay.require_plugin 'Generators/fancy' # # or # Generators::Fancy module PluginHost # Raised if Encoders::[] fails because: # * a file could not be found # * the requested Plugin is not registered PluginNotFound = Class.new LoadError HostNotFound = Class.new LoadError PLUGIN_HOSTS = [] PLUGIN_HOSTS_BY_ID = {} # dummy hash # Loads all plugins using list and load. def load_all for plugin in list load plugin end end # Returns the Plugin for +id+. # # Example: # yaml_plugin = MyPluginHost[:yaml] def [] id, *args, &blk plugin = validate_id(id) begin plugin = plugin_hash.[](plugin, *args, &blk) end while plugin.is_a? String plugin end alias load [] # Tries to +load+ the missing plugin by translating +const+ to the # underscore form (eg. LinesOfCode becomes lines_of_code). def const_missing const id = const.to_s. gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). gsub(/([a-z\d])([A-Z])/,'\1_\2'). downcase load id end class << self # Adds the module/class to the PLUGIN_HOSTS list. def extended mod PLUGIN_HOSTS << mod end end # The path where the plugins can be found. def plugin_path *args unless args.empty? @plugin_path = File.expand_path File.join(*args) end @plugin_path ||= '' end # Map a plugin_id to another. # # Usage: Put this in a file plugin_path/_map.rb. # # class MyColorHost < PluginHost # map :navy => :dark_blue, # :maroon => :brown, # :luna => :moon # end def map hash for from, to in hash from = validate_id from to = validate_id to plugin_hash[from] = to unless plugin_hash.has_key? from end end # Define the default plugin to use when no plugin is found # for a given id, or return the default plugin. # # See also map. # # class MyColorHost < PluginHost # map :navy => :dark_blue # default :gray # end # # MyColorHost.default # loads and returns the Gray plugin def default id = nil if id id = validate_id id raise "The default plugin can't be named \"default\"." if id == :default plugin_hash[:default] = id else load :default end end # Every plugin must register itself for +id+ by calling register_for, # which calls this method. # # See Plugin#register_for. def register plugin, id plugin_hash[validate_id(id)] = plugin end # A Hash of plugion_id => Plugin pairs. def plugin_hash @plugin_hash ||= (@plugin_hash = make_plugin_hash).tap { load_plugin_map } end # Returns an array of all .rb files in the plugin path. # # The extension .rb is not included. def list Dir[path_to('*')].select do |file| File.basename(file)[/^(?!_)\w+\.rb$/] end.map do |file| File.basename(file, '.rb').to_sym end end # Returns an array of all Plugins. # # Note: This loads all plugins using load_all. def all_plugins load_all plugin_hash.values.grep(Class) end # Loads the map file (see map). # # This is done automatically when plugin_path is called. def load_plugin_map mapfile = path_to '_map' if File.exist? mapfile require mapfile true else false end end protected # Return a plugin hash that automatically loads plugins. def make_plugin_hash Hash.new do |h, plugin_id| id = validate_id(plugin_id) path = path_to id begin require path rescue LoadError => boom if h.has_key?(:default) h[:default] else raise PluginNotFound, '%p could not load plugin %p: %s' % [self, id, boom] end else # Plugin should have registered by now if h.has_key? id h[id] else raise PluginNotFound, "No #{self.name} plugin for #{id.inspect} found in #{path}." end end end end # Returns the expected path to the plugin file for the given id. def path_to plugin_id File.join plugin_path, "#{plugin_id}.rb" end # Converts +id+ to a valid plugin ID String, or returns +nil+. # # Raises +ArgumentError+ for all other objects, or if the # given String includes non-alphanumeric characters (\W). def validate_id id case id when Symbol id.to_s when String if id[/\w+/] == id id.downcase else raise ArgumentError, "Invalid id given: #{id}" end else raise ArgumentError, "Symbol or String expected, but #{id.class} given." end end end end coderay-1.1.1/lib/coderay/helpers/plugin.rb0000644000004100000410000000215412663664402020664 0ustar www-datawww-datamodule CodeRay # = Plugin # # Plugins have to include this module. # # IMPORTANT: Use extend for this module. # # See CodeRay::PluginHost for examples. module Plugin attr_reader :plugin_id # Register this class for the given +id+. # # Example: # class MyPlugin < PluginHost::BaseClass # register_for :my_id # ... # end # # See PluginHost.register. def register_for id @plugin_id = id plugin_host.register self, id end # Returns the title of the plugin, or sets it to the # optional argument +title+. def title title = nil if title @title = title.to_s else @title ||= name[/([^:]+)$/, 1] end end # The PluginHost for this Plugin class. def plugin_host host = nil if host.is_a? PluginHost const_set :PLUGIN_HOST, host end self::PLUGIN_HOST end def aliases plugin_host.plugin_hash.inject [] do |aliases, (key, _)| aliases << key if plugin_host[key] == self aliases end end end end coderay-1.1.1/lib/coderay/helpers/word_list.rb0000644000004100000410000000317612663664402021401 0ustar www-datawww-datamodule CodeRay # = WordList # # A Hash subclass designed for mapping word lists to token types. # # A WordList is a Hash with some additional features. # It is intended to be used for keyword recognition. # # WordList is optimized to be used in Scanners, # typically to decide whether a given ident is a special token. # # For case insensitive words use WordList::CaseIgnoring. # # Example: # # # define word arrays # RESERVED_WORDS = %w[ # asm break case continue default do else # ] # # PREDEFINED_TYPES = %w[ # int long short char void # ] # # # make a WordList # IDENT_KIND = WordList.new(:ident). # add(RESERVED_WORDS, :reserved). # add(PREDEFINED_TYPES, :predefined_type) # # ... # # def scan_tokens tokens, options # ... # # elsif scan(/[A-Za-z_][A-Za-z_0-9]*/) # # use it # kind = IDENT_KIND[match] # ... class WordList < Hash # Create a new WordList with +default+ as default value. def initialize default = false super default end # Add words to the list and associate them with +value+. # # Returns +self+, so you can concat add calls. def add words, value = true words.each { |word| self[word] = value } self end end # A CaseIgnoring WordList is like a WordList, only that # keys are compared case-insensitively (normalizing keys using +downcase+). class WordList::CaseIgnoring < WordList def [] key super key.downcase end def []= key, value super key.downcase, value end end end coderay-1.1.1/lib/coderay/helpers/file_type.rb0000644000004100000410000001005212663664402021342 0ustar www-datawww-datamodule CodeRay # = FileType # # A simple filetype recognizer. # # == Usage # # # determine the type of the given # lang = FileType[file_name] # # # return :text if the file type is unknown # lang = FileType.fetch file_name, :text # # # try the shebang line, too # lang = FileType.fetch file_name, :text, true module FileType UnknownFileType = Class.new Exception class << self # Try to determine the file type of the file. # # +filename+ is a relative or absolute path to a file. # # The file itself is only accessed when +read_shebang+ is set to true. # That means you can get filetypes from files that don't exist. def [] filename, read_shebang = false name = File.basename filename ext = File.extname(name).sub(/^\./, '') # from last dot, delete the leading dot ext2 = filename.to_s[/\.(.*)/, 1] # from first dot type = TypeFromExt[ext] || TypeFromExt[ext.downcase] || (TypeFromExt[ext2] if ext2) || (TypeFromExt[ext2.downcase] if ext2) || TypeFromName[name] || TypeFromName[name.downcase] type ||= type_from_shebang(filename) if read_shebang type end # This works like Hash#fetch. # # If the filetype cannot be found, the +default+ value # is returned. def fetch filename, default = nil, read_shebang = false if default && block_given? warn 'Block supersedes default value argument; use either.' end if type = self[filename, read_shebang] type else return yield if block_given? return default if default raise UnknownFileType, 'Could not determine type of %p.' % filename end end protected def type_from_shebang filename return unless File.exist? filename File.open filename, 'r' do |f| if first_line = f.gets if type = first_line[TypeFromShebang] type.to_sym end end end end end TypeFromExt = { 'c' => :c, 'cfc' => :xml, 'cfm' => :xml, 'clj' => :clojure, 'css' => :css, 'diff' => :diff, 'dpr' => :delphi, 'erb' => :erb, 'gemspec' => :ruby, 'go' => :go, 'groovy' => :groovy, 'gvy' => :groovy, 'h' => :c, 'haml' => :haml, 'htm' => :html, 'html' => :html, 'html.erb' => :erb, 'java' => :java, 'js' => :java_script, 'json' => :json, 'lua' => :lua, 'mab' => :ruby, 'pas' => :delphi, 'patch' => :diff, 'phtml' => :php, 'php' => :php, 'php3' => :php, 'php4' => :php, 'php5' => :php, 'prawn' => :ruby, 'py' => :python, 'py3' => :python, 'pyw' => :python, 'rake' => :ruby, 'raydebug' => :raydebug, 'rb' => :ruby, 'rbw' => :ruby, 'rhtml' => :erb, 'rjs' => :ruby, 'rpdf' => :ruby, 'ru' => :ruby, # config.ru 'rxml' => :ruby, 'sass' => :sass, 'sql' => :sql, 'taskpaper' => :taskpaper, 'template' => :json, # AWS CloudFormation template 'tmproj' => :xml, 'xaml' => :xml, 'xhtml' => :html, 'xml' => :xml, 'yaml' => :yaml, 'yml' => :yaml, } for cpp_alias in %w[cc cpp cp cxx c++ C hh hpp h++ cu] TypeFromExt[cpp_alias] = :cpp end TypeFromShebang = /\b(?:ruby|perl|python|sh)\b/ TypeFromName = { 'Capfile' => :ruby, 'Rakefile' => :ruby, 'Rantfile' => :ruby, 'Gemfile' => :ruby, 'Guardfile' => :ruby, 'Vagrantfile' => :ruby, 'Appraisals' => :ruby } end end coderay-1.1.1/lib/coderay/for_redcloth.rb0000644000004100000410000000566312663664402020406 0ustar www-datawww-datamodule CodeRay # A little hack to enable CodeRay highlighting in RedCloth. # # Usage: # require 'coderay' # require 'coderay/for_redcloth' # RedCloth.new('@[ruby]puts "Hello, World!"@').to_html # # Make sure you have RedCloth 4.0.3 activated, for example by calling # require 'rubygems' # before RedCloth is loaded and before calling CodeRay.for_redcloth. module ForRedCloth def self.install gem 'RedCloth', '>= 4.0.3' if defined? gem require 'redcloth' unless RedCloth::VERSION.to_s >= '4.0.3' if defined? gem raise 'CodeRay.for_redcloth needs RedCloth version 4.0.3 or later. ' + "You have #{RedCloth::VERSION}. Please gem install RedCloth." else $".delete 'redcloth.rb' # sorry, but it works require 'rubygems' return install # retry end end unless RedCloth::VERSION.to_s >= '4.2.2' warn 'CodeRay.for_redcloth works best with RedCloth version 4.2.2 or later.' end RedCloth::TextileDoc.send :include, ForRedCloth::TextileDoc RedCloth::Formatters::HTML.module_eval do def unescape(html) # :nodoc: replacements = { '&' => '&', '"' => '"', '>' => '>', '<' => '<', } html.gsub(/&(?:amp|quot|[gl]t);/) { |entity| replacements[entity] } end undef code, bc_open, bc_close, escape_pre def code(opts) # :nodoc: opts[:block] = true if !opts[:lang] && RedCloth::VERSION.to_s >= '4.2.0' # simulating pre-4.2 behavior if opts[:text].sub!(/\A\[(\w+)\]/, '') if CodeRay::Scanners[$1].lang == :text opts[:text] = $& + opts[:text] else opts[:lang] = $1 end end end if opts[:lang] && !filter_coderay require 'coderay' @in_bc ||= nil format = @in_bc ? :div : :span opts[:text] = unescape(opts[:text]) unless @in_bc highlighted_code = CodeRay.encode opts[:text], opts[:lang], format highlighted_code.sub!(/\A<(span|div)/) { |m| m + pba(@in_bc || opts) } highlighted_code else "#{opts[:text]}" end end def bc_open(opts) # :nodoc: opts[:block] = true @in_bc = opts opts[:lang] ? '' : "" end def bc_close(opts) # :nodoc: opts = @in_bc @in_bc = nil opts[:lang] ? '' : "\n" end def escape_pre(text) # :nodoc: if @in_bc ||= nil text else html_esc(text, :html_escape_preformatted) end end end end module TextileDoc # :nodoc: attr_accessor :filter_coderay end end end CodeRay::ForRedCloth.installcoderay-1.1.1/lib/coderay/styles.rb0000644000004100000410000000041712663664402017247 0ustar www-datawww-datamodule CodeRay # This module holds the Style class and its subclasses. # # See Plugin. module Styles extend PluginHost plugin_path File.dirname(__FILE__), 'styles' autoload :Style, CodeRay.coderay_path('styles', 'style') end end coderay-1.1.1/lib/coderay/scanners.rb0000644000004100000410000000122712663664402017540 0ustar www-datawww-datarequire 'strscan' module CodeRay autoload :WordList, coderay_path('helpers', 'word_list') # = Scanners # # This module holds the Scanner class and its subclasses. # For example, the Ruby scanner is named CodeRay::Scanners::Ruby # can be found in coderay/scanners/ruby. # # Scanner also provides methods and constants for the register # mechanism and the [] method that returns the Scanner class # belonging to the given lang. # # See PluginHost. module Scanners extend PluginHost plugin_path File.dirname(__FILE__), 'scanners' autoload :Scanner, CodeRay.coderay_path('scanners', 'scanner') end end coderay-1.1.1/metadata.yml0000644000004100000410000000720512663664402015510 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: coderay version: !ruby/object:Gem::Version version: 1.1.1 platform: ruby authors: - Kornelius Kalnbach autorequire: bindir: bin cert_chain: [] date: 2016-02-20 00:00:00.000000000 Z dependencies: [] description: Fast and easy syntax highlighting for selected languages, written in Ruby. Comes with RedCloth integration and LOC counter. email: - murphy@rubychan.de executables: - coderay extensions: [] extra_rdoc_files: - README_INDEX.rdoc files: - README_INDEX.rdoc - Rakefile - bin/coderay - lib/coderay.rb - lib/coderay/duo.rb - lib/coderay/encoders.rb - lib/coderay/encoders/_map.rb - lib/coderay/encoders/comment_filter.rb - lib/coderay/encoders/count.rb - lib/coderay/encoders/debug.rb - lib/coderay/encoders/debug_lint.rb - lib/coderay/encoders/div.rb - lib/coderay/encoders/encoder.rb - lib/coderay/encoders/filter.rb - lib/coderay/encoders/html.rb - lib/coderay/encoders/html/css.rb - lib/coderay/encoders/html/numbering.rb - lib/coderay/encoders/html/output.rb - lib/coderay/encoders/json.rb - lib/coderay/encoders/lines_of_code.rb - lib/coderay/encoders/lint.rb - lib/coderay/encoders/null.rb - lib/coderay/encoders/page.rb - lib/coderay/encoders/span.rb - lib/coderay/encoders/statistic.rb - lib/coderay/encoders/terminal.rb - lib/coderay/encoders/text.rb - lib/coderay/encoders/token_kind_filter.rb - lib/coderay/encoders/xml.rb - lib/coderay/encoders/yaml.rb - lib/coderay/for_redcloth.rb - lib/coderay/helpers/file_type.rb - lib/coderay/helpers/plugin.rb - lib/coderay/helpers/plugin_host.rb - lib/coderay/helpers/word_list.rb - lib/coderay/scanners.rb - lib/coderay/scanners/_map.rb - lib/coderay/scanners/c.rb - lib/coderay/scanners/clojure.rb - lib/coderay/scanners/cpp.rb - lib/coderay/scanners/css.rb - lib/coderay/scanners/debug.rb - lib/coderay/scanners/delphi.rb - lib/coderay/scanners/diff.rb - lib/coderay/scanners/erb.rb - lib/coderay/scanners/go.rb - lib/coderay/scanners/groovy.rb - lib/coderay/scanners/haml.rb - lib/coderay/scanners/html.rb - lib/coderay/scanners/java.rb - lib/coderay/scanners/java/builtin_types.rb - lib/coderay/scanners/java_script.rb - lib/coderay/scanners/json.rb - lib/coderay/scanners/lua.rb - lib/coderay/scanners/php.rb - lib/coderay/scanners/python.rb - lib/coderay/scanners/raydebug.rb - lib/coderay/scanners/ruby.rb - lib/coderay/scanners/ruby/patterns.rb - lib/coderay/scanners/ruby/string_state.rb - lib/coderay/scanners/sass.rb - lib/coderay/scanners/scanner.rb - lib/coderay/scanners/sql.rb - lib/coderay/scanners/taskpaper.rb - lib/coderay/scanners/text.rb - lib/coderay/scanners/xml.rb - lib/coderay/scanners/yaml.rb - lib/coderay/styles.rb - lib/coderay/styles/_map.rb - lib/coderay/styles/alpha.rb - lib/coderay/styles/style.rb - lib/coderay/token_kinds.rb - lib/coderay/tokens.rb - lib/coderay/tokens_proxy.rb - lib/coderay/version.rb - test/functional/basic.rb - test/functional/examples.rb - test/functional/for_redcloth.rb - test/functional/suite.rb homepage: http://coderay.rubychan.de licenses: - MIT metadata: {} post_install_message: rdoc_options: - "-SNw2" - "-mREADME_INDEX.rdoc" - "-t CodeRay Documentation" require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 1.8.6 required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: coderay rubygems_version: 2.5.1 signing_key: specification_version: 4 summary: Fast syntax highlighting for selected languages. test_files: - test/functional/basic.rb - test/functional/examples.rb - test/functional/for_redcloth.rb - test/functional/suite.rb coderay-1.1.1/test/0000755000004100000410000000000012663664402014160 5ustar www-datawww-datacoderay-1.1.1/test/functional/0000755000004100000410000000000012663664402016322 5ustar www-datawww-datacoderay-1.1.1/test/functional/examples.rb0000755000004100000410000001227212663664402020474 0ustar www-datawww-datarequire 'test/unit' $:.unshift File.expand_path('../../../lib', __FILE__) require 'coderay' class ExamplesTest < Test::Unit::TestCase def test_examples # output as HTML div (using inline CSS styles) div = CodeRay.scan('puts "Hello, world!"', :ruby).div assert_equal <<-DIV, div
puts "Hello, world!"
DIV # ...with line numbers div = CodeRay.scan(<<-CODE.chomp, :ruby).div(:line_numbers => :table) 5.times do puts 'Hello, world!' end CODE assert_equal <<-DIV, div
1
2
3
5.times do
  puts 'Hello, world!'
end
DIV # output as standalone HTML page (using CSS classes) page = CodeRay.scan('puts "Hello, world!"', :ruby).page assert_match <<-PAGE, page
1
puts "Hello, world!"
PAGE # keep scanned tokens for later use tokens = CodeRay.scan('{ "just": "an", "example": 42 }', :json) assert_kind_of CodeRay::TokensProxy, tokens assert_equal ["{", :operator, " ", :space, :begin_group, :key, "\"", :delimiter, "just", :content, "\"", :delimiter, :end_group, :key, ":", :operator, " ", :space, :begin_group, :string, "\"", :delimiter, "an", :content, "\"", :delimiter, :end_group, :string, ",", :operator, " ", :space, :begin_group, :key, "\"", :delimiter, "example", :content, "\"", :delimiter, :end_group, :key, ":", :operator, " ", :space, "42", :integer, " ", :space, "}", :operator], tokens.tokens # produce a token statistic assert_equal <<-STATISTIC, tokens.statistic Code Statistics Tokens 26 Non-Whitespace 15 Bytes Total 31 Token Types (7): type count ratio size (average) ------------------------------------------------------------- TOTAL 26 100.00 % 1.2 delimiter 6 23.08 % 1.0 operator 5 19.23 % 1.0 space 5 19.23 % 1.0 key 4 15.38 % 0.0 :begin_group 3 11.54 % 0.0 :end_group 3 11.54 % 0.0 content 3 11.54 % 4.3 string 2 7.69 % 0.0 integer 1 3.85 % 2.0 STATISTIC # count the tokens assert_equal 26, tokens.count # produce a HTML div, but with CSS classes div = tokens.div(:css => :class) assert_equal <<-DIV, div
{ "just": "an", "example": 42 }
DIV # highlight a file (HTML div); guess the file type base on the extension assert_equal :ruby, CodeRay::FileType[__FILE__] # get a new scanner for Python python_scanner = CodeRay.scanner :python assert_kind_of CodeRay::Scanners::Python, python_scanner # get a new encoder for terminal terminal_encoder = CodeRay.encoder :term assert_kind_of CodeRay::Encoders::Terminal, terminal_encoder # scanning into tokens tokens = python_scanner.tokenize 'import this; # The Zen of Python' assert_equal ["import", :keyword, " ", :space, "this", :include, ";", :operator, " ", :space, "# The Zen of Python", :comment], tokens # format the tokens term = terminal_encoder.encode_tokens(tokens) assert_equal "\e[32mimport\e[0m \e[31mthis\e[0m; \e[1;30m# The Zen of Python\e[0m", term # re-using scanner and encoder ruby_highlighter = CodeRay::Duo[:ruby, :div] div = ruby_highlighter.encode('puts "Hello, world!"') assert_equal <<-DIV, div
puts "Hello, world!"
DIV end end coderay-1.1.1/test/functional/suite.rb0000755000004100000410000000064412663664402020007 0ustar www-datawww-datarequire 'test/unit' $VERBOSE = $CODERAY_DEBUG = true $:.unshift File.expand_path('../../../lib', __FILE__) require 'coderay' mydir = File.dirname(__FILE__) suite = Dir[File.join(mydir, '*.rb')]. map { |tc| File.basename(tc).sub(/\.rb$/, '') } - %w'suite for_redcloth' puts "Running basic CodeRay #{CodeRay::VERSION} tests: #{suite.join(', ')}" for test_case in suite load File.join(mydir, test_case + '.rb') end coderay-1.1.1/test/functional/basic.rb0000755000004100000410000002112512663664402017734 0ustar www-datawww-data# encoding: utf-8 require 'test/unit' require File.expand_path('../../lib/assert_warning', __FILE__) $:.unshift File.expand_path('../../../lib', __FILE__) require 'coderay' class BasicTest < Test::Unit::TestCase def test_version assert_nothing_raised do assert_match(/\A\d\.\d\.\d?\z/, CodeRay::VERSION) end end def with_empty_load_path old_load_path = $:.dup $:.clear yield ensure $:.replace old_load_path end def test_autoload with_empty_load_path do assert_nothing_raised do CodeRay::Scanners::Java::BuiltinTypes end end end RUBY_TEST_CODE = 'puts "Hello, World!"' RUBY_TEST_TOKENS = [ ['puts', :ident], [' ', :space], [:begin_group, :string], ['"', :delimiter], ['Hello, World!', :content], ['"', :delimiter], [:end_group, :string] ].flatten def test_simple_scan assert_nothing_raised do assert_equal RUBY_TEST_TOKENS, CodeRay.scan(RUBY_TEST_CODE, :ruby).tokens end end RUBY_TEST_HTML = 'puts "' + 'Hello, World!"' def test_simple_highlight assert_nothing_raised do assert_equal RUBY_TEST_HTML, CodeRay.scan(RUBY_TEST_CODE, :ruby).html end end def test_scan_file CodeRay.scan_file __FILE__ end def test_encode assert_equal 1, CodeRay.encode('test', :python, :count) end def test_encode_tokens assert_equal 1, CodeRay.encode_tokens(CodeRay::Tokens['test', :string], :count) end def test_encode_file assert_equal File.read(__FILE__), CodeRay.encode_file(__FILE__, :text) end def test_highlight assert_match '
test
', CodeRay.highlight('test', :python) end def test_highlight_file assert_match "require 'test/unit'\n", CodeRay.highlight_file(__FILE__) end def test_duo assert_equal(RUBY_TEST_CODE, CodeRay::Duo[:plain, :text].highlight(RUBY_TEST_CODE)) assert_equal(RUBY_TEST_CODE, CodeRay::Duo[:plain => :text].highlight(RUBY_TEST_CODE)) end def test_duo_stream assert_equal(RUBY_TEST_CODE, CodeRay::Duo[:plain, :text].highlight(RUBY_TEST_CODE, :stream => true)) end def test_comment_filter assert_equal <<-EXPECTED, CodeRay.scan(<<-INPUT, :ruby).comment_filter.text #!/usr/bin/env ruby code more code EXPECTED #!/usr/bin/env ruby =begin A multi-line comment. =end code # A single-line comment. more code # and another comment, in-line. INPUT end def test_lines_of_code assert_equal 2, CodeRay.scan(<<-INPUT, :ruby).lines_of_code #!/usr/bin/env ruby =begin A multi-line comment. =end code # A single-line comment. more code # and another comment, in-line. INPUT rHTML = <<-RHTML <%= controller.controller_name.titleize %>: <%= controller.action_name %> <%= stylesheet_link_tag 'scaffold' %>

<%= flash[:notice] %>

<%= yield %>
RHTML assert_equal 0, CodeRay.scan(rHTML, :html).lines_of_code assert_equal 0, CodeRay.scan(rHTML, :php).lines_of_code assert_equal 0, CodeRay.scan(rHTML, :yaml).lines_of_code assert_equal 4, CodeRay.scan(rHTML, :erb).lines_of_code end def test_list_of_encoders assert_kind_of(Array, CodeRay::Encoders.list) assert CodeRay::Encoders.list.include?(:count) end def test_list_of_scanners assert_kind_of(Array, CodeRay::Scanners.list) assert CodeRay::Scanners.list.include?(:text) end def test_token_kinds assert_kind_of Hash, CodeRay::TokenKinds for kind, css_class in CodeRay::TokenKinds assert_kind_of Symbol, kind if css_class != false assert_kind_of String, css_class, "TokenKinds[%p] == %p" % [kind, css_class] end end assert_equal 'reserved', CodeRay::TokenKinds[:reserved] assert_equal false, CodeRay::TokenKinds[:shibboleet] end class Milk < CodeRay::Encoders::Encoder FILE_EXTENSION = 'cocoa' end class HoneyBee < CodeRay::Encoders::Encoder end def test_encoder_file_extension assert_nothing_raised do assert_equal 'html', CodeRay::Encoders::Page::FILE_EXTENSION assert_equal 'cocoa', Milk::FILE_EXTENSION assert_equal 'cocoa', Milk.new.file_extension assert_equal 'honeybee', HoneyBee::FILE_EXTENSION assert_equal 'honeybee', HoneyBee.new.file_extension end assert_raise NameError do HoneyBee::MISSING_CONSTANT end end def test_encoder_tokens encoder = CodeRay::Encoders::Encoder.new encoder.send :setup, {} assert_raise(ArgumentError) { encoder.token :strange, '' } encoder.token 'test', :debug end def test_encoder_deprecated_interface encoder = CodeRay::Encoders::Encoder.new encoder.send :setup, {} assert_warning 'Using old Tokens#<< interface.' do encoder << ['test', :content] end assert_raise ArgumentError do encoder << [:strange, :input] end assert_raise ArgumentError do encoder.encode_tokens [['test', :token]] end end def encoder_token_interface_deprecation_warning_given CodeRay::Encoders::Encoder.send :class_variable_get, :@@CODERAY_TOKEN_INTERFACE_DEPRECATION_WARNING_GIVEN end def test_scanner_file_extension assert_equal 'rb', CodeRay::Scanners::Ruby.file_extension assert_equal 'rb', CodeRay::Scanners::Ruby.new.file_extension assert_equal 'java', CodeRay::Scanners::Java.file_extension assert_equal 'java', CodeRay::Scanners::Java.new.file_extension end def test_scanner_lang assert_equal :ruby, CodeRay::Scanners::Ruby.lang assert_equal :ruby, CodeRay::Scanners::Ruby.new.lang assert_equal :java, CodeRay::Scanners::Java.lang assert_equal :java, CodeRay::Scanners::Java.new.lang end def test_scanner_tokenize assert_equal ['foo', :plain], CodeRay::Scanners::Plain.new.tokenize('foo') assert_equal [['foo', :plain], ['bar', :plain]], CodeRay::Scanners::Plain.new.tokenize(['foo', 'bar']) CodeRay::Scanners::Plain.new.tokenize 42 end def test_scanner_tokens scanner = CodeRay::Scanners::Plain.new scanner.tokenize('foo') assert_equal ['foo', :plain], scanner.tokens scanner.string = '' assert_equal ['', :plain], scanner.tokens end def test_scanner_line_and_column scanner = CodeRay::Scanners::Plain.new "foo\nbär+quux" assert_equal 0, scanner.pos assert_equal 1, scanner.line assert_equal 1, scanner.column scanner.scan(/foo/) assert_equal 3, scanner.pos assert_equal 1, scanner.line assert_equal 4, scanner.column scanner.scan(/\n/) assert_equal 4, scanner.pos assert_equal 2, scanner.line assert_equal 1, scanner.column scanner.scan(/b/) assert_equal 5, scanner.pos assert_equal 2, scanner.line assert_equal 2, scanner.column scanner.scan(/a/) assert_equal 5, scanner.pos assert_equal 2, scanner.line assert_equal 2, scanner.column scanner.scan(/ä/) assert_equal 7, scanner.pos assert_equal 2, scanner.line assert_equal 4, scanner.column scanner.scan(/r/) assert_equal 8, scanner.pos assert_equal 2, scanner.line assert_equal 5, scanner.column end def test_scanner_use_subclasses assert_raise NotImplementedError do CodeRay::Scanners::Scanner.new end end class InvalidScanner < CodeRay::Scanners::Scanner end def test_scanner_scan_tokens assert_raise NotImplementedError do InvalidScanner.new.tokenize '' end end class RaisingScanner < CodeRay::Scanners::Scanner def scan_tokens encoder, options raise_inspect 'message', [], :initial end end def test_scanner_raise_inspect assert_raise CodeRay::Scanners::Scanner::ScanError do RaisingScanner.new.tokenize '' end end def test_scan_a_frozen_string assert_nothing_raised do CodeRay.scan RUBY_VERSION, :ruby CodeRay.scan RUBY_VERSION, :plain end end def test_scan_a_non_string assert_nothing_raised do CodeRay.scan 42, :ruby CodeRay.scan nil, :ruby CodeRay.scan self, :ruby CodeRay.encode ENV.to_hash, :ruby, :page CodeRay.highlight CodeRay, :plain end end end coderay-1.1.1/test/functional/for_redcloth.rb0000644000004100000410000000602712663664402021326 0ustar www-datawww-datarequire 'test/unit' $:.unshift File.expand_path('../../../lib', __FILE__) require 'coderay' begin require 'rubygems' unless defined? Gem gem 'RedCloth', '>= 4.0.3' rescue nil require 'redcloth' rescue LoadError warn 'RedCloth not found - skipping for_redcloth tests.' undef RedCloth if defined? RedCloth end class BasicTest < Test::Unit::TestCase def test_for_redcloth require 'coderay/for_redcloth' assert_equal "

puts "Hello, World!"

", RedCloth.new('@[ruby]puts "Hello, World!"@').to_html assert_equal <<-BLOCKCODE.chomp,
puts "Hello, World!"
BLOCKCODE RedCloth.new('bc[ruby]. puts "Hello, World!"').to_html end def test_for_redcloth_no_lang require 'coderay/for_redcloth' assert_equal "

puts \"Hello, World!\"

", RedCloth.new('@puts "Hello, World!"@').to_html assert_equal <<-BLOCKCODE.chomp,
puts \"Hello, World!\"
BLOCKCODE RedCloth.new('bc. puts "Hello, World!"').to_html end def test_for_redcloth_style require 'coderay/for_redcloth' assert_equal <<-BLOCKCODE.chomp,
puts \"Hello, World!\"
BLOCKCODE RedCloth.new('bc{color: red}. puts "Hello, World!"').to_html end def test_for_redcloth_escapes require 'coderay/for_redcloth' assert_equal '

>

', RedCloth.new('@[ruby]>@').to_html assert_equal <<-BLOCKCODE.chomp,
&
BLOCKCODE RedCloth.new('bc[ruby]. &').to_html end def test_for_redcloth_escapes2 require 'coderay/for_redcloth' assert_equal "

#include <test.h>

", RedCloth.new('@[c]#include @').to_html end # See http://jgarber.lighthouseapp.com/projects/13054/tickets/124-code-markup-does-not-allow-brackets. def test_for_redcloth_false_positive require 'coderay/for_redcloth' assert_equal '

[project]_dff.skjd

', RedCloth.new('@[project]_dff.skjd@').to_html # false positive, but expected behavior / known issue assert_equal "

_dff.skjd

", RedCloth.new('@[ruby]_dff.skjd@').to_html assert_equal <<-BLOCKCODE.chomp, RedCloth.new('bc. [project]_dff.skjd').to_html
[project]_dff.skjd
BLOCKCODE end end if defined? RedClothcoderay-1.1.1/README_INDEX.rdoc0000644000004100000410000001072312663664402015741 0ustar www-datawww-data= CodeRay Tired of blue'n'gray? Try the original version of this documentation on coderay.rubychan.de[http://coderay.rubychan.de/doc/] :-) == About CodeRay is a Ruby library for syntax highlighting. You put your code in, and you get it back colored; Keywords, strings, floats, comments - all in different colors. And with line numbers. *Syntax* *Highlighting*... * makes code easier to read and maintain * lets you detect syntax errors faster * helps you to understand the syntax of a language * looks nice * is what everybody wants to have on their website * solves all your problems and makes the girls run after you == Installation % gem install coderay === Dependencies CodeRay needs Ruby 1.8.7+ or 1.9.2+. It also runs on Rubinius and JRuby. == Example Usage require 'coderay' html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table) == Documentation See CodeRay. == Credits === Special Thanks to * licenser (Heinz N. Gies) for ending my QBasic career, inventing the Coder project and the input/output plugin system. CodeRay would not exist without him. * bovi (Daniel Bovensiepen) for helping me out on various occasions. === Thanks to * Caleb Clausen for writing RubyLexer (see http://rubyforge.org/projects/rubylexer) and lots of very interesting mail traffic * birkenfeld (Georg Brandl) and mitsuhiku (Arnim Ronacher) for PyKleur, now pygments. You guys rock! * Jamis Buck for writing Syntax (see http://rubyforge.org/projects/syntax) I got some useful ideas from it. * Doug Kearns and everyone else who worked on ruby.vim - it not only helped me coding CodeRay, but also gave me a wonderful target to reach for the Ruby scanner. * everyone who uses CodeBB on http://www.rubyforen.de and http://www.python-forum.de * iGEL, magichisoka, manveru, WoNáDo and everyone I forgot from rubyforen.de * Dethix from ruby-mine.de * zickzackw * Dookie (who is no longer with us...) and Leonidas from http://www.python-forum.de * Andreas Schwarz for finding out that CaseIgnoringWordList was not case ignoring! Such things really make you write tests. * closure for the first version of the Scheme scanner. * Stefan Walk for the first version of the JavaScript and PHP scanners. * Josh Goebel for another version of the JavaScript scanner, a SQL and a Diff scanner. * Jonathan Younger for pointing out the licence confusion caused by wrong LICENSE file. * Jeremy Hinegardner for finding the shebang-on-empty-file bug in FileType. * Charles Oliver Nutter and Yehuda Katz for helping me benchmark CodeRay on JRuby. * Andreas Neuhaus for pointing out a markup bug in coderay/for_redcloth. * 0xf30fc7 for the FileType patch concerning Delphi file extensions. * The folks at redmine.org - thank you for using and fixing CodeRay! * Keith Pitt for his SQL scanners * Rob Aldred for the terminal encoder * Trans for pointing out $DEBUG dependencies * Flameeyes for finding that Term::ANSIColor was obsolete * matz and all Ruby gods and gurus * The inventors of: the computer, the internet, the true color display, HTML & CSS, VIM, Ruby, pizza, microwaves, guitars, scouting, programming, anime, manga, coke and green ice tea. Where would we be without all those people? === Created using * Ruby[http://ruby-lang.org/] * Chihiro (my Sony VAIO laptop); Henrietta (my old MacBook); Triella, born Rico (my new MacBook); as well as Seras and Hikari (my PCs) * RDE[http://homepage2.nifty.com/sakazuki/rde_e.html], VIM[http://vim.org] and TextMate[http://macromates.com] * Subversion[http://subversion.tigris.org/] * Redmine[http://redmine.org/] * Firefox[http://www.mozilla.org/products/firefox/], Firebug[http://getfirebug.com/], Safari[http://www.apple.com/safari/], and Thunderbird[http://www.mozilla.org/products/thunderbird/] * RubyGems[http://docs.rubygems.org/] and Rake[http://rake.rubyforge.org/] * TortoiseSVN[http://tortoisesvn.tigris.org/] using Apache via XAMPP[http://www.apachefriends.org/en/xampp.html] * RDoc (though I'm quite unsatisfied with it) * Microsoft Windows (yes, I confess!) and MacOS X * GNUWin32, MinGW and some other tools to make the shell under windows a bit less useless * Term::ANSIColor[http://term-ansicolor.rubyforge.org/] * PLEAC[http://pleac.sourceforge.net/] code examples * Github * Travis CI (http://travis-ci.org/rubychan/github) === Free * As you can see, CodeRay was created under heavy use of *free* software. * So CodeRay is also *free*. * If you use CodeRay to create software, think about making this software *free*, too. * Thanks :)