comparison indenters/rbeautify.rb @ 777:f55b7f34a3e1

Updated Ruby Script Beautifier to version 2.9. git-svn-id: svn://svn.code.sf.net/p/universalindent/code/trunk@1054 59b1889a-e5ac-428c-b0c7-476e01d41282
author thomas_-_s <thomas_-_s@59b1889a-e5ac-428c-b0c7-476e01d41282>
date Tue, 27 Dec 2011 13:28:58 +0000
parents 99383b949316
children
comparison
equal deleted inserted replaced
776:f69bf0213445 777:f55b7f34a3e1
1 #!/usr/bin/ruby -w 1 #!/usr/bin/ruby -w
2 2
3 # NEED_SYMLINK
4 3
5 =begin 4 =begin
6 /*************************************************************************** 5 /***************************************************************************
7 * Copyright (C) 2006, Paul Lutus * 6 * Copyright (C) 2008, Paul Lutus *
8 * * 7 * *
9 * This program is free software; you can redistribute it and/or modify * 8 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by * 9 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or * 10 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. * 11 * (at your option) any later version. *
21 * Free Software Foundation, Inc., * 20 * Free Software Foundation, Inc., *
22 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
23 ***************************************************************************/ 22 ***************************************************************************/
24 =end 23 =end
25 24
26 PVERSION = "Version 2.2, 10/29/2007" 25 PVERSION = "Version 2.9, 10/24/2008"
27 26
28 $tabSize = 3 27 module RBeautify
29 $tabStr = " " 28
30 29 # user-customizable values
31 # indent regexp tests 30
32 31 RBeautify::TabStr = " "
33 $indentExp = [ 32 RBeautify::TabSize = 3
34 /^module\b/, 33
35 /^if\b/, 34 # indent regexp tests
36 /(=\s*|^)until\b/, 35
37 /(=\s*|^)for\b/, 36 IndentExp = [
38 /^unless\b/, 37 /^module\b/,
39 /(=\s*|^)while\b/, 38 /^class\b/,
40 /(=\s*|^)begin\b/, 39 /^if\b/,
41 /(^| )case\b/, 40 /(=\s*|^)until\b/,
42 /\bthen\b/, 41 /(=\s*|^)for\b/,
43 /^class\b/, 42 /^unless\b/,
44 /^rescue\b/, 43 /(=\s*|^)while\b/,
45 /^def\b/, 44 /(=\s*|^)begin\b/,
46 /\bdo\b/, 45 /(^| )case\b/,
47 /^else\b/, 46 /\bthen\b/,
48 /^elsif\b/, 47 /^rescue\b/,
49 /^ensure\b/, 48 /^def\b/,
50 /\bwhen\b/, 49 /\bdo\b/,
51 /\{[^\}]*$/, 50 /^else\b/,
52 /\[[^\]]*$/ 51 /^elsif\b/,
53 ] 52 /^ensure\b/,
54 53 /\bwhen\b/,
55 # outdent regexp tests 54 /\{[^\}]*$/,
56 55 /\[[^\]]*$/
57 $outdentExp = [ 56 ]
58 /^rescue\b/, 57
59 /^ensure\b/, 58 # outdent regexp tests
60 /^elsif\b/, 59
61 /^end\b/, 60 OutdentExp = [
62 /^else\b/, 61 /^rescue\b/,
63 /\bwhen\b/, 62 /^ensure\b/,
64 /^[^\{]*\}/, 63 /^elsif\b/,
65 /^[^\[]*\]/ 64 /^end\b/,
66 ] 65 /^else\b/,
67 66 /\bwhen\b/,
68 def makeTab(tab) 67 /^[^\{]*\}/,
69 return (tab < 0)?"":$tabStr * $tabSize * tab 68 /^[^\[]*\]/
69 ]
70
71 def RBeautify.rb_make_tab(tab)
72 return (tab < 0)?"":TabStr * TabSize * tab
73 end
74
75 def RBeautify.rb_add_line(line,tab)
76 line.strip!
77 line = rb_make_tab(tab) + line if line.length > 0
78 return line
79 end
80
81 def RBeautify.beautify_string(source, path = "")
82 comment_block = false
83 in_here_doc = false
84 here_doc_term = ""
85 program_end = false
86 multiLine_array = []
87 multiLine_str = ""
88 tab = 0
89 output = []
90 source.each do |line|
91 line.chomp!
92 if(!program_end)
93 # detect program end mark
94 if(line =~ /^__END__$/)
95 program_end = true
96 else
97 # combine continuing lines
98 if(!(line =~ /^\s*#/) && line =~ /[^\\]\\\s*$/)
99 multiLine_array.push line
100 multiLine_str += line.sub(/^(.*)\\\s*$/,"\\1")
101 next
102 end
103
104 # add final line
105 if(multiLine_str.length > 0)
106 multiLine_array.push line
107 multiLine_str += line.sub(/^(.*)\\\s*$/,"\\1")
108 end
109
110 tline = ((multiLine_str.length > 0)?multiLine_str:line).strip
111 if(tline =~ /^=begin/)
112 comment_block = true
113 end
114 if(in_here_doc)
115 in_here_doc = false if tline =~ %r{\s*#{here_doc_term}\s*}
116 else # not in here_doc
117 if tline =~ %r{=\s*<<}
118 here_doc_term = tline.sub(%r{.*=\s*<<-?\s*([_|\w]+).*},"\\1")
119 in_here_doc = here_doc_term.size > 0
120 end
121 end
122 end
123 end
124 if(comment_block || program_end || in_here_doc)
125 # add the line unchanged
126 output << line
127 else
128 comment_line = (tline =~ /^#/)
129 if(!comment_line)
130 # throw out sequences that will
131 # only sow confusion
132 while tline.gsub!(/\{[^\{]*?\}/,"")
133 end
134 while tline.gsub!(/\[[^\[]*?\]/,"")
135 end
136 while tline.gsub!(/'.*?'/,"")
137 end
138 while tline.gsub!(/".*?"/,"")
139 end
140 while tline.gsub!(/\`.*?\`/,"")
141 end
142 while tline.gsub!(/\([^\(]*?\)/,"")
143 end
144 while tline.gsub!(/\/.*?\//,"")
145 end
146 while tline.gsub!(/%r(.).*?\1/,"")
147 end
148 # delete end-of-line comments
149 tline.sub!(/#[^\"]+$/,"")
150 # convert quotes
151 tline.gsub!(/\\\"/,"'")
152 OutdentExp.each do |re|
153 if(tline =~ re)
154 tab -= 1
155 break
156 end
157 end
158 end
159 if (multiLine_array.length > 0)
160 multiLine_array.each do |ml|
161 output << rb_add_line(ml,tab)
162 end
163 multiLine_array.clear
164 multiLine_str = ""
165 else
166 output << rb_add_line(line,tab)
167 end
168 if(!comment_line)
169 IndentExp.each do |re|
170 if(tline =~ re && !(tline =~ /\s+end\s*$/))
171 tab += 1
172 break
173 end
174 end
175 end
176 end
177 if(tline =~ /^=end/)
178 comment_block = false
179 end
180 end
181 error = (tab != 0)
182 STDERR.puts "Error: indent/outdent mismatch: #{tab}." if error
183 return output.join("\n") + "\n",error
184 end # beautify_string
185
186 def RBeautify.beautify_file(path)
187 error = false
188 if(path == '-') # stdin source
189 source = STDIN.read
190 dest,error = beautify_string(source,"stdin")
191 print dest
192 else # named file source
193 source = File.read(path)
194 dest,error = beautify_string(source,path)
195 if(source != dest)
196 # make a backup copy
197 File.open(path + "~","w") { |f| f.write(source) }
198 # overwrite the original
199 File.open(path,"w") { |f| f.write(dest) }
200 end
201 end
202 return error
203 end # beautify_file
204
205 def RBeautify.main
206 error = false
207 if(!ARGV[0])
208 STDERR.puts "usage: Ruby filenames or \"-\" for stdin."
209 exit 0
210 end
211 ARGV.each do |path|
212 error = (beautify_file(path))?true:error
213 end
214 error = (error)?1:0
215 exit error
216 end # main
217 end # module RBeautify
218
219 # if launched as a standalone program, not loaded as a module
220 if __FILE__ == $0
221 RBeautify.main
70 end 222 end
71
72 def addLine(line,tab)
73 line.strip!
74 line = makeTab(tab)+line if line.length > 0
75 return line + "\n"
76 end
77
78 def beautifyRuby(path)
79 commentBlock = false
80 programEnd = false
81 multiLineArray = Array.new
82 multiLineStr = ""
83 tab = 0
84 source = File.read(path)
85 dest = ""
86 source.split("\n").each do |line|
87 if(!programEnd)
88 # detect program end mark
89 if(line =~ /^__END__$/)
90 programEnd = true
91 else
92 # combine continuing lines
93 if(!(line =~ /^\s*#/) && line =~ /[^\\]\\\s*$/)
94 multiLineArray.push line
95 multiLineStr += line.sub(/^(.*)\\\s*$/,"\\1")
96 next
97 end
98
99 # add final line
100 if(multiLineStr.length > 0)
101 multiLineArray.push line
102 multiLineStr += line.sub(/^(.*)\\\s*$/,"\\1")
103 end
104
105 tline = ((multiLineStr.length > 0)?multiLineStr:line).strip
106 if(tline =~ /^=begin/)
107 commentBlock = true
108 end
109 end
110 end
111 if(commentBlock || programEnd)
112 # add the line unchanged
113 dest += line + "\n"
114 else
115 commentLine = (tline =~ /^#/)
116 if(!commentLine)
117 # throw out sequences that will
118 # only sow confusion
119 while tline.gsub!(/\{[^\{]*?\}/,"")
120 end
121 while tline.gsub!(/\[[^\[]*?\]/,"")
122 end
123 while tline.gsub!(/'.*?'/,"")
124 end
125 while tline.gsub!(/".*?"/,"")
126 end
127 while tline.gsub!(/\`.*?\`/,"")
128 end
129 while tline.gsub!(/\([^\(]*?\)/,"")
130 end
131 while tline.gsub!(/\/.*?\//,"")
132 end
133 while tline.gsub!(/%r(.).*?\1/,"")
134 end
135 # delete end-of-line comments
136 tline.sub!(/#[^\"]+$/,"")
137 # convert quotes
138 tline.gsub!(/\\\"/,"'")
139 $outdentExp.each do |re|
140 if(tline =~ re)
141 tab -= 1
142 break
143 end
144 end
145 end
146 if (multiLineArray.length > 0)
147 multiLineArray.each do |ml|
148 dest += addLine(ml,tab)
149 end
150 multiLineArray.clear
151 multiLineStr = ""
152 else
153 dest += addLine(line,tab)
154 end
155 if(!commentLine)
156 $indentExp.each do |re|
157 if(tline =~ re && !(tline =~ /\s+end\s*$/))
158 tab += 1
159 break
160 end
161 end
162 end
163 end
164 if(tline =~ /^=end/)
165 commentBlock = false
166 end
167 end
168 if(source != dest)
169 # make a backup copy
170 File.open(path + "~","w") { |f| f.write(source) }
171 # overwrite the original
172 File.open(path,"w") { |f| f.write(dest) }
173 end
174 if(tab != 0)
175 STDERR.puts "#{path}: Indentation error: #{tab}"
176 end
177 end
178
179 if(!ARGV[0])
180 STDERR.puts "usage: Ruby filenames to beautify."
181 exit 0
182 end
183
184 ARGV.each do |path|
185 beautifyRuby(path)
186 end