tailwind-sorter 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -0
- data/README.md +55 -20
- data/exe/tailwind_sorter +4 -1
- data/lib/tailwind_sorter/sorter.rb +44 -12
- data/lib/tailwind_sorter/version.rb +1 -1
- data/lib/tailwind_sorter.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 82b25d2e48c760db25e242cafa14a986831e6ccaff1498ea7fbf638dc22392d9
|
4
|
+
data.tar.gz: dc94b034b7e7922bafc9f618a7db6f839d102eb2c38f916689f538fcfab07d2c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 95a45a46c6a5911db7bd2e48fde99b7a752f2de25bc5832b009c0fe5d840912474be6047caf2f7ecb3d2325e894c466bab4ff9f32f71fe88506448ff204bb74c
|
7
|
+
data.tar.gz: 98a11cdfd1bebff6fd7a8a24069326dc26776dffdcb4b37f8271374793c04133823ebd2c3375c5a6192cec5f5f68ac0b61e9322be9757658b102d32898f02358
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
### 0.4.0
|
2
|
+
|
3
|
+
- Add support for regular expressions in configuration for class ordering (#3)
|
4
|
+
|
5
|
+
So instead of having to specify all variants of a certain Tailwind class, now you can cover all of them with a
|
6
|
+
regular expression.
|
7
|
+
- Cache sorting keys during processing (speeds up sorting a file with repeating CSS classes).
|
8
|
+
- Fix LOAD_PATH issues when running tests (#2).
|
9
|
+
- Add Github Action for tests, enhance tests.
|
10
|
+
- Require ruby 3.1+.
|
11
|
+
|
12
|
+
### 0.3.1
|
13
|
+
|
14
|
+
Return warnings when called from ruby code in warn_only mode.
|
15
|
+
|
16
|
+
### 0.3.0
|
17
|
+
|
18
|
+
First public release of the gemified version of Tailwind sorter.
|
19
|
+
|
20
|
+
### 0.0.0 - the original script
|
21
|
+
|
22
|
+
The repository with the bare-bones sorter script can be found here: https://github.com/NejRemeslnici/tailwind-sorter/tree/original-script
|
data/README.md
CHANGED
@@ -12,8 +12,11 @@ The gem contains a standalone executable script that can work in two ways:
|
|
12
12
|
Out of the box the script supports sorting classes in [Slim templates](http://slim-lang.com/) but can be configured for
|
13
13
|
anything else. The script also removes duplicate classes.
|
14
14
|
|
15
|
-
_This is what it looks like when Tailwind sorter is auto-run upon saving a changed template file in
|
16
|
-
<img src="img/
|
15
|
+
_This is what it looks like when Tailwind sorter is auto-run upon saving a changed template file in VS Code:_
|
16
|
+
<img src="img/tailwind_sorter_vscode.gif" alt="Automatically ordering CSS classes upon file saving in VS Code"></img>
|
17
|
+
|
18
|
+
_And similarly in RubyMine IDE:_
|
19
|
+
<img src="img/tailwind_sorter_rubymine.gif" alt="Automatically ordering CSS classes upon file saving in RubyMine"></img>
|
17
20
|
|
18
21
|
Please read the [accompanying post on dev.to](https://dev.to/nejremeslnici/tailwind-css-class-sorter-the-custom-way-35g5) for more details, if interested.
|
19
22
|
|
@@ -37,12 +40,11 @@ solution. This problem is even larger if you’ve added
|
|
37
40
|
[custom utility classes](https://tailwindcss.com/docs/adding-new-utilities) to your project.
|
38
41
|
|
39
42
|
Above all, it is **surprisingly easy** to create a custom sorting script – the one we use and present here is only
|
40
|
-
~
|
43
|
+
~150 lines. So, take this script and especially its config as a **template for you to revise and adapt**.
|
41
44
|
|
42
45
|
## Installation
|
43
46
|
|
44
|
-
Since version 0.3, the script has been packed into a gem so that it can be used directly from ruby as well as a standalone script (now a binstub).
|
45
|
-
|
47
|
+
Since version 0.3, the script has been packed into a gem so that it can be used directly from ruby as well as a standalone script (now a binstub).
|
46
48
|
|
47
49
|
### Installing the gem
|
48
50
|
|
@@ -69,7 +71,7 @@ $ bundle binstubs tailwind-sorter
|
|
69
71
|
|
70
72
|
This will create a `bin/tailwind_sorter` binstub file.
|
71
73
|
|
72
|
-
The gem has **no dependencies**, apart from ruby (tested on ruby 3.
|
74
|
+
The gem has **no dependencies**, apart from ruby (tested on ruby 3.1+) and its stdlib.
|
73
75
|
|
74
76
|
## Configuration
|
75
77
|
|
@@ -78,28 +80,61 @@ configured.
|
|
78
80
|
|
79
81
|
There are two important places to configure in the YAML file:
|
80
82
|
|
81
|
-
- **regular expressions**
|
82
|
-
format (such as `section#flash-messages.hidden.mt-4`) and classes in the context of the
|
83
|
-
Rails helpers (`link_to "E-shop", eshop_path, class: "no-underline font-bold red-100")`,
|
83
|
+
- **regular expressions** that tell the Tailwind sorter where to find CSS classes to sort: out of the box, the script
|
84
|
+
matches classes in the Slim format (such as `section#flash-messages.hidden.mt-4`) and classes in the context of the
|
85
|
+
`class` attribute in ruby / Rails helpers (`link_to "E-shop", eshop_path, class: "no-underline font-bold red-100")`,
|
84
86
|
|
85
87
|
- **CSS classes order and grouping**: the `classes_order` section in the YAML file determines the order in which the
|
86
88
|
classes will be sorted. If you want the classes with Tailwind variants (such as `sm:`, `hover:` etc.) to always be
|
87
89
|
ordered towards the end of line, put the classes in one big group, otherwise split them into any groups you want and
|
88
90
|
they will be ordered last in the particular group.
|
89
91
|
|
90
|
-
|
92
|
+
You have two options when specifying classes in this config section: pure strings and regular expressions:
|
93
|
+
|
94
|
+
- You can always just **list the CSS class names** in the config. This style gives you a full control over the ordering and it is the fastest option as well. The downside of it is that you'll find yourself having to update the config more often as new Tailwind classes variants emerge in your project and / or Tailwind itself:
|
95
|
+
|
96
|
+
```yaml
|
97
|
+
classes_order:
|
98
|
+
spacing:
|
99
|
+
...
|
100
|
+
- py-2
|
101
|
+
- py-4
|
102
|
+
- py-8
|
103
|
+
...
|
104
|
+
```
|
105
|
+
|
106
|
+
- Or, you can use **regular expressions** to cover all variants of a Tailwind class at once. A regular expression in
|
107
|
+
this part of the config is specified as a string delimited by slashes. Note that the
|
108
|
+
[`\A` and `\z` boundaries](https://docs.ruby-lang.org/en/master/Regexp.html#class-Regexp-label-Boundary+Anchors) are
|
109
|
+
automatically added to the expression so that it always matches the whole class name, not just part of it. Using regular expressions to sort classes shortens your configuration greatly but makes it a bit harder to understand.
|
110
|
+
|
111
|
+
```yaml
|
112
|
+
classes_order:
|
113
|
+
spacing:
|
114
|
+
...
|
115
|
+
- /py-\d+/
|
116
|
+
...
|
117
|
+
```
|
118
|
+
|
119
|
+
- And, of course, you can also freely mix these two approaches.
|
120
|
+
|
121
|
+
Unknown (e.g. your custom) classes will be **ordered first**. If you want to sort them differently, you will have to add them
|
122
|
+
to the config file to their proper place under `classes_order`. We recommend ordering custom classes first though as in
|
123
|
+
our opinion such classes usually bear more important meanings than the Tailwind ones and this setup also makes it easier
|
124
|
+
to spot typos in class names.
|
91
125
|
|
92
|
-
The default sort order of the classes resembles the one of Headwind which, in turn, seems to
|
93
|
-
the sections in the [official Tailwind documentation](https://tailwindcss.com/docs).
|
126
|
+
The default sort order of the classes in the bundled config file resembles the one of Headwind which, in turn, seems to
|
127
|
+
be inspired by the order of the sections in the [official Tailwind documentation](https://tailwindcss.com/docs).
|
94
128
|
|
95
|
-
More details about the configuration file can be found in
|
129
|
+
More details about the configuration file can be found in
|
130
|
+
[the wiki](https://github.com/NejRemeslnici/tailwind-sorter/wiki/The-config-file-explanation).
|
96
131
|
|
97
132
|
### Adding your unique set of Tailwind classes
|
98
133
|
|
99
134
|
The script works best if you only include the classes that you really use in your project. Once you grab all the classes
|
100
|
-
e.g. from your [
|
135
|
+
e.g. from your [JIT-ed](https://tailwindcss.com/docs/just-in-time-mode) production CSS bundle, you can initially reorder them using the following ruby snippet. Suppose you
|
101
136
|
have the ”default“ Tailwind classes sorted (taken e.g. from
|
102
|
-
[here](https://github.com/avencera/rustywind/blob/master/src/defaults.rs)
|
137
|
+
[here](https://github.com/avencera/rustywind/blob/master/rustywind-core/src/defaults.rs), one per line, in
|
103
138
|
the `default_classes.txt` file and your own (unordered) classes in `our_classes.txt`. Then the sorting could go along these lines:
|
104
139
|
|
105
140
|
```ruby
|
@@ -114,7 +149,7 @@ the `sorted_classes.txt` file) and move all of them to the appropriate sections
|
|
114
149
|
|
115
150
|
## Running the script
|
116
151
|
|
117
|
-
|
152
|
+
You can run the script manually like so:
|
118
153
|
|
119
154
|
```sh
|
120
155
|
bin/tailwind_sorter app/views/my_template.html.slim
|
@@ -122,7 +157,7 @@ bin/tailwind_sorter app/views/my_template.html.slim
|
|
122
157
|
|
123
158
|
The script finds all css classes and reorders them in-place in the file.
|
124
159
|
|
125
|
-
|
160
|
+
The script requires the configuration file to be present in `config/tailwind_sorter.yml` by default. You can tweak the configuration file path with the `-c` parameter:
|
126
161
|
|
127
162
|
```sh
|
128
163
|
bin/tailwind_sorter -c path/to/my/config_file.yml app/views/my_template.html.slim
|
@@ -161,10 +196,10 @@ You can also optionally pass in ome arguments such as `warn_only: true` to only
|
|
161
196
|
```sh
|
162
197
|
bundle install # to install the rspec gem
|
163
198
|
bundle exec rspec
|
164
|
-
|
199
|
+
.................
|
165
200
|
|
166
|
-
Finished in
|
167
|
-
|
201
|
+
Finished in 1.08 seconds (files took 0.03424 seconds to load)
|
202
|
+
17 examples, 0 failures
|
168
203
|
```
|
169
204
|
|
170
205
|
## Answers for the curious
|
data/exe/tailwind_sorter
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
3
|
+
lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
|
4
|
+
$LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
require "tailwind_sorter"
|
4
7
|
|
5
8
|
warn_only = false
|
6
9
|
config_file = "config/tailwind_sorter.yml"
|
@@ -3,6 +3,10 @@ require "yaml"
|
|
3
3
|
|
4
4
|
module TailwindSorter
|
5
5
|
class Sorter
|
6
|
+
def initialize
|
7
|
+
@sorting_keys_cache = {}
|
8
|
+
end
|
9
|
+
|
6
10
|
# reorders multiple variants, e.g.: "focus:sm:block" -> "sm:focus:block"
|
7
11
|
def sort_variants(css_class_with_variants, variants_order:)
|
8
12
|
*variants, css_class = css_class_with_variants.split(":")
|
@@ -15,31 +19,54 @@ module TailwindSorter
|
|
15
19
|
# Constructs the sorting key for sorting CSS classes in the following way:
|
16
20
|
#
|
17
21
|
# group_index, variant1_index, variant2_index, class_index
|
18
|
-
# "sm:focus:flex"
|
19
|
-
# "flex"
|
20
|
-
# "
|
21
|
-
def sorting_key(css_class_with_variants, variants_order:, classes_order:, class_groups:,
|
22
|
+
# "sm:focus:flex" -> "01,01,11,0010"
|
23
|
+
# "flex" -> "01,00,00,0010"
|
24
|
+
# "custom-class" -> "00,00,00,0000"
|
25
|
+
def sorting_key(css_class_with_variants, variants_order:, classes_order:, class_groups:, default_index: 0)
|
26
|
+
return @sorting_keys_cache[css_class_with_variants] if @sorting_keys_cache[css_class_with_variants]
|
27
|
+
|
22
28
|
*variants, css_class = css_class_with_variants.split(":")
|
29
|
+
|
30
|
+
matching_index_in_group = nil
|
31
|
+
matching_group = class_groups.find do |group|
|
32
|
+
matching_index_in_group ||= classes_order[group].index { _1 === css_class }
|
33
|
+
end
|
34
|
+
|
23
35
|
key = [
|
24
|
-
format("%02d", class_groups.index
|
36
|
+
format("%02d", matching_group && class_groups.index(matching_group) || default_index),
|
25
37
|
format("%02d", variants_order.index(variants[0]) || default_index),
|
26
38
|
format("%02d", variants_order.index(variants[1]) || default_index),
|
27
|
-
format("%04d",
|
39
|
+
format("%04d", matching_index_in_group || default_index)
|
28
40
|
].join(",")
|
29
41
|
|
30
42
|
# puts "#{css_class_with_variants} #{key}"
|
31
|
-
key
|
43
|
+
@sorting_keys_cache[css_class_with_variants] = key
|
44
|
+
end
|
45
|
+
|
46
|
+
def convert_regexps!(classes_order)
|
47
|
+
classes_order.each do |group, class_patterns|
|
48
|
+
class_patterns.map! do |class_or_pattern|
|
49
|
+
if !(patterns = class_or_pattern.match(%r{\A/(.*)/\z}).to_a).empty?
|
50
|
+
Regexp.new(/\A#{patterns.last}\z/)
|
51
|
+
else
|
52
|
+
class_or_pattern
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
classes_order
|
32
58
|
end
|
33
59
|
|
34
60
|
def sort_classes(file, regexps:, variants_order:, classes_order:, default_index: 0, warn_only: false)
|
61
|
+
convert_regexps!(classes_order)
|
35
62
|
class_groups = classes_order.keys
|
36
|
-
|
63
|
+
warnings = []
|
37
64
|
|
38
65
|
infile = File.open(file)
|
39
66
|
outfile = Tempfile.create("#{File.basename(file)}.sorted")
|
40
67
|
|
41
68
|
calculate_sorting_key = lambda do |css_class_with_variants|
|
42
|
-
sorting_key(css_class_with_variants, variants_order:, classes_order:, class_groups:,
|
69
|
+
sorting_key(css_class_with_variants, variants_order:, classes_order:, class_groups:, default_index:)
|
43
70
|
end
|
44
71
|
|
45
72
|
changed = false
|
@@ -69,7 +96,9 @@ module TailwindSorter
|
|
69
96
|
# puts orig_keys.inspect
|
70
97
|
# puts sorted_keys.inspect
|
71
98
|
if orig_keys != sorted_keys
|
72
|
-
|
99
|
+
warning = "#{file}:#{line_number}:CSS classes are not sorted well. Please run 'tailwind_sorter #{file}'."
|
100
|
+
warnings << warning
|
101
|
+
puts(warning)
|
73
102
|
end
|
74
103
|
else
|
75
104
|
orig_line = line.dup unless changed
|
@@ -83,7 +112,10 @@ module TailwindSorter
|
|
83
112
|
|
84
113
|
success = true
|
85
114
|
|
86
|
-
|
115
|
+
warnings
|
116
|
+
|
117
|
+
rescue StandardError => e
|
118
|
+
warn "An error occurred: #{e}"
|
87
119
|
success = false
|
88
120
|
|
89
121
|
ensure
|
@@ -113,4 +145,4 @@ module TailwindSorter
|
|
113
145
|
new.run(...)
|
114
146
|
end
|
115
147
|
end
|
116
|
-
end
|
148
|
+
end
|
data/lib/tailwind_sorter.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tailwind-sorter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- NejŘemeslníci.cz
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-08-04 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Simple but customizable sorter for TailwindCSS classes
|
14
14
|
email:
|
@@ -18,6 +18,7 @@ executables:
|
|
18
18
|
extensions: []
|
19
19
|
extra_rdoc_files: []
|
20
20
|
files:
|
21
|
+
- CHANGELOG.md
|
21
22
|
- README.md
|
22
23
|
- Rakefile
|
23
24
|
- exe/tailwind_sorter
|
@@ -39,14 +40,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
39
40
|
requirements:
|
40
41
|
- - ">="
|
41
42
|
- !ruby/object:Gem::Version
|
42
|
-
version: '3.
|
43
|
+
version: '3.1'
|
43
44
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
44
45
|
requirements:
|
45
46
|
- - ">="
|
46
47
|
- !ruby/object:Gem::Version
|
47
48
|
version: '0'
|
48
49
|
requirements: []
|
49
|
-
rubygems_version: 3.
|
50
|
+
rubygems_version: 3.5.3
|
50
51
|
signing_key:
|
51
52
|
specification_version: 4
|
52
53
|
summary: Customizable TailwindCSS classes sorter
|