front-compiler 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG ADDED
@@ -0,0 +1,14 @@
1
+ * 1.0.6 (December 14, 2009) - Nikolay V. Nemshilov aka St.
2
+ * rubygem is now available
3
+ * console util was added
4
+
5
+ * 1.0.2 (April 25, 2009) - Nikolay V. Nemshilov aka St.
6
+ * Tokens negotiation process update
7
+ * The self-build script enhancement
8
+
9
+ * 1.0.0 (April 5, 2009) - Nikolay V. Nemshilov aka St.
10
+
11
+ * The Self-Build Feature was implemented
12
+ * Missed semicolons restoration feature added
13
+ * Documentation updates
14
+ * Tagged the source as version 1.0.0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Nikolay V. Nemshilov
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,174 @@
1
+ Welcome!
2
+ ========
3
+
4
+ FrontCompiler is a simple collection of compactors for the JavaScript,
5
+ CSS and HTML source code. It removes trailing whitespaces, comments and
6
+ transformates the local variables to make the sourcecode shorter.
7
+
8
+ For JavaScript, it can create a more compressed self-building script
9
+ for your code, see the description below.
10
+
11
+ The library can be used as a plugin for rails. See description below.
12
+
13
+
14
+ RubyGem and Console tool
15
+ ========================
16
+
17
+ FrontCompiler is now available as a rubygem at the gemcutter service
18
+
19
+ gem sources -a http://gemcutter.org
20
+ gem install front-compiler
21
+
22
+ With the rubygem you'll have a console tool called 'frontcc'
23
+
24
+ $ frontcc file0.js file1.js file2.js file3.js
25
+
26
+
27
+
28
+ Basic Usage
29
+ ===========
30
+
31
+ It's pretty simple
32
+
33
+ @c = FrontCompiler.new
34
+
35
+ @compact_js = @c.compact_js(File.open('src/something.js', 'r'));
36
+ @compact_css = @c.compact_css(File.open('src/something.css', 'r'));
37
+ @compact_html = @c.compact_html(File.open('src/something.css', 'r'));
38
+
39
+ or shorter
40
+
41
+ @compact_js = @c.compact_file('src/something.js');
42
+ @compact_css = @c.compact_file('src/something.css');
43
+ @compact_html = @c.compact_file('src/something.css');
44
+
45
+ or you can compact several files at once like that
46
+
47
+ @library_code = @c.compact_files(%w{
48
+ src/lib.js
49
+ src/lib/something.js
50
+ src/lib/another.js
51
+ })
52
+
53
+ Same for the other file-types
54
+
55
+ CSS Inlining
56
+ ============
57
+
58
+ With the tool you can convert your css source in some javascript
59
+ definition so you could put the styles in the same file as your
60
+ javascript and have -1 (or several) hits to your sever.
61
+
62
+ File('public/javascripts/all_in_one.js', 'w') do |file|
63
+ file.write @c.compact_files(%w{
64
+ public/javascripts/prototype.js
65
+ public/javascripts/effects.js
66
+ public/javascripts/application.js
67
+ })
68
+
69
+ file.write @c.inline_css(
70
+ File.open('public/stylesheets/application.css').read
71
+ )
72
+ end
73
+
74
+ Now you have a single javascript file which contains both, javascript
75
+ and the application stylesheets in one.
76
+
77
+ NOTE: if the user have JavaScript switched off, then he won't see the
78
+ styles.
79
+
80
+ Nested CSS Handling
81
+ ===================
82
+
83
+ Nested CSS is a feature when you describe your css with nested constructions
84
+ like that
85
+
86
+ div.article {
87
+ div.title {
88
+ font-weight: bold;
89
+ span.date {
90
+ color: pink;
91
+ }
92
+ }
93
+ div.text {
94
+ background: #EEE;
95
+ }
96
+ }
97
+
98
+ Which means the same as the following code.
99
+
100
+ div.article div.title {
101
+ font-weight: bold;
102
+ }
103
+ div.article div.title span.date {
104
+ color: pink
105
+ }
106
+ div.article div.text {
107
+ background: #EEE;
108
+ }
109
+
110
+ Nested styles are more clean, simple and follows the DRY principle. The only
111
+ little problem, there's no browsers which support the feature yet. But the idea
112
+ is alive and people like it. So we have added the feature emulation in the
113
+ project.
114
+
115
+ You can create nested css descriptions and then when you compress your css
116
+ with FrontCompiler, it will be automatically converted in a correct css source
117
+ which the browsers can understand.
118
+
119
+
120
+ Rails Usage
121
+ ===========
122
+
123
+ The project can be used as a usual rails plugin. Just clone the
124
+ project into your vendor/plugins/front_compiler directory and you will
125
+ have the following methods aviable both in your controllers and
126
+ templates
127
+
128
+
129
+ * compact_files(list) - compacts the files fromt the given list and
130
+ puts them in a single string. You can specify
131
+ a list of file-names here.
132
+
133
+ * compact_file(file) - compacts the given file (can be a file-name)
134
+
135
+ * compact_js(source) - returns compacted version of the given source
136
+ * compact_css(source)
137
+ * compact_html(source)
138
+
139
+ * inline_css(source) - converts the css-source in javascript
140
+ * inline_css_file(file) - converts the given css-file in a javascript
141
+ source (can be a file-name)
142
+
143
+
144
+ Self-Build Scripts
145
+ ==================
146
+
147
+ FrontCompiler provides you another nice feature, the scripts self-building.
148
+ The idea is that it will convert your code into a string, replace all long
149
+ tokens by short replacements and then compile a javascript code which will
150
+ replace all the tokens back on the user's browser side.
151
+
152
+ This will give you extra 20-40% compression over the existing FrontCompiler
153
+ compression.
154
+
155
+ The browser side restoration happens pretty quick and almost invisible for
156
+ the end user.
157
+
158
+ As the feature actually change the code and requires the end script to be
159
+ executed with JavaScript, it won't work if you use JSON as a media format
160
+ without actual evaluating it as a javascript code. For this reason, to use
161
+ the feature, you need to call it specifically.
162
+
163
+ @c = FrontCompiler.new
164
+ @c.compact_js(File.open('src/something.js', 'r')).create_self_build;
165
+
166
+ If you want FrontCompiler to create self-builds by default you can just
167
+ uncomment the call in the java_script.rb file.
168
+
169
+
170
+ Enjoy!
171
+
172
+ --
173
+ The code released under terms of the MIT License
174
+ Copyright (C) 2008-2009 Nikolay V. Nemshilov aka St.
data/Rakefile ADDED
@@ -0,0 +1,82 @@
1
+ require "rake"
2
+ require "rake/clean"
3
+ require "rake/gempackagetask"
4
+ require "rake/rdoctask"
5
+ require "rake/testtask"
6
+ require "spec/rake/spectask"
7
+ require "fileutils"
8
+
9
+ def __DIR__
10
+ File.dirname(__FILE__)
11
+ end
12
+
13
+ include FileUtils
14
+
15
+ NAME = "front_compiler"
16
+
17
+ require "lib/front_compiler"
18
+ require "lib/front_compiler_helper"
19
+
20
+ def sudo
21
+ ENV['FC_SUDO'] ||= "sudo"
22
+ sudo = windows? ? "" : ENV['FC_SUDO']
23
+ end
24
+
25
+ def windows?
26
+ (PLATFORM =~ /win32|cygwin/) rescue nil
27
+ end
28
+
29
+ def install_home
30
+ ENV['GEM_HOME'] ? "-i #{ENV['GEM_HOME']}" : ""
31
+ end
32
+
33
+ ##############################################################################
34
+ # Packaging & Installation
35
+ ##############################################################################
36
+ CLEAN.include ["**/.*.sw?", "pkg", "lib/*.bundle", "*.gem", "doc/rdoc", ".config", "coverage", "cache"]
37
+
38
+ desc "Run the specs."
39
+ task :default => :specs
40
+
41
+ task :frontcompiler => [:clean, :rdoc, :package]
42
+
43
+ spec = Gem::Specification.new do |s|
44
+ s.name = NAME
45
+ s.version = FrontCompiler::VERSION
46
+ s.platform = Gem::Platform::RUBY
47
+ s.author = "Nikolay V. Nemshilov"
48
+ s.email = "nemshilov@gmail.com"
49
+ s.homepage = "http://st-on-it.blogspot.com"
50
+ s.summary = "FrontCompiler is a simple collection of compactors for the JavaScript,
51
+ CSS and HTML source code. It removes trailing whitespaces, comments and
52
+ transformates the local variables to make the sourcecode shorter."
53
+ s.bindir = "bin"
54
+ s.description = s.summary
55
+ s.executables = %w( )
56
+ s.require_path = "lib"
57
+ s.files = %w( README Rakefile init.rb install.rb uninstall.rb ) + Dir["{docs,bin,spec,lib,examples,script}/**/*"]
58
+
59
+ # rdoc
60
+ s.has_rdoc = true
61
+ s.extra_rdoc_files = %w( README )
62
+ #s.rdoc_options += RDOC_OPTS + ["--exclude", "^(app|uploads)"]
63
+
64
+ # Dependencies
65
+ # s.add_dependency "something"
66
+ # Requirements
67
+ s.required_ruby_version = ">= 1.8.4"
68
+ end
69
+
70
+ Rake::GemPackageTask.new(spec) do |package|
71
+ package.gem_spec = spec
72
+ end
73
+
74
+ desc "Run :package and install the resulting .gem"
75
+ task :install => :package do
76
+ sh %{#{sudo} gem install #{install_home} --local pkg/#{NAME}-#{FrontCompiler::VERSION}.gem --no-rdoc --no-ri}
77
+ end
78
+
79
+ desc "Run :clean and uninstall the .gem"
80
+ task :uninstall => :clean do
81
+ sh %{#{sudo} gem uninstall #{NAME}}
82
+ end
data/bin/frontcc ADDED
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__),'..','lib')))
3
+
4
+ require 'front_compiler'
5
+
6
+ if ARGV.empty? || ARGV.include?('-h') || ARGV.include?('--help')
7
+ puts %Q{FrontCompiler the Ruby based JavaScript/CSS/HTML compiler
8
+ (C) 2008-2009 Nikolay Nemshilov
9
+
10
+
11
+ frontcc [options] file file file ...
12
+
13
+ options:
14
+ -h Show this help
15
+ -p Create an albeit packed script
16
+
17
+
18
+ The command supports any standard console */* selectors
19
+ and will automatically recognize file-types by extensions
20
+ }
21
+ else
22
+ cc = FrontCompiler.new
23
+
24
+ javascript = false
25
+
26
+ # creating an overall source
27
+ source = ARGV.collect{ |path| Dir[path] }.flatten.collect do |path|
28
+ if File.exists? path
29
+ src = File.open(path, 'r').read
30
+
31
+ case path.split('.').last.downcase
32
+ when "html"
33
+ throw "We don't inline HTML into JavaScript" if javascript
34
+ cc.compact_html(src)
35
+ when "css"
36
+ cc.send(javascript ? :inline_css : :compact_css, src)
37
+ when "js"
38
+ javascript = true
39
+ src =~ /;\s*\Z/ ? src : (src + ';') # <- checking the end semicolon
40
+
41
+ else
42
+ throw "Unsupported kind of file '#{path}'"
43
+ end
44
+ end
45
+ end.compact.join("")
46
+
47
+ if javascript
48
+ source = cc.compact_js(source)
49
+ source = source.create_self_build if ARGV.include?('-p')
50
+ end
51
+
52
+ puts source
53
+ end
data/init.rb ADDED
@@ -0,0 +1,25 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'lib', 'front_compiler'))
2
+
3
+ if defined? ActionController
4
+ ActionController::Base.class_eval {
5
+ include FrontCompilerHelper
6
+ helper FrontCompilerHelper
7
+ }
8
+ end
9
+
10
+ # Rails 2.2
11
+ if defined? ActionView::Helpers::AssetTagHelper::AssetCollection
12
+ ActionView::Helpers::AssetTagHelper::JavaScriptSources.class_eval do
13
+ alias :original_joined_contents :joined_contents
14
+ def joined_contents
15
+ FrontCompiler.new.compact_js(original_joined_contents)
16
+ end
17
+ end
18
+ ActionView::Helpers::AssetTagHelper::StylesheetSources.class_eval do
19
+ alias :original_joined_contents :joined_contents
20
+ def joined_contents
21
+ FrontCompiler.new.compact_css(original_joined_contents)
22
+ end
23
+ end
24
+ end
25
+
@@ -0,0 +1,5 @@
1
+ #
2
+ # Hook for rails when the plugin is used as a gem
3
+ #
4
+ require 'front_compiler'
5
+ require File.dirname(__FILE__) + '/../init.rb'
@@ -0,0 +1,72 @@
1
+ #
2
+ # This module contains the nested css handling
3
+ # it converts virtual nested css constructions to standard css constructions
4
+ #
5
+ # Copyright (C) Nikolay V. Nemshilov aka St.
6
+ #
7
+ class FrontCompiler
8
+ class FrontCompiler::CssSource < FrontCompiler::SourceCode
9
+ module NestedStyles
10
+ # overloads the constructor, to convert the styles on fly
11
+ def initialize(src, keep_as_is=false)
12
+ super src
13
+ convert_nested_styles! unless keep_as_is
14
+ end
15
+
16
+ # converts the nested styles constructions in the source
17
+ CSS_CONSTRUCTION_RE = /((\A|\}|;)\s*?([^\}\{;]+?)\s*?)\{.*?\}/m
18
+ def convert_nested_styles!
19
+ # loop though the blocks
20
+ offset = 0
21
+ while pos = index(CSS_CONSTRUCTION_RE, offset)
22
+ pos += $1.size # <- getting the actual block position
23
+ block = find_block("{}", pos)
24
+ block = block[1, block.size-1]; pos+=1 # <- remove the container
25
+ block_size = block.size
26
+
27
+ parent_rules = clean_rules_from $3 # <- the block rules list
28
+
29
+ block_sub_styles = []
30
+
31
+ # looking for a nested construction
32
+ while block_pos = block.index(CSS_CONSTRUCTION_RE)
33
+ trail_char = $2.dup
34
+
35
+ block_start = $1.dup
36
+ block_start = block_start[trail_char.size, block_start.size]
37
+ block_start_size = block_start.size
38
+
39
+ block_pos += trail_char.size # <- updating the sub-block position
40
+
41
+ # update the sub-bolock rules
42
+ clean_rules_from($3).each do |block_rule|
43
+ block_start.gsub! block_rule, parent_rules.collect{ |p_rule|
44
+ "#{p_rule} #{block_rule}"
45
+ }.join(", ")
46
+ end
47
+
48
+ # getting the construction body
49
+ block_body = find_block("{}", block_pos + block_start_size, block)
50
+
51
+ # removing the construction out of the block
52
+ block[block_pos, block_start_size + block_body.size] = ''
53
+ block_sub_styles << block_start + block_body
54
+ end
55
+
56
+ # replacing the block
57
+ self[pos, block_size] = block + block_sub_styles.join('')
58
+
59
+ offset = pos + block.size - 1
60
+ end
61
+ end
62
+
63
+ protected
64
+ # creates a clean css-rules list out of the str
65
+ def clean_rules_from(str)
66
+ str.split(',').collect{ |rule|
67
+ rule.gsub(/\s+/, ' ').gsub(/\/\*.*?\*\//im, '').strip
68
+ }
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,42 @@
1
+ #
2
+ # The CSS sources compactor
3
+ #
4
+ # Copyright (C) Nikolay V. Nemshilov aka St.
5
+ #
6
+ require "front_compiler/css_source/nested_styles"
7
+
8
+ class FrontCompiler::CssSource < FrontCompiler::SourceCode
9
+ include NestedStyles
10
+
11
+ # removes all the comments out of the given source
12
+ def remove_comments!
13
+ string_safely do
14
+ gsub!(/\/\*.*?\*\//im, '')
15
+ end
16
+ end
17
+
18
+ # removes all the empty lines out of the source code
19
+ def remove_empty_lines!
20
+ string_safely do
21
+ gsub!(/\n\s*\n/m, "\n")
22
+ end
23
+ end
24
+
25
+ # removes tailing whitespaces out of the source code
26
+ def remove_trailing_spaces!
27
+ string_safely do
28
+ gsub!(/\s+/im, ' ')
29
+ gsub!(/\s*(\+|>|\||~|\{|\}|,|\)|\(|;|:|\*)\s*/im, '\1')
30
+ gsub!(/;\}/, '}')
31
+ strip!
32
+ end
33
+ end
34
+
35
+ # converts the source in such a way that it could be
36
+ # delivered with javascript in the same file
37
+ def to_javascript
38
+ "document.write(\"<style type=\\\"text/css\\\">#{
39
+ compact.gsub('"', '\"')
40
+ }</style>\");"
41
+ end
42
+ end
@@ -0,0 +1,24 @@
1
+ #
2
+ # The HTML sources compactor
3
+ #
4
+ # Copyright (C) Nikolay V. Nemshilov aka St.
5
+ #
6
+ class FrontCompiler::HTMLCompactor
7
+ # applies all the compactings to the given source
8
+ def minimize(source)
9
+ source = remove_comments(source)
10
+ source = remove_trailing_spaces(source)
11
+ end
12
+
13
+ # removes all the comments out of the code
14
+ def remove_comments(source)
15
+ source.gsub /<!--.*?-->/, ''
16
+ end
17
+
18
+ # remove all the trailing spaces out of the code
19
+ def remove_trailing_spaces(source)
20
+ source.gsub! /\s+/, ' '
21
+ source.gsub! />\s+/, '>'
22
+ source.gsub /\s+</, '<'
23
+ end
24
+ end
@@ -0,0 +1,135 @@
1
+ #
2
+ # This module contains the javascript logical
3
+ # structures processor/compactor
4
+ #
5
+ # This module is a part of the JavaScript class and taken out
6
+ # just to keep the things simple
7
+ #
8
+ # Copyright (C) Nikolay V. Nemshilov aka St.
9
+ #
10
+ class FrontCompiler
11
+ class JavaScript < FrontCompiler::SourceCode
12
+ module LogicCompactor
13
+ #
14
+ # checks and compacts the script-logic
15
+ #
16
+ def compact_logic!
17
+ string_safely do
18
+ join_multiline_defs!
19
+ fix_missed_semicolons!
20
+ simplify_constructions_of self
21
+ end
22
+ end
23
+
24
+ protected
25
+ #
26
+ # joins constructions which split on several lines
27
+ #
28
+ MULTILINING_CHARS_RE = %w{ ? : = - + * / % ! & | < > ,
29
+ }.collect{ |c| Regexp.escape(c)}.join("|")
30
+ def join_multiline_defs!
31
+ gsub!(/\s+(#{MULTILINING_CHARS_RE})\s+/m, ' \1 ')
32
+ gsub!(/\s+(#{MULTILINING_CHARS_RE})(\S)/m, ' \1\2')
33
+ gsub!(/(\S)(#{MULTILINING_CHARS_RE})\s+/m, '\1\2 ')
34
+
35
+ gsub!(/\s*(\.)\s*/m, '\1') # <- fold object member calls
36
+
37
+ gsub!(/(\()\s+/m, '\1') # <- fold method argument defs
38
+ gsub!(/\s+(\))/m, '\1')
39
+ end
40
+
41
+ #
42
+ # tries to simplify the short logical constructions
43
+ # which were defined as multilined but could be simplier
44
+ #
45
+ def simplify_constructions_of(src)
46
+ [/(if|for|while)\s*\(/im, /(else|do)\s*\s\{/im].each do |regexp|
47
+ offset = 0
48
+ while pos = src.index(regexp, offset)
49
+ block = name = $1.dup
50
+ block += find_block("()", pos + block.size, src)
51
+ body = find_block("{}", pos + block.size, src)
52
+
53
+ unless body == ''
54
+ block += body[/\A\s*/m]; body.strip! # removing starting empty-chars
55
+ body_code = body[1, body.size-2]
56
+
57
+ # checking if the code can be simplified
58
+ can_be_simplified = number_of_code_lines_in(body_code) == 1
59
+
60
+ # check additional 'if' constructions restrictions
61
+ if can_be_simplified and name == 'if'
62
+ # double ifs construction check
63
+ can_be_simplified &= !body_code.match(/\A\s*if\s*\(/im)
64
+
65
+ # checking the else blocks missintersections
66
+ if src[pos+block.size+body.size, 40].match(/\A\s*else(\s+|\{)/)
67
+ can_be_simplified &= !body_code.match(/(\A|[^a-z\d_$])if\s*\(/)
68
+ end
69
+ end
70
+
71
+ # try to simplify internal constructions
72
+ simplify_constructions_of body_code
73
+
74
+ if can_be_simplified
75
+ check_semicolons_in body_code
76
+ else
77
+ body_code = "{#{body_code}}"
78
+ end
79
+
80
+ src[pos+block.size, body.size] = body_code
81
+ body = body_code
82
+ end
83
+
84
+ offset = pos + block.size + body.size
85
+ end
86
+ end
87
+ end
88
+
89
+ # calculates the number of code-lines in the string
90
+ def number_of_code_lines_in(src)
91
+ src = src.dup
92
+
93
+ # replacing all the method calls, blocks and lists with dummies
94
+ ['[]', '()', '{}'].each do |pair|
95
+ offset = 0
96
+ while pos = src.index(pair[0,1], offset)
97
+ offset = pos + 1
98
+ block = find_block(pair, 0, src[pos, src.size])
99
+
100
+ src[pos, block.size] = pair
101
+ end
102
+ end
103
+
104
+ # putting semicolons after try/catch/finally constructions, so they were conuted as well
105
+ src.gsub!(/(catch\s*\(\)|finally)\s*\{\}/, '\&;')
106
+ src.gsub!(/\(\)\s*\{\}/, '\&;')
107
+
108
+ # calculating the number of the lines
109
+ src.split(';').collect{ |line|
110
+ line.strip != '' ? 1 : nil
111
+ }.compact.size
112
+ end
113
+ end
114
+
115
+ # checks if there's ommited semicolons in the code
116
+ def check_semicolons_in(src)
117
+ src[/\s*\Z/m] = ";#{src[/\s*\Z/m]}" unless src.strip[-1,1].match(/[;\}]/)
118
+
119
+ # removing bug causing semicolons after a function
120
+ src.gsub!(/(\A\s*function\s*.*?\(.*?\)\s*\{.*?\});(\s*\Z)/im) do
121
+ $1 + $2
122
+ end
123
+ end
124
+
125
+ def fix_missed_semicolons!
126
+ gsub! /([^{}()|\[&;:=,\s])([ \t]*?\n\s*?(return|if|function|while|try|do)[^a-zA-Z_$])/, '\1;\2'
127
+
128
+ # (function(){....})(..) if(...)
129
+ gsub! /(\}\)\([^)]*\))([ \t]*?\n\s*?(return|if|function|while|try|do)[^a-zA-Z_$])/, '\1;\2'
130
+
131
+ # fixing wrong added semicolons before the if calls
132
+ gsub! /([^a-zA-Z_$](else|do));(\s+(if|while|do|try)[^a-zA-Z_$])/, '\1\3'
133
+ end
134
+ end
135
+ end