Module: RubyBeautify

Extended by:
RubyBeautify
Included in:
RubyBeautify
Defined in:
lib/ruby-beautify.rb,
lib/ruby-beautify/version.rb

Constant Summary collapse

OPEN_BLOCK_START =
["module", "class", "begin", "def", 'if', 'while', 'unless', 'case']
BOTH_BLOCK =
["else", "elsif", 'rescue', 'when']
OPEN_BLOCK_DO =
['do', '{']
CLOSE_BLOCK =
['end', '}']
OPEN_BRACKETS =
[:on_lparen, :on_lbracket, :on_lbrace, :on_embexpr_beg, :on_tlambeg]
CLOSE_BRACKETS =
[:on_rparen, :on_rbracket, :on_rbrace, :on_embexpr_end]
NEW_LINES =
[:on_nl, :on_ignored_nl, :on_comment, :on_embdoc_end]
VERSION =
'0.98.1'

Instance Method Summary collapse

Instance Method Details

#both_block?(line_lex) ⇒ Boolean

is the first word one of our ‘both’ keywords?

Returns:

  • (Boolean)


109
110
111
112
113
114
115
116
# File 'lib/ruby-beautify.rb', line 109

def both_block?(line_lex)
	line_lex.each do |x|
		# search for a first non-space token
		if not x[1] == :on_sp
			return x[1] == :on_kw && BOTH_BLOCK.include?(x[2])
		end
	end
end

#closing_assignment?(line_lex) ⇒ Boolean

Returns:

  • (Boolean)


80
81
82
83
84
85
# File 'lib/ruby-beautify.rb', line 80

def closing_assignment?(line_lex)
	opens = opening_assignment_count line_lex
	closes = closing_assignment_count line_lex
	return false if opens == closes
	return true if closes > opens
end

#closing_block?(line_lex) ⇒ Boolean

kinda complex, we count open/close to determine if we ultimately have close a hanging line. Always true if it’s a both_block.

Returns:

  • (Boolean)


130
131
132
133
134
135
136
137
# File 'lib/ruby-beautify.rb', line 130

def closing_block?(line_lex)
	return true if both_block? line_lex
	opens = starts_block?(line_lex) ? 1 : 0
	opens += opening_block_count line_lex
	closes = closing_block_count line_lex
	return false if opens == closes
	return true if opens < closes
end

#contains_block_assignment?(line_lex) ⇒ Boolean

test for assignment from a block

Returns:

  • (Boolean)


88
89
90
91
92
93
94
95
# File 'lib/ruby-beautify.rb', line 88

def contains_block_assignment?(line_lex)
	compacted_line = line_lex.reject{|x| x[1] == :on_sp} #remove spaces
	idx = compacted_line.rindex{|x| ['=', '||='].include? x[2]} #find last equal
	if idx
		return OPEN_BLOCK_START.include?(compacted_line[idx+1][2]) #check for if/begin block
	end
	return false
end

#opening_assignment?(line_lex) ⇒ Boolean

same trick as opening_block

Returns:

  • (Boolean)


72
73
74
75
76
77
# File 'lib/ruby-beautify.rb', line 72

def opening_assignment?(line_lex)
	opens = opening_assignment_count line_lex
	closes = closing_assignment_count line_lex
	return false if opens == closes
	return true if opens > closes
end

#opening_block?(line_lex) ⇒ Boolean

kinda complex, we count open/close to determine if we ultimately have a hanging line. Always true if it’s a both_block.

Returns:

  • (Boolean)


120
121
122
123
124
125
126
# File 'lib/ruby-beautify.rb', line 120

def opening_block?(line_lex)
	opens = (starts_block?(line_lex) || both_block?(line_lex)) ? 1 : 0
	opens += opening_block_count line_lex
	closes = closing_block_count line_lex
	return false if opens == closes
	return true if opens > closes
end

#pretty_string(content, indent_token: "\t", indent_count: 1) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/ruby-beautify.rb', line 17

def pretty_string(content, indent_token: "\t", indent_count: 1)
	output_string = ""
	raise "Bad Syntax" unless syntax_ok? content
	lex = ::Ripper.lex(content)

	indent_level = 0
	line_lex = []

	# walk through line tokens
	lex.each do |token|
		line_lex << token

		if token[1] == :on_heredoc_end
			output_string << line_lex.map {|l| l[2]}.join
			line_lex.clear

		elsif NEW_LINES.include? token[1] # if type of this token is a new line
			# did we just close something?  if so, lets bring it down a level.
			if closing_block?(line_lex) || closing_assignment?(line_lex)
				indent_level -= 1 if indent_level > 0
			end

			# print our line, in place.
			line_string = line_lex.map {|l| l[2]}.join
			output_string += indented_line(indent_level, indent_token, indent_count, line_string)

			# oh, we opened something did we?  lets indent for the next run.
			if opening_block?(line_lex) || opening_assignment?(line_lex)
				indent_level += 1
			end

			line_lex.clear
		end
	end

	return output_string
end

#starts_block?(line_lex) ⇒ Boolean

is the first word a key word?

Returns:

  • (Boolean)


98
99
100
101
102
103
104
105
106
# File 'lib/ruby-beautify.rb', line 98

def starts_block?(line_lex)
	return true if contains_block_assignment? line_lex
	line_lex.each do |x|
		# search for a first non-space token
		if not x[1] == :on_sp
			return x[1] == :on_kw && OPEN_BLOCK_START.include?(x[2])
		end
	end
end

#syntax_ok?(string) ⇒ Boolean

check the syntax of a string see www.ruby-forum.com/topic/4419079#1130079

Returns:

  • (Boolean)


57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/ruby-beautify.rb', line 57

def syntax_ok?(string)
	begin
		# eval will parse the code, raising a SyntaxError if something is
		# syntactically wrong, then start executing it.  first thing is the
		# throw, so it throws, skipping all the rest.
		catch(:good) do
			eval("BEGIN { throw :good }; #{string}")
		end
		return true
	rescue SyntaxError
		return false
	end
end