diff --git a/.gitignore b/.gitignore index dc96cb9..1210def 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ /spec/reports/ /tmp/ /Gemfile.lock +/test/fixtures/tailwindcss/class_sorting.css diff --git a/erb-formatter.gemspec b/erb-formatter.gemspec index e3179c2..9a68c5b 100644 --- a/erb-formatter.gemspec +++ b/erb-formatter.gemspec @@ -30,5 +30,6 @@ Gem::Specification.new do |spec| spec.add_dependency "syntax_tree", '~> 6.0' + spec.add_development_dependency "tailwindcss-rails", "~> 2.0" spec.add_development_dependency "m", "~> 1.0" end diff --git a/lib/erb/formatter/command_line.rb b/lib/erb/formatter/command_line.rb index d53310b..356b708 100644 --- a/lib/erb/formatter/command_line.rb +++ b/lib/erb/formatter/command_line.rb @@ -3,6 +3,19 @@ require 'optparse' class ERB::Formatter::CommandLine + def self.tailwindcss_class_sorter(css_path) + css = File.read(css_path) + + css = css.tr("\n", " ").gsub(%r{\/\*.*?\*\/},"") # remove comments + css = css.gsub(%r<@media.*?\{>, "") # strip media queries + css = css.scan(%r<(?:^|\}|\{) *(\S.*?) *\{>).join(" ") # extract selectors + classes = css.tr(","," ").split(" ").grep(/\./).uniq.map { _1.split('.').last.gsub("\\", "") } + indexed_classes = Hash[classes.zip((0...classes.size).to_a)] + + ->(class_name) do + indexed_classes[class_name] || classes.index { _1.start_with?(class_name) } || -1 + end + end attr_reader :write, :filename, :read_stdin @@ -41,6 +54,10 @@ def initialize(argv, stdin: $stdin) @single_class_per_line = value end + parser.on("--tailwind-output-path PATH", "Set the path to the tailwind output file") do |value| + @tailwind_output_path = value + end + parser.on("--[no-]debug", "Enable debug mode") do |value| $DEBUG = value end @@ -73,11 +90,21 @@ def run end end + if @tailwind_output_path + css_class_sorter = self.class.tailwindcss_class_sorter(@tailwind_output_path) + end + files.each do |(filename, code)| if ignore_list.should_ignore_file? filename print code unless write else - html = ERB::Formatter.new(code, filename: filename, line_width: @width || 80, single_class_per_line: @single_class_per_line) + html = ERB::Formatter.new( + code, + filename: filename, + line_width: @width || 80, + single_class_per_line: @single_class_per_line, + css_class_sorter: css_class_sorter + ) if write File.write(filename, html) diff --git a/test/erb/test_formatter.rb b/test/erb/test_formatter.rb index adb4454..d99e6b1 100644 --- a/test/erb/test_formatter.rb +++ b/test/erb/test_formatter.rb @@ -16,7 +16,7 @@ def test_fixtures expected_path = erb_path.chomp('.erb') + '.expected.erb' # File.write expected_path, ERB::Formatter.format(File.read(erb_path)) - assert_equal(File.read(expected_path), ERB::Formatter.format(File.read(erb_path)), "Formatting of #{erb_path} failed") + assert_equal(File.read(expected_path), ERB::Formatter.new(File.read(erb_path)).to_s, "Formatting of #{erb_path} failed") end end @@ -156,4 +156,29 @@ def test_format_ruby_with_long_lines_and_larger_line_width ).to_s, ) end + + def test_tailwindcss_class_sorting + require 'tailwindcss-rails' + require 'erb/formatter/command_line' + + error_log = "#{__dir__}/../../tmp/tailwindcss.err.log" + Dir.mkdir(File.dirname(error_log)) unless File.exist?(File.dirname(error_log)) + + system( + Tailwindcss::Commands.executable, + "--content", "#{__dir__}/../fixtures/tailwindcss/class_sorting.html.erb", + "--output", "#{__dir__}/../fixtures/tailwindcss/class_sorting.css", + err: error_log, + ) || raise("Failed to generate tailwindcss output:\n#{File.read(error_log)}") + + css_class_sorter = ERB::Formatter::CommandLine.tailwindcss_class_sorter("#{__dir__}/../fixtures/tailwindcss/class_sorting.css") + + assert_equal( + File.read("#{__dir__}/../fixtures/tailwindcss/class_sorting.html.expected.erb"), + ERB::Formatter.new( + File.read("#{__dir__}/../fixtures/tailwindcss/class_sorting.html.erb"), + css_class_sorter: css_class_sorter, + ).to_s, + ) + end end diff --git a/test/fixtures/tailwindcss/class_sorting.html.erb b/test/fixtures/tailwindcss/class_sorting.html.erb new file mode 100644 index 0000000..9ff335d --- /dev/null +++ b/test/fixtures/tailwindcss/class_sorting.html.erb @@ -0,0 +1,14 @@ +