ruby-beautify 0.9.0

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/.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