Skip to content

Commit

Permalink
Add a sorter based on a TailwindCSS output file
Browse files Browse the repository at this point in the history
This sorter will use the same definition sequence found in the output
file which is what is also used by the official TailwindCSS prettyprint
formatter.

Co-Authored-By: Francesco Aiello <francesco.aiello@hey.com>
  • Loading branch information
elia and FrancescoAiello01 committed Dec 29, 2023
1 parent ef8a847 commit 2624861
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
/spec/reports/
/tmp/
/Gemfile.lock
/test/fixtures/tailwindcss/class_sorting.css
1 change: 1 addition & 0 deletions erb-formatter.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -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
29 changes: 28 additions & 1 deletion lib/erb/formatter/command_line.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
27 changes: 26 additions & 1 deletion test/erb/test_formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
14 changes: 14 additions & 0 deletions test/fixtures/tailwindcss/class_sorting.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<div class="pt-2 p-4">
</div>

<div class="text-gray-700 shadow-md p-3 border-gray-300 ml-4 h-24 flex border-2">
</div>

<div class="hover:opacity-75 opacity-50 hover:scale-150 scale-125">
</div>

<div class="lg:grid-cols-4 grid sm:grid-cols-3 grid-cols-2">
</div>

<div class="p-3 shadow-xl select2-dropdown">
</div>
16 changes: 16 additions & 0 deletions test/fixtures/tailwindcss/class_sorting.html.expected.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<div class="p-4 pt-2">
</div>

<div
class="ml-4 flex h-24 border-2 border-gray-300 p-3 text-gray-700 shadow-md"
>
</div>

<div class="scale-125 opacity-50 hover:scale-150 hover:opacity-75">
</div>

<div class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4">
</div>

<div class="select2-dropdown p-3 shadow-xl">
</div>

0 comments on commit 2624861

Please sign in to comment.