Last active
March 29, 2023 02:05
-
-
Save westonganger/e84297d0f5a892fba3e46510bdc73fa7 to your computer and use it in GitHub Desktop.
Naive ERB to Slim Converter (because slimrb does a really terrible job converting)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
### USAGE: `./convert_slim_to_erb path/to/views/` | |
### LIMITATIONS: | |
### - Does not add closing tags such as `<% end %>` or `</div>` | |
SELF_CLOSING_TAGS = ["input","br","hr","img","meta","area","base","col","embed","link","source","track","wbr","param"].freeze | |
@line = nil | |
@indent = nil | |
@next_line = nil | |
@next_indent = nil | |
@ruby_block_indent = nil | |
Object.class_eval do | |
def present? | |
self && !self.strip.empty? | |
end | |
def blank? | |
!present? | |
end | |
def presence | |
self if present? | |
end | |
end | |
def get_indent(str) | |
str[/^\ */] | |
end | |
def prepend_attr(attr, value) | |
return if value.to_s.blank? | |
if value.is_a?(Array) | |
value = value.join(" ") | |
end | |
if !@line.include?("#{attr}=") | |
@line.sub!(">", " #{attr}=\"#{value}\">") | |
else | |
@line.sub!("#{attr}=\"", "#{attr}=\"#{value} ") # double quotes | |
@line.sub!("#{attr}=\'", "#{attr}='#{value} ") # single quotes | |
end | |
return true | |
end | |
### SCRIPT START | |
files = ARGV[0].presence || "views/" | |
files = `find #{files} -name '*.slim'`.split("\n") | |
files.each do |file| | |
@content = "" | |
@lines = File.readlines(file) | |
@total_num_lines = @lines.size | |
@lines.each_with_index do |line, i| | |
puts "Line: #{i+1} of #{@total_num_lines}, File: #{file}" | |
@line = line | |
@indent = get_indent(@line) | |
if @line.strip.blank? | |
@content << "\n" | |
next | |
else | |
if @ruby_block_indent | |
if @indent.size > @ruby_block_indent.size | |
@content << @line | |
next | |
else | |
if @ruby_block_indent | |
@content << "#{@ruby_block_indent}%>\n\n" | |
end | |
@ruby_block_indent = nil | |
end | |
else | |
### TODO: Add close tag functionality | |
# if @prev_indent && @indent.size <= @prev_indent.size | |
# if @prev_el_type.present? | |
# @content << "#{@prev_indent}</#{@prev_el_type}>\n\n" | |
# elsif ["else","elsif","when"].none?{|x| @line.strip.sub("-","").strip.start_with?(x) } | |
# @content.sub!(/\n\n\n$/, "\n") | |
# @content.sub!(/\n\n$/, "\n") | |
# @content << "#{@prev_indent[2..-1]}<% end %>\n\n" | |
# end | |
# end | |
end | |
end | |
if @line.strip.start_with?("ruby:") | |
@line.sub!("ruby:", "<%") | |
@ruby_block_indent = @indent | |
elsif @line.strip.start_with?("-") | |
@line.sub!("#{@indent}-", "#{@indent}<%") | |
@line.sub!(/$/, " %>") | |
elsif @line.strip.start_with?("=") | |
@line.sub!("#{@indent}=", "#{@indent}<%=") | |
@line.sub!(/$/, " %>") | |
elsif @line.strip.start_with?("|") | |
@line.sub!("#{@indent}|", "#{@indent}") | |
else | |
### Normal element | |
part1 = @line.split(" ").first | |
element = part1.split(/\.|#/).first | |
if element.blank? | |
element = "div" | |
el_match = /^/ | |
else | |
el_match = element | |
end | |
classes = part1.sub(el_match, "").split(".").map{|y| y.split("#").first }.compact | |
ids = part1.sub(el_match, "").split("#").map{|y| y.split(".").first }.compact | |
prepend_attr("class", classes) | |
prepend_attr("id", ids) | |
@line.sub!(part1, element) | |
parts = @line.split(" ") | |
html_attrs = [] | |
element = @line.split(" ").first | |
parts = @line.sub(element, "").strip.split('" ') | |
inner_html = nil | |
parts.map(&:strip).each_with_index do |part,i| | |
if part.strip.start_with?("-") | |
part.sub!("-", "<%") | |
part.sub!(/$/, " %>") | |
inner_html = part | |
elsif part.strip.start_with?("=") | |
part.sub!("=", "<%=") | |
part.sub!(/$/, " %>") | |
inner_html = part | |
elsif part.strip.start_with?("|") | |
part.sub!("|", "<%") | |
part.sub!(/$/, " %>") | |
inner_html = part | |
elsif part.match?(/.+=[\"|\']/) | |
html_attrs << part | |
end | |
if inner_html | |
break | |
end | |
end | |
@line = "#{@indent}<#{element}#{' ' if !html_attrs.empty?}#{html_attrs.join(" ")}#{'/' if SELF_CLOSING_TAGS.include?(element)}>#{inner_html}" | |
if inner_html | |
@line << "</#{element}>" | |
end | |
@line << "\n" | |
end | |
@content << @line | |
end | |
File.open(file.sub('slim', 'erb'), "wb") do |f| | |
f.write @content | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment