ruby-beautify 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ *.orig
2
+ *.pyc
data/README.md ADDED
@@ -0,0 +1,5 @@
1
+ About
2
+ =====
3
+ This is a CLI bin to help print pretty ruby text to console.
4
+
5
+ This is a modifitcation of the sublime-text2 plugin provided by https://github.com/CraigWilliams/BeautifyRuby/blob/master/lib/rbeautify.rb
data/bin/rbeautify ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/ruby
2
+ require 'rbeautify'
3
+ require 'app'
4
+ require 'cli'
5
+ require 'filemagic'
6
+
7
+ include ErnieBrodeur
8
+
9
+ App.version = "0.9.0"
10
+ App.banner = "Usage: print ruby into a pretty format, or break trying."
11
+
12
+ Options.parse!
13
+
14
+ if ARGV.empty?
15
+ begin
16
+ puts RBeautify.beautify_string :ruby, STDIN
17
+ rescue Exception => e
18
+ puts e.message
19
+ exit
20
+ end
21
+ else
22
+ ARGV.each do |f|
23
+ if File.exist? f
24
+ puts RBeautify.beautify_string :ruby, open(f).read
25
+ else
26
+ puts "No such file: #{f}"
27
+ end
28
+ end
29
+ end
data/lib/app.rb ADDED
@@ -0,0 +1,79 @@
1
+ $:.push '/home/ebrodeur/Projects/bin_snippets/lib'
2
+
3
+ # Some requires, they don't fit elsewhere.
4
+ require 'yajl'
5
+ require 'sys/proctable'
6
+ module ErnieBrodeur
7
+
8
+ class Application
9
+ attr_accessor :version
10
+ attr_accessor :banner
11
+ attr_accessor :long_description
12
+ attr_accessor :plugins
13
+
14
+ # return the name of the app, for now this is just the cmd ran, later it will be
15
+ # something generated but more unique.
16
+ def name
17
+ $0.split("/").last
18
+ end
19
+
20
+ def cache_dir
21
+ "#{Dir.home}/.cache/erniebrodeur/#{App.name}/"
22
+ end
23
+
24
+ def config_dir
25
+ "#{Dir.home}/.config/erniebrodeur/#{App.name}/"
26
+ end
27
+
28
+ def pids
29
+ a = Sys::ProcTable.ps.select{|x| x.cmdline =~ /.*#{App.name}.*-[dD].*/}.map {|x| x.pid}
30
+ a.delete $$
31
+ return a if a.any?
32
+ nil
33
+ end
34
+
35
+ def initialize
36
+ @version = '0.0.0'
37
+ @banner = 'A bin snippet by Ernie Brodeur that does . . . something.'
38
+ @long_description = ''
39
+ @plugins = []
40
+ end
41
+
42
+ def daemonize(*params, &block)
43
+ if params[0] && !params[0][:multiple_pids] && pids
44
+ puts_or_log :info, "#{App.name} appears to be running (#{pids}), only one allowed, exiting."
45
+ exit
46
+ end
47
+ puts_or_log :info, "Forking to background."
48
+
49
+ Process.daemon
50
+ block.call
51
+ end
52
+
53
+ def kill_daemon
54
+ if !pids
55
+ puts_or_log :fatal, "No pids found, exiting."
56
+ end
57
+
58
+ pids.each do |p|
59
+ puts_or_log :info, "Killing #{p}"
60
+ %x[kill -TERM #{p}]
61
+ end
62
+ end
63
+ private
64
+ def puts_or_log(l, s)
65
+ if App.plugins.include? 'logging'
66
+ Log.send l, s
67
+ else
68
+ puts s
69
+ exit if l.to_sym == :fatal
70
+ end
71
+ end
72
+ end
73
+
74
+ App = Application.new
75
+
76
+ # This will load a helper, if it exists.
77
+ f = "#{$:.last}/helpers/#{App.name}.rb"
78
+ require f if File.exist? f
79
+ end
data/lib/beautifier.rb ADDED
@@ -0,0 +1,168 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Ruby beautifier, version 2.1, 09/11/2006
4
+ # Copyright (c) 2006, P. Lutus
5
+ # Released under the GPL
6
+
7
+ # Changes
8
+ # Craig Williams
9
+ # 12/26/2011
10
+ # Modified (very minor) to work with a Sublime Text 2 plugin
11
+
12
+ # indent regexp tests
13
+
14
+ @indentExp = [
15
+ /^module\b/,
16
+ /^if\b/,
17
+ /^\@{0,2}[\w\.]*[\s\t]*\=[\s\t]*if\b/,
18
+ /(=\s*|^)until\b/,
19
+ /(=\s*|^)for\b/,
20
+ /^unless\b/,
21
+ /^\@{0,2}[\w\.]*[\s\t]*\=[\s\t]*unless\b/,
22
+ /(=\s*|^)while\b/,
23
+ /(=\s*|^)begin\b/,
24
+ /(^| )case\b/,
25
+ /\bthen\b/,
26
+ /^class\b/,
27
+ /^rescue\b/,
28
+ /^def\b/,
29
+ /\bdo\b/,
30
+ /^else\b/,
31
+ /^elsif\b/,
32
+ /^ensure\b/,
33
+ /\bwhen\b/,
34
+ /\{[^\}]*$/,
35
+ /\[[^\]]*$/,
36
+ /\([^\)]*$/
37
+ ]
38
+
39
+ # outdent regexp tests
40
+
41
+ @outdentExp = [
42
+ /^rescue\b/,
43
+ /^ensure\b/,
44
+ /^elsif\b/,
45
+ /^end\b/,
46
+ /^else\b/,
47
+ /\bwhen\b/,
48
+ /^[^\{]*\}/,
49
+ /^[^\[]*\]/,
50
+ /^[^\(]*\)/
51
+ ]
52
+
53
+ def makeTab(tab)
54
+ (tab < 0) ? "" : @tabStr * @tabSize * tab
55
+ end
56
+
57
+ def addLine(line,tab)
58
+ line.strip!
59
+ line = makeTab(tab)+line if line.length > 0
60
+ line + "\n"
61
+ end
62
+
63
+ def beautifyRuby(contents)
64
+ commentBlock = false
65
+ programEnd = false
66
+ multiLineArray = Array.new
67
+ multiLineStr = ""
68
+ tab = 0
69
+ source = contents
70
+ dest = ""
71
+ source.split("\n").each do |line|
72
+ if(!programEnd)
73
+ # detect program end mark
74
+ if(line =~ /^__END__$/)
75
+ programEnd = true
76
+ else
77
+ # combine continuing lines
78
+ if(!(line =~ /^\s*#/) && line =~ /[^\\]\\\s*$/)
79
+ multiLineArray.push line
80
+ multiLineStr += line.sub(/^(.*)\\\s*$/,"\\1")
81
+ next
82
+ end
83
+
84
+ # add final line
85
+ if(multiLineStr.length > 0)
86
+ multiLineArray.push line
87
+ multiLineStr += line.sub(/^(.*)\\\s*$/,"\\1")
88
+ end
89
+
90
+ tline = ((multiLineStr.length > 0)?multiLineStr:line).strip
91
+ if(tline =~ /^=begin/)
92
+ commentBlock = true
93
+ end
94
+ end
95
+ end
96
+ if(commentBlock || programEnd)
97
+ # add the line unchanged
98
+ dest += line + "\n"
99
+ else
100
+ commentLine = (tline =~ /^#/)
101
+ if(!commentLine)
102
+ # throw out sequences that will
103
+ # only sow confusion
104
+ while tline.gsub!(/'.*?'/,"")
105
+ end
106
+ while tline.gsub!(/".*?"/,"")
107
+ end
108
+ while tline.gsub!(/\`.*?\`/,"")
109
+ end
110
+ while tline.gsub!(/\{[^\{]*?\}/,"")
111
+ end
112
+ while tline.gsub!(/\([^\(]*?\)/,"")
113
+ end
114
+ while tline.gsub!(/\/.*?\//,"")
115
+ end
116
+ while tline.gsub!(/%r(.).*?\1/,"")
117
+ end
118
+ tline.gsub!(/\\\"/,"'")
119
+ @outdentExp.each do |re|
120
+ if(tline =~ re)
121
+ tab -= 1
122
+ break
123
+ end
124
+ end
125
+ end
126
+ if (multiLineArray.length > 0)
127
+ multiLineArray.each do |ml|
128
+ dest += addLine(ml,tab)
129
+ end
130
+ multiLineArray.clear
131
+ multiLineStr = ""
132
+ else
133
+ dest += addLine(line,tab)
134
+ end
135
+ if(!commentLine)
136
+ @indentExp.each do |re|
137
+ if(tline =~ re && !(tline =~ /\s+end\s*$/))
138
+ tab += 1
139
+ break
140
+ end
141
+ end
142
+ end
143
+ end
144
+ if(tline =~ /^=end/)
145
+ commentBlock = false
146
+ end
147
+ end
148
+ STDOUT.write(dest)
149
+ # uncomment this to complain about mismatched blocks
150
+ # if(tab != 0)
151
+ # STDERR.puts "#{path}: Indentation error: #{tab}"
152
+ # end
153
+ end
154
+
155
+ tab_or_space = ARGV.first
156
+ path = ARGV.last
157
+ path.gsub!("\\", "/") if RUBY_PLATFORM =~ /mswin/
158
+ contents = IO.read(path)
159
+
160
+ if tab_or_space == 'space'
161
+ @tabSize = 2
162
+ @tabStr = " "
163
+ else
164
+ @tabSize = 1
165
+ @tabStr = "\t"
166
+ end
167
+
168
+ beautifyRuby(contents)
data/lib/cli.rb ADDED
@@ -0,0 +1,81 @@
1
+ # This library is to reduce the amount of effort I need to build a binary with option parsing
2
+ # and sensable defaults. It is not intended to be convient for anybody but me, their
3
+ # are a host of good @options out there if you want cli tools.
4
+ require 'optparse'
5
+
6
+ module ErnieBrodeur
7
+ class OptBlob
8
+ def initialize
9
+ @options = {}
10
+
11
+ @parser = OptionParser.new do |opts|
12
+ opts.banner = ErnieBrodeur::App.banner
13
+
14
+ opts.on("-V", "--version", "Print version") { |version| @options[:version] = true}
15
+ opts.on("-p", "--pry", "open a pry shell.") { |pry| @options[:pry] = true}
16
+ if App.plugins.include? 'logging'
17
+ opts.on("-l", "--log-level LEVEL", "Change the log level, default is debug.") { |level| ErnieBrodeur::Log.level level }
18
+ opts.on("--log-file FILE", "What file to output to, default is STDOUT") { |file| ErnieBrodeur::Log.filename file }
19
+ end
20
+ end
21
+ end
22
+
23
+ #TODO figure out a more dynamic way to include the parser and hash table.
24
+ def []=(key, value)
25
+ @options[key] = value
26
+ end
27
+
28
+ def [](key)
29
+ @options[key]
30
+ end
31
+
32
+ # This will build an on/off option with a default value set to false.
33
+ def bool_on(word, description = "")
34
+ Options[word.to_sym] = false
35
+ @parser.on "-#{word.chars.first}", "--[no]#{word}", description do |o|
36
+ Options[word.to_sym] == o
37
+ end
38
+ end
39
+
40
+ # This is the parser value on lifted up.
41
+ def on(*opts, &block)
42
+ @parser.on(*opts, &block)
43
+ end
44
+
45
+ def on_tail(*opts, &block)
46
+ @parser.on(*opts, &block)
47
+ end
48
+
49
+ def on_head(*opts, &block)
50
+ @parser.on(*opts, &block)
51
+ end
52
+
53
+ def parse!
54
+ @parser.banner = ErnieBrodeur::App.banner
55
+ @parser.parse!
56
+
57
+ if @options[:version]
58
+ puts ErnieBrodeur::App.version
59
+ exit 0
60
+ end
61
+
62
+ # we need to mash in our config array. To do this we want to make config
63
+ # options that don't overwrite cli options.
64
+ if App.plugins.include? 'config'
65
+ Config.each do |k,v|
66
+ @options[k] = v if !@options[k]
67
+ end
68
+ end
69
+ end
70
+
71
+ def on_pry
72
+ if @options[:pry]
73
+ require 'pry'
74
+ binding.pry
75
+ end
76
+ end
77
+ end
78
+
79
+ App.plugins.push "cli"
80
+ Options = OptBlob.new
81
+ end
data/lib/filemagic.rb ADDED
@@ -0,0 +1,13 @@
1
+ module ErnieBrodeur
2
+ # Add some basic filemagic types.
3
+ class FileMagic
4
+ def self.mime_type(file)
5
+ if File.exist? file
6
+ %x[file -bk --mime-type '#{file}'].chomp!
7
+ else
8
+ raise 'nosuchfile'
9
+ end
10
+ end
11
+ end
12
+ App.plugins.push 'filemagic'
13
+ end
data/lib/rbeautify.rb ADDED
@@ -0,0 +1,27 @@
1
+ require 'rbeautify/block_start'
2
+ require 'rbeautify/block_end'
3
+ require 'rbeautify/block_matcher'
4
+ require 'rbeautify/language'
5
+ require 'rbeautify/line'
6
+
7
+ require 'rbeautify/config/ruby'
8
+
9
+ module RBeautify
10
+
11
+ def self.beautify_string(language, source, use_tabs=false)
12
+ dest = ""
13
+ block = nil
14
+
15
+ unless language.is_a? RBeautify::Language
16
+ language = RBeautify::Language.language(language)
17
+ end
18
+
19
+ source.lines.each_with_index do |line_content, line_number|
20
+ line = RBeautify::Line.new(language, line_content, line_number, block, use_tabs)
21
+ dest += line.format + "\n"
22
+ block = line.block
23
+ end
24
+
25
+ return dest
26
+ end
27
+ end # module RBeautify
@@ -0,0 +1,23 @@
1
+ module RBeautify
2
+
3
+ class BlockEnd
4
+
5
+ attr_accessor :block_start, :offset, :match, :after_match
6
+
7
+ def initialize(block_start, offset, match, after_match)
8
+ self.block_start = block_start
9
+ self.offset = offset
10
+ self.match = match
11
+ self.after_match = after_match
12
+ end
13
+
14
+ def end_offset
15
+ offset + match.length
16
+ end
17
+
18
+ def end_can_also_be_start?
19
+ block_start.block_matcher.end_can_also_be_start?
20
+ end
21
+ end
22
+
23
+ end
@@ -0,0 +1,153 @@
1
+ module RBeautify
2
+
3
+ class BlockMatcher
4
+
5
+ attr_reader :language, :name, :starts, :ends, :options
6
+
7
+ def initialize(language, name, starts, ends, options = {})
8
+ @language = language
9
+ @name = name
10
+ @starts = starts
11
+ @ends = ends.nil? ? starts : ends
12
+ @options = options
13
+ end
14
+
15
+ class << self
16
+ def parse(language, original_block, line_number, string, current_offset)
17
+ block_end = original_block && original_block.parse_block_end(string, current_offset)
18
+
19
+ if (block_start = first_block_start(language,
20
+ original_block,
21
+ line_number,
22
+ string,
23
+ current_offset,
24
+ block_end.nil? ? nil : block_end.offset))
25
+
26
+ block_end = nil
27
+ end
28
+
29
+ if block_end
30
+ # Check whether the section of the line which is a block end is also a block start
31
+ if block_end.end_can_also_be_start? &&
32
+ (block_start_candidate = first_block_start(language, block_end.block_start.parent, line_number, string, current_offset)) &&
33
+ block_start_candidate.offset == block_end.offset
34
+ block_start = block_start_candidate
35
+ end
36
+
37
+ end
38
+
39
+ if block_start
40
+ if debug
41
+ puts "MATCH: '#{string.slice(0, string.length - block_start.match.length - block_start.after_match.length)}<START type=#{block_start.name}>#{block_start.match}</START>#{block_start.after_match}'"
42
+ end
43
+ parse(language, block_start, line_number, block_start.after_match, block_start.end_offset)
44
+ elsif block_end
45
+ if debug
46
+ puts "MATCH: '#{string.slice(0, string.length - block_end.match.length - block_end.after_match.length)}<END>#{block_end.match}</END>#{block_end.after_match}'"
47
+ end
48
+ parse(language, block_end.block_start.parent, line_number, block_end.after_match, block_end.end_offset)
49
+ else
50
+ original_block
51
+ end
52
+ end
53
+
54
+ def debug=(value)
55
+ @debug = value
56
+ end
57
+
58
+ def debug
59
+ @debug
60
+ end
61
+
62
+ private
63
+ def first_block_start(language, parent_block, line_number, string, offset, maximum_offset = nil)
64
+ first_block_start = nil
65
+ language.matchers.each do |matcher|
66
+ if matcher.can_nest?(parent_block)
67
+ if (block_start_candidate = matcher.parse_block_start(string, parent_block, offset, line_number)) &&
68
+ (maximum_offset.nil? || maximum_offset > block_start_candidate.offset)
69
+ first_block_start = block_start_candidate
70
+ maximum_offset = first_block_start.offset
71
+ end
72
+ end
73
+ end
74
+ first_block_start
75
+ end
76
+ end
77
+
78
+ def parse_block_start(string, parent_block, offset, line_number)
79
+ if !string.empty? && (match = starts.match(string))
80
+ RBeautify::BlockStart.new(self, parent_block, line_number, offset + match.begin(0), match[0], match.post_match)
81
+ end
82
+ end
83
+
84
+ def indent_end_line?(block)
85
+ evaluate_option_for_block(:indent_end_line, block)
86
+ end
87
+
88
+ def indent_size(block)
89
+ evaluate_option_for_block(:indent_size, block) || language.indent_size
90
+ end
91
+
92
+ # Look for blocks within the content of this one
93
+ def parse_content?
94
+ options[:parse_content] != false
95
+ end
96
+
97
+ # Indent the content of this block
98
+ def format_content?
99
+ options[:format_content] != false
100
+ end
101
+
102
+ def can_nest?(parent_block)
103
+ return false unless parent_block.nil? || parent_block.parse_content?
104
+
105
+ if options[:nest_only]
106
+ parent_block && options[:nest_only].include?(parent_block.name)
107
+ else
108
+ parent_block.nil? ||
109
+ options[:nest_except].nil? || !options[:nest_except].include?(parent_block.name)
110
+ end
111
+ end
112
+
113
+ def ends?
114
+ ends != false
115
+ end
116
+
117
+ def end_is_implicit?
118
+ options[:end] == :implicit
119
+ end
120
+
121
+ def end_can_also_be_start?
122
+ if ends == starts
123
+ options[:end_can_also_be_start] == true
124
+ else
125
+ options[:end_can_also_be_start] != false
126
+ end
127
+ end
128
+
129
+ def negate_ends_match?
130
+ options[:negate_ends_match]
131
+ end
132
+
133
+ # True if blocks can contain the escape character \ which needs to be
134
+ # checked for on end match
135
+ def escape_character?
136
+ options[:escape_character] == true
137
+ end
138
+
139
+ def inspect
140
+ name
141
+ end
142
+
143
+ private
144
+ def evaluate_option_for_block(key, block)
145
+ if options[key] && options[key].respond_to?(:call)
146
+ options[key].call(block)
147
+ else
148
+ options[key]
149
+ end
150
+ end
151
+
152
+ end
153
+ end