diff options
Diffstat (limited to 'lib/coderay/helpers')
-rw-r--r-- | lib/coderay/helpers/file_type.rb | 244 | ||||
-rw-r--r-- | lib/coderay/helpers/plugin.rb | 186 |
2 files changed, 163 insertions, 267 deletions
diff --git a/lib/coderay/helpers/file_type.rb b/lib/coderay/helpers/file_type.rb index 8b1a728..2cbaa6d 100644 --- a/lib/coderay/helpers/file_type.rb +++ b/lib/coderay/helpers/file_type.rb @@ -1,69 +1,70 @@ module CodeRay - -# = FileType -# -# A simple filetype recognizer. -# -# == Usage -# -# # determine the type of the given -# lang = FileType[ARGV.first] -# -# # return :plaintext if the file type is unknown -# lang = FileType.fetch ARGV.first, :plaintext -# -# # try the shebang line, too -# lang = FileType.fetch ARGV.first, :plaintext, 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 ||= 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 and block_given? - warn 'Block supersedes default value argument; use either.' - end - - unless type = self[filename, read_shebang] - return yield if block_given? - return default if default - raise UnknownFileType, 'Could not determine type of %p.' % filename - end - type - end + + # = FileType + # + # A simple filetype recognizer. + # + # == Usage + # + # # determine the type of the given + # lang = FileType[ARGV.first] + # + # # return :plaintext if the file type is unknown + # lang = FileType.fetch ARGV.first, :plaintext + # + # # try the shebang line, too + # lang = FileType.fetch ARGV.first, :plaintext, true + module FileType - protected + UnknownFileType = Class.new Exception - def shebang filename - begin + 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 ||= 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 shebang filename + return unless File.exist? filename File.open filename, 'r' do |f| if first_line = f.gets if type = first_line[TypeFromShebang] @@ -71,67 +72,64 @@ module FileType end end end - rescue IOError - nil end + end - - end - - TypeFromExt = { - 'c' => :c, - 'clj' => :clojure, - 'css' => :css, - 'diff' => :diff, - 'dpr' => :delphi, - 'gemspec' => :ruby, - 'groovy' => :groovy, - 'gvy' => :groovy, - 'h' => :c, - 'htm' => :html, - 'html' => :html, - 'html.erb' => :rhtml, - 'java' => :java, - 'js' => :java_script, - 'json' => :json, - 'mab' => :ruby, - 'pas' => :delphi, - 'patch' => :diff, - 'php' => :php, - 'php3' => :php, - 'php4' => :php, - 'php5' => :php, - 'py' => :python, - 'py3' => :python, - 'pyw' => :python, - 'rake' => :ruby, - 'raydebug' => :raydebug, - 'rb' => :ruby, - 'rbw' => :ruby, - 'rhtml' => :rhtml, - 'rjs' => :ruby, - 'rpdf' => :ruby, - 'rxml' => :ruby, - 'sch' => :scheme, - 'sql' => :sql, - 'ss' => :scheme, - 'xhtml' => :xhtml, - '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 + + TypeFromExt = { + 'c' => :c, + 'clj' => :clojure, + 'css' => :css, + 'diff' => :diff, + 'dpr' => :delphi, + 'gemspec' => :ruby, + 'groovy' => :groovy, + 'gvy' => :groovy, + 'h' => :c, + 'htm' => :html, + 'html' => :html, + 'html.erb' => :rhtml, + 'java' => :java, + 'js' => :java_script, + 'json' => :json, + 'mab' => :ruby, + 'pas' => :delphi, + 'patch' => :diff, + 'php' => :php, + 'php3' => :php, + 'php4' => :php, + 'php5' => :php, + 'py' => :python, + 'py3' => :python, + 'pyw' => :python, + 'rake' => :ruby, + 'raydebug' => :raydebug, + 'rb' => :ruby, + 'rbw' => :ruby, + 'rhtml' => :rhtml, + 'rjs' => :ruby, + 'rpdf' => :ruby, + 'rxml' => :ruby, + 'sch' => :scheme, + 'sql' => :sql, + 'ss' => :scheme, + 'xhtml' => :xhtml, + '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, + } + end - - TypeFromShebang = /\b(?:ruby|perl|python|sh)\b/ - - TypeFromName = { - 'Capfile' => :ruby, - 'Rakefile' => :ruby, - 'Rantfile' => :ruby, - } - -end - + end diff --git a/lib/coderay/helpers/plugin.rb b/lib/coderay/helpers/plugin.rb index 96bfdd6..f4f6739 100644 --- a/lib/coderay/helpers/plugin.rb +++ b/lib/coderay/helpers/plugin.rb @@ -5,7 +5,8 @@ module CodeRay # A simple subclass/subfolder plugin system. # # Example: - # class Generators < PluginHost + # class Generators + # extend PluginHost # plugin_path 'app/generators' # end # @@ -65,16 +66,6 @@ module CodeRay load id end - # Loads a helper file for the given +plugin_id+ and +helper_name+. - # Helpers are located in a folder with the name of the plugin, - # so if you have a plugin called "plugin" inside a folder named "plugins" - # and a helper named "helper", this method will try to load - # "plugins/plugin/helper". - def require_helper plugin_id, helper_name - path = path_to File.join(plugin_id, helper_name) - require path - end - class << self # Adds the module/class to the PLUGIN_HOSTS list. @@ -82,45 +73,14 @@ module CodeRay PLUGIN_HOSTS << mod end - # Warns you that you should not #include this module. - def included mod - warn "#{name} should not be included. Use extend." - end - - # Find the PluginHost for host_id. - def host_by_id host_id - unless PLUGIN_HOSTS_BY_ID.default_proc - ph = Hash.new do |h, a_host_id| - for host in PLUGIN_HOSTS - h[host.host_id] = host - end - h.fetch a_host_id, nil - end - PLUGIN_HOSTS_BY_ID.replace ph - end - PLUGIN_HOSTS_BY_ID[host_id] - 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) - load_map - end - @plugin_path - end - - # The host's ID. - # - # If PLUGIN_HOST_ID is not set, it is simply the class name. - def host_id - if self.const_defined? :PLUGIN_HOST_ID - self::PLUGIN_HOST_ID - else - name end + @plugin_path ||= '' end # Map a plugin_id to another. @@ -141,7 +101,7 @@ module CodeRay end # Define the default plugin to use when no plugin is found - # for a given id. + # for a given id, or return the default plugin. # # See also map. # @@ -149,12 +109,14 @@ module CodeRay # 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 plugin_hash[nil] = id else - plugin_hash[nil] + load nil end end @@ -164,17 +126,13 @@ module CodeRay # See Plugin#register_for. def register plugin, *ids for id in ids - unless id.is_a? Symbol - raise ArgumentError, - "id must be a Symbol, but it was a #{id.class}" - end plugin_hash[validate_id(id)] = plugin end end # A Hash of plugion_id => Plugin pairs. def plugin_hash - @plugin_hash ||= create_plugin_hash + @plugin_hash ||= make_plugin_hash end # Returns an array of all .rb files in the plugin path. @@ -184,7 +142,7 @@ module CodeRay Dir[path_to('*')].select do |file| File.basename(file)[/^(?!_)\w+\.rb$/] end.map do |file| - File.basename file, '.rb' + File.basename(file, '.rb').to_sym end end @@ -203,39 +161,38 @@ module CodeRay all_plugins.map { |plugin| plugin.title } end - # Makes a map of all loaded plugins. - def inspect - map = plugin_hash.dup - map.each do |id, plugin| - map[id] = plugin.to_s[/(?>\w+)$/] - end - "#{name}[#{host_id}]#{map.inspect}" - end - protected - # Created a new plugin list and stores it to @plugin_hash. - def create_plugin_hash - @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? nil # default plugin - h[id] = h[nil] + + # Return a plugin hash that automatically loads plugins. + def make_plugin_hash + map_loaded = false + Hash.new do |h, plugin_id| + id = validate_id(plugin_id) + path = path_to id + begin + raise LoadError, "#{path} not found" unless File.exist? path + require path + rescue LoadError => boom + if map_loaded + if h.has_key?(nil) # default plugin + h[nil] else raise PluginNotFound, 'Could not load plugin %p: %s' % [id, boom] end else - # Plugin should have registered by now - unless h.has_key? id - raise PluginNotFound, - "No #{self.name} plugin for #{id.inspect} found in #{path}." - end + load_map + map_loaded = true + h[plugin_id] + 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 - h[id] end + end end # Loads the map file (see map). @@ -243,20 +200,7 @@ module CodeRay # This is done automatically when plugin_path is called. def load_map mapfile = path_to '_map' - if File.exist? mapfile - require mapfile - elsif $VERBOSE - warn 'no _map.rb found for %s' % name - end - end - - # Returns the Plugin for +id+. - # Use it like Hash#fetch. - # - # Example: - # yaml_plugin = MyPluginHost[:yaml, :default] - def fetch id, *args, &blk - plugin_hash.fetch validate_id(id), *args, &blk + require mapfile if File.exist? mapfile end # Returns the expected path to the plugin file for the given id. @@ -276,12 +220,10 @@ module CodeRay if id[/\w+/] == id id.downcase.to_sym else - warn "Invalid id: '#{id}' given." - '' + raise ArgumentError, "Invalid id given: #{id}" end else - raise ArgumentError, - "String or Symbol expected, but #{id.class} given." + raise ArgumentError, "String or Symbol expected, but #{id.class} given." end end @@ -292,15 +234,11 @@ module CodeRay # # Plugins have to include this module. # - # IMPORTANT: use extend for this module. + # IMPORTANT: Use extend for this module. # # See CodeRay::PluginHost for examples. module Plugin - def included mod # :nodoc: - warn "#{name} should not be included. Use extend." - end - # Register this class for the given langs. # Example: # class MyPlugin < PluginHost::BaseClass @@ -326,57 +264,17 @@ module CodeRay # The PluginHost for this Plugin class. def plugin_host host = nil - if host and not host.is_a? PluginHost - raise ArgumentError, - "PluginHost expected, but #{host.class} given." + if host.is_a? PluginHost + const_set :PLUGIN_HOST, host end - self.const_set :PLUGIN_HOST, host if host self::PLUGIN_HOST end - # Require some helper files. - # - # Example: - # - # class MyPlugin < PluginHost::BaseClass - # register_for :my_id - # helper :my_helper - # - # The above example loads the file myplugin/my_helper.rb relative to the - # file in which MyPlugin was defined. - # - # You can also load a helper from a different plugin: - # - # helper 'other_plugin/helper_name' - def helper *helpers - for helper in helpers - if helper.is_a?(String) && helper[/\//] - self::PLUGIN_HOST.require_helper $`, $' - else - self::PLUGIN_HOST.require_helper plugin_id.to_s, helper.to_s - end - end - end - # Returns the plugin id used by the engine. def plugin_id - @plugin_id || name[/\w+$/].downcase + @plugin_id ||= name[/\w+$/].downcase end end - # Convenience method for plugin loading. - # The syntax used is: - # - # CodeRay.require_plugin '<Host ID>/<Plugin ID>' - # - # Returns the loaded plugin. - def self.require_plugin path - host_id, plugin_id = path.split '/', 2 - host = PluginHost.host_by_id(host_id) - raise PluginHost::HostNotFound, - "No host for #{host_id.inspect} found." unless host - host.load plugin_id - end - -end
\ No newline at end of file +end |