annotate .svn/pristine/0f/0f5d0b28aa88dc0b634f0aed6c20653f95af7206.svn-base @ 929:5f33065ddc4b redmine-1.3

Update to Redmine SVN rev 9414 on 1.3-stable branch
author Chris Cannam
date Wed, 27 Jun 2012 14:54:18 +0100
parents cbb26bc654de
children
rev   line source
Chris@909 1 module CodeRay
Chris@909 2
Chris@909 3 # = FileType
Chris@909 4 #
Chris@909 5 # A simple filetype recognizer.
Chris@909 6 #
Chris@909 7 # == Usage
Chris@909 8 #
Chris@909 9 # # determine the type of the given
Chris@909 10 # lang = FileType[file_name]
Chris@909 11 #
Chris@909 12 # # return :text if the file type is unknown
Chris@909 13 # lang = FileType.fetch file_name, :text
Chris@909 14 #
Chris@909 15 # # try the shebang line, too
Chris@909 16 # lang = FileType.fetch file_name, :text, true
Chris@909 17 module FileType
Chris@909 18
Chris@909 19 UnknownFileType = Class.new Exception
Chris@909 20
Chris@909 21 class << self
Chris@909 22
Chris@909 23 # Try to determine the file type of the file.
Chris@909 24 #
Chris@909 25 # +filename+ is a relative or absolute path to a file.
Chris@909 26 #
Chris@909 27 # The file itself is only accessed when +read_shebang+ is set to true.
Chris@909 28 # That means you can get filetypes from files that don't exist.
Chris@909 29 def [] filename, read_shebang = false
Chris@909 30 name = File.basename filename
Chris@909 31 ext = File.extname(name).sub(/^\./, '') # from last dot, delete the leading dot
Chris@909 32 ext2 = filename.to_s[/\.(.*)/, 1] # from first dot
Chris@909 33
Chris@909 34 type =
Chris@909 35 TypeFromExt[ext] ||
Chris@909 36 TypeFromExt[ext.downcase] ||
Chris@909 37 (TypeFromExt[ext2] if ext2) ||
Chris@909 38 (TypeFromExt[ext2.downcase] if ext2) ||
Chris@909 39 TypeFromName[name] ||
Chris@909 40 TypeFromName[name.downcase]
Chris@909 41 type ||= shebang(filename) if read_shebang
Chris@909 42
Chris@909 43 type
Chris@909 44 end
Chris@909 45
Chris@909 46 # This works like Hash#fetch.
Chris@909 47 #
Chris@909 48 # If the filetype cannot be found, the +default+ value
Chris@909 49 # is returned.
Chris@909 50 def fetch filename, default = nil, read_shebang = false
Chris@909 51 if default && block_given?
Chris@909 52 warn 'Block supersedes default value argument; use either.'
Chris@909 53 end
Chris@909 54
Chris@909 55 if type = self[filename, read_shebang]
Chris@909 56 type
Chris@909 57 else
Chris@909 58 return yield if block_given?
Chris@909 59 return default if default
Chris@909 60 raise UnknownFileType, 'Could not determine type of %p.' % filename
Chris@909 61 end
Chris@909 62 end
Chris@909 63
Chris@909 64 protected
Chris@909 65
Chris@909 66 def shebang filename
Chris@909 67 return unless File.exist? filename
Chris@909 68 File.open filename, 'r' do |f|
Chris@909 69 if first_line = f.gets
Chris@909 70 if type = first_line[TypeFromShebang]
Chris@909 71 type.to_sym
Chris@909 72 end
Chris@909 73 end
Chris@909 74 end
Chris@909 75 end
Chris@909 76
Chris@909 77 end
Chris@909 78
Chris@909 79 TypeFromExt = {
Chris@909 80 'c' => :c,
Chris@909 81 'cfc' => :xml,
Chris@909 82 'cfm' => :xml,
Chris@909 83 'clj' => :clojure,
Chris@909 84 'css' => :css,
Chris@909 85 'diff' => :diff,
Chris@909 86 'dpr' => :delphi,
Chris@909 87 'gemspec' => :ruby,
Chris@909 88 'groovy' => :groovy,
Chris@909 89 'gvy' => :groovy,
Chris@909 90 'h' => :c,
Chris@909 91 'haml' => :haml,
Chris@909 92 'htm' => :page,
Chris@909 93 'html' => :page,
Chris@909 94 'html.erb' => :erb,
Chris@909 95 'java' => :java,
Chris@909 96 'js' => :java_script,
Chris@909 97 'json' => :json,
Chris@909 98 'mab' => :ruby,
Chris@909 99 'pas' => :delphi,
Chris@909 100 'patch' => :diff,
Chris@909 101 'php' => :php,
Chris@909 102 'php3' => :php,
Chris@909 103 'php4' => :php,
Chris@909 104 'php5' => :php,
Chris@909 105 'prawn' => :ruby,
Chris@909 106 'py' => :python,
Chris@909 107 'py3' => :python,
Chris@909 108 'pyw' => :python,
Chris@909 109 'rake' => :ruby,
Chris@909 110 'raydebug' => :raydebug,
Chris@909 111 'rb' => :ruby,
Chris@909 112 'rbw' => :ruby,
Chris@909 113 'rhtml' => :erb,
Chris@909 114 'rjs' => :ruby,
Chris@909 115 'rpdf' => :ruby,
Chris@909 116 'ru' => :ruby,
Chris@909 117 'rxml' => :ruby,
Chris@909 118 # 'sch' => :scheme,
Chris@909 119 'sql' => :sql,
Chris@909 120 # 'ss' => :scheme,
Chris@909 121 'xhtml' => :page,
Chris@909 122 'xml' => :xml,
Chris@909 123 'yaml' => :yaml,
Chris@909 124 'yml' => :yaml,
Chris@909 125 }
Chris@909 126 for cpp_alias in %w[cc cpp cp cxx c++ C hh hpp h++ cu]
Chris@909 127 TypeFromExt[cpp_alias] = :cpp
Chris@909 128 end
Chris@909 129
Chris@909 130 TypeFromShebang = /\b(?:ruby|perl|python|sh)\b/
Chris@909 131
Chris@909 132 TypeFromName = {
Chris@909 133 'Capfile' => :ruby,
Chris@909 134 'Rakefile' => :ruby,
Chris@909 135 'Rantfile' => :ruby,
Chris@909 136 'Gemfile' => :ruby,
Chris@909 137 }
Chris@909 138
Chris@909 139 end
Chris@909 140
Chris@909 141 end