comparison .svn/pristine/0f/0f5d0b28aa88dc0b634f0aed6c20653f95af7206.svn-base @ 909:cbb26bc654de redmine-1.3

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