super-slim 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7c27c1a3bdc54556d0e0418a316838423719f9a0da47bba2be27b4a2812498c7
4
+ data.tar.gz: d5a779c6fa56691f985b3a82516769118dcb17a883eacfc6bbbe23b6afb14da0
5
+ SHA512:
6
+ metadata.gz: 0d5e8d990ae3886c94cbd198f1ccfbf51722e121cf2529bfc239da0b52b6639aaf9dec2609396eef4ab43f938d9d15d0f1913085c79b23704c8373e17bac4269
7
+ data.tar.gz: e7eef329f3c7adef4ba9b7f53e697a35e8aec0501c72304517c590ade320641555ec7167cf6f0ff1fa8f693fe22b45bb99da3a69e6808afcc13cdfa630a5123f
data/CHANGELOG.md ADDED
@@ -0,0 +1,118 @@
1
+ # Changelog
2
+
3
+ ## [Unreleased]
4
+
5
+ ## [3.0.0] — 2026-11-05
6
+
7
+ SuperSlim is published as super-slim, the name of its command.
8
+
9
+ **Breaking**
10
+ - The gem is renamed `super-slim`: write `gem "super-slim"` in the Gemfile and `plugins: [super-slim]` in RuboCop's
11
+ configuration. The `SuperSlim` module, `require "super_slim"`, the `super-slim` command and `.super-slim.yml` are
12
+ unchanged.
13
+
14
+ ## [2.2.0] — 2026-11-05
15
+
16
+ Six linter rules and options, `super-slim format`, and a formatter that no longer wraps a line RuboCop then refuses.
17
+
18
+ **New**
19
+ - `super-slim format` and the `format:` key of `.super-slim.yml`; `fmt` remains an alias for both.
20
+ - Every linter rule takes `include:` and `exclude:` globs.
21
+ - DeprecatedAttributes (`attributes: {old: new}`), and prefixes in DeprecatedClasses (`ml-*: ms-*`).
22
+ - UnescapedOutput (`==`, `html_safe`, `raw`, `#{{}}`), EmbeddedEngines (`forbidden_engines:`) and HardcodedText, off
23
+ by default.
24
+
25
+ **Fixed**
26
+ - `super-slim format` keeps a line ending with an `if`, `unless`, `while`, `until` or `rescue` modifier on one line:
27
+ wrapped, RuboCop refused it (Style/MultilineIfModifier).
28
+
29
+ ## [2.1.0] — 2026-11-05
30
+
31
+ Slim's doctypes are back, for email layouts.
32
+
33
+ **New**
34
+ - `doctype transitional`, `strict` and `frameset` render the HTML 4.01 doctypes again, and XML templates take `1.1`,
35
+ `basic`, `mobile`, `svg` and the XHTML 1.0 ones, as in Slim 5. Email layouts need `doctype transitional`:
36
+ `<!DOCTYPE html>` switches Apple Mail and iOS Mail to standards mode, which opens a gap under the images of table
37
+ cells.
38
+
39
+ ## [2.0.1] — 2026-11-05
40
+
41
+ Two fixes to `super-slim`: braces around wrapped attributes, and `--help`.
42
+
43
+ **Fixed**
44
+ - `super-slim fmt` writes a space before `{` when it wraps attributes inside `{}` (`a.btn {`), as templates
45
+ usually do; `(` and `[` stay attached to the tag.
46
+ - `super-slim --help`, `-h` and `help` print the usage on stdout and exit 0, after a command too
47
+ (`super-slim fmt --help`). An unknown option, such as `fmt --chek`, fails with the usage and status 64
48
+ instead of crashing.
49
+
50
+ ## [2.0.0] — 2026-11-05
51
+
52
+ SlimX becomes SuperSlim, sheds what a Rails app doesn't need, and `super-slim fmt` wraps long lines.
53
+
54
+ **Breaking**
55
+ - The gem is renamed: `super_slim` in the Gemfile, the `SuperSlim` module, the `super-slim lint|fmt` command,
56
+ `.super-slim.yml` and `plugins: [super_slim]` for RuboCop. Compiled templates name their variables
57
+ `_super_slim1` instead of `_slimx1`.
58
+ - No more Tilt adapter: `require "slimx/tilt"` has no replacement. Rails and `SuperSlim.compile` are unchanged.
59
+ - No more strict mode (`SlimX.strict`, `strict: true`): run `super-slim fmt --check` in CI instead.
60
+ - No more custom shortcuts: only `#id` and `.class`.
61
+ - Only `doctype 5`, `doctype html` and `doctype xml` remain; HTML 4 and XHTML doctypes, such as
62
+ `doctype transitional`, raise `Invalid doctype`.
63
+
64
+ **New**
65
+ - `super-slim fmt` wraps lines longer than `fmt: max_line_length` in `.super-slim.yml`, off by default: a tag's
66
+ attributes one per line inside `fmt: attribute_delimiters` (`"()"`, `"[]"` or `"{}"`), then the arguments of
67
+ its Ruby code after each comma, four spaces deep when the line opens a block. A wrap is kept only when the
68
+ compiled Ruby differs by whitespace alone.
69
+
70
+ ## [1.1.0] — 2026-11-04
71
+
72
+ A RuboCop plugin that lints the Ruby inside templates with SlimX's own parser, and templates compiled up to 10% faster.
73
+
74
+ **New**
75
+ - A RuboCop plugin (`plugins: [slimx]`) lints the Ruby of templates: `-` and `=` lines, code attributes, splats,
76
+ `#{}` interpolations and `ruby:` blocks. Offenses point at their line and column in the `.slim` file, and
77
+ autocorrection writes back into it. It replaces rubocop-slim, and with it slimi and Temple; unlike slimi, it
78
+ also reads the output of a tag with whitespace markers and attributes (`span> title="x" = name`).
79
+
80
+ **Faster**
81
+ - Templates compile 7% faster without JIT and 10% faster with YJIT, with 11% to 16% fewer allocations (6,097
82
+ public templates, Ruby 3.3 and 4.0). Rendering is unchanged.
83
+
84
+ **Fixed**
85
+ - `slimx lint` reports the offenses of one line in the same order on every Ruby version.
86
+
87
+ ## [1.0.0] — 2026-11-04
88
+
89
+ First stable release: a Slim 5 engine written from scratch, without Temple. 0.1.0 and 0.1.1 were previews. It
90
+ renders what Slim 5 renders with `format: :html, sort_attrs: false`, byte for byte; XML formats (`.xml`, `.rss`,
91
+ `.atom`) render as XML.
92
+
93
+ **New**
94
+ - Rails through a railtie, Tilt through `require "slimx/tilt"`, and `SlimX.compile` for plain Ruby.
95
+ - Every `-` and `=` stays on its template line, so backtraces point at the right one.
96
+ - `slimx fmt`, which refuses any change to the compiled Ruby, and strict mode (`SlimX.strict`), which
97
+ refuses unformatted templates at compile time.
98
+ - `slimx lint` with 29 rules from slim-lint, haml-lint, erb_lint, Herb and eslint-plugin-jsx-a11y,
99
+ configured in `.slimx.yml`.
100
+ - `tailwind_classes`, off by default: class shortcuts read Tailwind class names.
101
+
102
+ **Left out**
103
+ - XHTML, `sort_attrs` and the other Temple options, the `coffee:`, `sass:`, `scss:`, `less:`, `erb:`,
104
+ `builder:` and wiki engines, conditional comments, the `logic_less`, `translator`, `include` and `smart`
105
+ plugins, and lambda shortcuts: each raises at compile time.
106
+
107
+ **Requires**
108
+ - Ruby 3.3 or later, every Ruby still maintained, Rails 8.0 or 8.1 for the railtie, and strscan 3.1.1 or later,
109
+ newer than the one Ruby 3.3 ships.
110
+
111
+ [Unreleased]: https://github.com/levups/super-slim/compare/v3.0.0...HEAD
112
+ [3.0.0]: https://github.com/levups/super-slim/compare/v2.2.0...v3.0.0
113
+ [2.2.0]: https://github.com/levups/super-slim/compare/v2.1.0...v2.2.0
114
+ [2.1.0]: https://github.com/levups/super-slim/compare/v2.0.1...v2.1.0
115
+ [2.0.1]: https://github.com/levups/super-slim/compare/v2.0.0...v2.0.1
116
+ [2.0.0]: https://github.com/levups/super-slim/compare/v1.1.0...v2.0.0
117
+ [1.1.0]: https://github.com/next-gen-gems/slimx/compare/v1.0.0...v1.1.0
118
+ [1.0.0]: https://github.com/next-gen-gems/slimx/releases/tag/v1.0.0
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2026 Level UP Solutions
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/LICENSE-slim ADDED
@@ -0,0 +1,22 @@
1
+ SuperSlim's parser follows the grammar and the parsing algorithm of Slim
2
+ (https://github.com/slim-template/slim), released under the MIT License:
3
+
4
+ Copyright (c) 2010 - 2026 Slim Team
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,217 @@
1
+ # SuperSlim
2
+
3
+ A Slim template engine rewritten from scratch: no Temple, no filter pipeline, a single-pass compiler and a
4
+ render-time runtime of a few methods. Templates written for [Slim](https://github.com/slim-template/slim) 5
5
+ render byte for byte the same, faster, with fewer allocations.
6
+
7
+ https://levups.github.io/super-slim/
8
+
9
+ ## Installation
10
+
11
+ ```ruby
12
+ # Gemfile
13
+ gem "super-slim" # instead of slim-rails
14
+ ```
15
+
16
+ ## Usage
17
+
18
+ Rails picks it up through its railtie. Outside Rails, `SuperSlim.compile(source)` returns the Ruby code.
19
+
20
+ ## What SuperSlim renders
21
+
22
+ HTML5, with attributes in the order you write them — what Slim renders with
23
+ `format: :html, sort_attrs: false`. Templates whose format is XML (`.xml`, `.rss`, `.atom`) render as XML
24
+ (`<link />`, `doctype xml`) from their format alone.
25
+
26
+ The whole Slim 5 grammar is supported: tags and `#id`/`.class` shortcuts, attributes with
27
+ any delimiter, boolean attributes, `*splat`, `data`/`aria` hashes, `class` merging, `<`/`>` whitespace
28
+ markers, `|` and `'` text, inline HTML, `/` and `/!` comments, `-` control code, `=`/`==` output, `#{}` and
29
+ `#{{}}` interpolation, Slim's doctypes (`html`, `transitional` for email clients, their XHTML versions in XML
30
+ templates), and the `ruby:`, `javascript:`, `css:` and `markdown:` (through
31
+ [Markly](https://github.com/ioquatix/markly)) embedded engines.
32
+
33
+ ## Tailwind class names
34
+
35
+ Slim cuts `.rounded-b-[3px]` at the bracket, and refuses `.lg:[&:nth-child(3)]:hover:underline`. Turn on
36
+ `tailwind_classes` and the `.` shortcut takes any Tailwind class name:
37
+
38
+ ```slim
39
+ .p-1.rounded-b-[3px].lg:[&:nth-child(3)]:hover:underline
40
+ .font-['Open_Sans'].bg-(--brand).mx-0.5.w-1/2.!font-bold.@lg:flex
41
+ ul.*:p-2
42
+ ```
43
+
44
+ ```ruby
45
+ SuperSlim.tailwind_classes = true # config/initializers/super_slim.rb, or tailwind_classes: true per compile
46
+ ```
47
+
48
+ ```yaml
49
+ # .super-slim.yml, for super-slim lint and super-slim format
50
+ tailwind_classes: true
51
+ ```
52
+
53
+ Attribute lists keep their meaning: Tailwind never puts a bracket right after a letter or a digit, so
54
+ `a.btn[href="/"]` is still a link with a class and an `href`. A colon followed by a space still nests a tag
55
+ (`li.item: a`), and a final `/` still closes one. What changes is what Slim mangles: it renders `.size-2.5` as
56
+ `class="size-2 5"`, the option as `class="size-2.5"`. On 7,505 templates from 31 apps, 16 compile differently
57
+ with the option, all of them Tailwind classes Slim breaks. It stays off by default all the same, so that
58
+ turning SuperSlim on changes nothing.
59
+
60
+ The option only changes how templates are read: compiling 1,408 templates takes the same time (+0.5%, within
61
+ noise), and the compiled Ruby, so the time it takes to render, is the same.
62
+
63
+ ## What SuperSlim leaves out
64
+
65
+ Each fails at compile time with a clear error instead of being silently ignored:
66
+
67
+ - the XHTML format, `sort_attrs`, `attr_quote`, `pretty`, `js_wrapper` and every Temple option;
68
+ - the `coffee:`, `sass:`, `scss:`, `less:`, `erb:`, `builder:`, `textile:`, `rdoc:`, `asciidoc:` and wiki
69
+ engines, and `/[if IE]` conditional comments;
70
+ - the `logic_less`, `translator`, `include` and `smart` plugins, and custom shortcuts: only `#id` and `.class`.
71
+
72
+ They can come back if people ask, as long as they cost nothing at render time.
73
+
74
+ ## Migrating from Slim
75
+
76
+ Slim's defaults are `format: :xhtml` and `sort_attrs: true`. If you never changed them, first switch Slim
77
+ to `format: :html, sort_attrs: false` and check your test suite: that is the output SuperSlim gives. Then swap
78
+ `slim-rails` for `super-slim`, and drop any `Slim::Engine.set_options`/`with_options` call.
79
+
80
+ ## Formatter and linter
81
+
82
+ One parser serves the compiler, the formatter and the linter, so all three read templates the same way.
83
+
84
+ `super-slim format [--check] [PATH…]` (or `fmt`) rewrites templates in their canonical layout: two spaces per level, `- code`,
85
+ `= output` and `p = output` spacing, no redundant `div`, no trailing whitespace, single blank lines, one final
86
+ newline. Text blocks move as a whole, so the whitespace they render stays put — and before writing anything,
87
+ the formatter compiles both versions and refuses if the Ruby differs. Formatting cannot change a page.
88
+
89
+ With `format: max_line_length: 120` in `.super-slim.yml`, `format` also wraps longer lines: a tag's attributes one
90
+ per line inside `attribute_delimiters` (`"()"` by default, `"[]"` or `"{}"`), then the arguments of its Ruby code after each comma, four spaces deep when the line opens a block. It keeps a wrap only
91
+ when the compiled Ruby differs by whitespace alone, and leaves lines already spread over several lines alone.
92
+
93
+ `super-slim lint [PATH…]` reads `.super-slim.yml` and checks, with about a third of the CPU time slim-lint takes:
94
+
95
+ | Rule | From | Default |
96
+ |---|---|---|
97
+ | Indentation, Tab, TrailingWhitespace, EmptyLines, TrailingBlankLines, ControlStatementSpacing, RedundantDiv | slim-lint, fixed by `super-slim format` | on |
98
+ | LineLength (`max: 120`), CommentControlStatement, EmptyControlStatement, ConsecutiveControlStatements (`max: 2`), TagCase | slim-lint | on |
99
+ | InstanceVariables (in partials) | haml-lint, Rails conventions | on |
100
+ | StrictLocals (partials declare `/# locals:`) | Rails 7.1 strict locals | off |
101
+ | DuplicateId, ImageAlt, IframeTitle, AnchorHref, NestedLinks, PositiveTabindex, BooleanAttributeValue, AriaRole, AriaAttribute | Herb, eslint-plugin-jsx-a11y | on |
102
+ | ButtonType, InlineStyles | eslint-plugin-react, haml-lint | off |
103
+ | DeprecatedClasses (`classes: {old: new}`, `old-*: new-*` for a prefix), DeprecatedAttributes (`attributes: {old: new}`) | erb_lint | on, empty |
104
+ | UnescapedOutput (`==`, `html_safe`, `raw`, `#{{}}`) | Brakeman, erb_lint | off |
105
+ | EmbeddedEngines (`forbidden_engines: [javascript, css]`) | slim-lint | off |
106
+ | HardcodedText (text to translate) | erb_lint | off |
107
+ | UnnecessaryInterpolation, UnnecessaryStringOutput | haml-lint | on |
108
+ | Zwsp (invisible characters) | slim-lint | on |
109
+
110
+ ```yaml
111
+ # .super-slim.yml
112
+ linters:
113
+ LineLength:
114
+ max: 150
115
+ ButtonType:
116
+ enabled: true
117
+ DeprecatedClasses:
118
+ classes:
119
+ text-muted: text-body-secondary
120
+ ml-*: ms-*
121
+ InlineStyles:
122
+ enabled: true
123
+ exclude: ["app/views/*_mailer/**/*"]
124
+ HardcodedText:
125
+ enabled: true
126
+ include: ["app/views/shop/**/*.slim"]
127
+ ```
128
+
129
+ Every rule takes `include:` and `exclude:`, lists of globs matched against paths relative to `.super-slim.yml`
130
+ (`**/` spans directories).
131
+
132
+ The Ruby inside templates is RuboCop's job: SuperSlim ships a RuboCop plugin that hands it each `-` and `=` line,
133
+ code attribute, splat, `#{}` interpolation and `ruby:` block, read by SuperSlim's own parser. Offenses point at their
134
+ line and column in the `.slim` file, and autocorrection writes back into it. It replaces rubocop-slim, and with
135
+ it slimi and Temple:
136
+
137
+ ```yaml
138
+ # .rubocop-slim.yml, run with rubocop -c .rubocop-slim.yml
139
+ inherit_from: .rubocop.yml
140
+ plugins:
141
+ - super-slim
142
+ AllCops:
143
+ Include:
144
+ - "**/*.slim"
145
+ ```
146
+
147
+ The cops that cannot hold in a template — indentation and alignment across lines, frozen string comments,
148
+ `Lint/UselessAssignment` on a variable a later line reads — are turned off for `.slim` files, as rubocop-slim
149
+ does. Unlike slimi, SuperSlim also reads the output of a tag with whitespace markers and attributes
150
+ (`span> title="x" = name`), so a few offenses appear when switching.
151
+
152
+ ## How it is tested
153
+
154
+ - Slim's own test suite and its literate specification (`TESTS.md`) run against SuperSlim: every template renders
155
+ through Slim and SuperSlim, and both outputs must match.
156
+ - A seeded fuzzer generates thousands of random templates from the grammar and compares both engines; CI adds
157
+ 10,000 from a new seed on every run.
158
+ - Golden snapshots (`test/golden`) hold the rendered HTML, compiled Ruby, formatting and lint offenses of
159
+ templates covering the grammar, its errors and Tailwind class names: `UPDATE_GOLDEN=1` rewrites them.
160
+ - `bench/compiled_digests.rb` proves a refactoring leaves the compiled Ruby of a whole corpus unchanged.
161
+
162
+ Real templates come from 30 public apps pinned in `corpus/manifest.yml`: `rake corpus:fetch` downloads only
163
+ their `.slim` files into the ignored `corpus/cache`, `rake corpus:check` compiles, formats and lints each one
164
+ against Slim, and `rake corpus:diff BASE=rev` reports what changes between a revision and the working tree:
165
+ compiled Ruby, formatting, lint offenses. Downloaded templates are never rendered, as rendering runs their
166
+ Ruby; directories you trust, such as your own app, render too when passed in `SUPER_SLIM_CORPUS`.
167
+
168
+ ## Benchmarks
169
+
170
+ `bench/compare.rb` renders the same blog page with SuperSlim, Slim, Haml, Erubi and Herb, checks that they all
171
+ produce the same HTML, and writes compile and render speed and allocations to `docs/benchmarks.json`, which
172
+ the website reads. Run it before each release, on a quiet machine:
173
+
174
+ ```sh
175
+ bundle exec rake bench # YJIT, 5 seconds per measurement
176
+ SUPER_SLIM_CORPUS=path/to/app/views bundle exec rake bench # adds the compile time of a whole app against Slim
177
+ BENCH_LOCK=path/to/.bench.lock bundle exec rake bench # waits for other benchmarks holding that lock
178
+ ```
179
+
180
+ With `corpus/cache` fetched, it also times the open-source corpus, and `super-slim lint` and `format` there against
181
+ slim-lint when it is installed. `bundle exec rake docs` rewrites the linter rules on the website
182
+ (`docs/tools.html`), after checking every example against the linter.
183
+
184
+ ## Development
185
+
186
+ ```sh
187
+ bundle install
188
+ bundle exec rake test # SuperSlim's tests, then Slim's own suites
189
+ BUNDLE_GEMFILE=gemfiles/rails_8_0.gemfile bundle exec rake test # the same on Rails 8.0
190
+ bundle exec rubocop
191
+ FUZZ_SEED=42 FUZZ_CASES=20000 bundle exec ruby -Ilib test/fuzz_test.rb
192
+ bundle exec ruby -Ilib bench/corpus.rb path/to/app # compile time and allocations against Slim
193
+ bundle exec ruby --yjit -Ilib bench/render.rb # render speed and allocations against Slim
194
+ ```
195
+
196
+ ### Releasing
197
+
198
+ Pull requests leave `CHANGELOG.md` alone: a release starts by writing its notes under `## [Unreleased]`, from the
199
+ pull requests merged since the last tag, without committing them. Refresh the website's numbers on a quiet machine
200
+ (`SUPER_SLIM_CORPUS=path/to/app/views bundle exec rake bench`) and merge them through a pull request, then, from an
201
+ up-to-date `main` whose CI is green:
202
+
203
+ ```sh
204
+ bin/release minor --dry-run # the notes and the changes, nothing written
205
+ bin/release minor # or patch, major, or an exact version such as 1.2.0
206
+ ```
207
+
208
+ `main` takes no direct push, so `bin/release` dates the Unreleased section and bumps the version on a branch
209
+ `release/vX.Y.Z`, opens its pull request, which merges itself once CI is green, and waits for it. It then pushes a
210
+ signed tag `vX.Y.Z` on the merge commit (`bin/release --tag X.Y.Z` does it if you stopped waiting). The tag starts
211
+ the Release workflow, which publishes the gem to RubyGems through trusted publishing and creates the GitHub release
212
+ with the version's notes and the `.gem`.
213
+
214
+ ## License
215
+
216
+ MIT, by Level UP Solutions, part of [Next Gen Gems](https://github.com/next-gen-gems). The parser follows the
217
+ grammar and parsing algorithm of [Slim](https://github.com/slim-template/slim), by the Slim Team (MIT).
@@ -0,0 +1,212 @@
1
+ inherit_mode:
2
+ merge:
3
+ - Exclude
4
+ - Include
5
+
6
+ AllCops:
7
+ Include:
8
+ - "**/*.slim"
9
+
10
+ Layout/ArgumentAlignment:
11
+ Exclude:
12
+ - "**/*.slim"
13
+
14
+ Layout/ArrayAlignment:
15
+ Exclude:
16
+ - "**/*.slim"
17
+
18
+ Layout/BlockAlignment:
19
+ Exclude:
20
+ - "**/*.slim"
21
+
22
+ Layout/ClosingParenthesisIndentation:
23
+ Exclude:
24
+ - "**/*.slim"
25
+
26
+ Layout/EmptyLineAfterGuardClause:
27
+ Exclude:
28
+ - "**/*.slim"
29
+
30
+ Layout/EndAlignment:
31
+ Exclude:
32
+ - "**/*.slim"
33
+
34
+ Layout/FirstArgumentIndentation:
35
+ Exclude:
36
+ - "**/*.slim"
37
+
38
+ Layout/FirstArrayElementIndentation:
39
+ Exclude:
40
+ - "**/*.slim"
41
+
42
+ Layout/FirstArrayElementLineBreak:
43
+ Exclude:
44
+ - "**/*.slim"
45
+
46
+ Layout/FirstHashElementIndentation:
47
+ Exclude:
48
+ - "**/*.slim"
49
+
50
+ Layout/FirstHashElementLineBreak:
51
+ Exclude:
52
+ - "**/*.slim"
53
+
54
+ Layout/FirstMethodArgumentLineBreak:
55
+ Exclude:
56
+ - "**/*.slim"
57
+
58
+ Layout/FirstParameterIndentation:
59
+ Exclude:
60
+ - "**/*.slim"
61
+
62
+ Layout/HashAlignment:
63
+ Exclude:
64
+ - "**/*.slim"
65
+
66
+ Layout/InitialIndentation:
67
+ Exclude:
68
+ - "**/*.slim"
69
+
70
+ Layout/IndentationConsistency:
71
+ Exclude:
72
+ - "**/*.slim"
73
+
74
+ Layout/IndentationWidth:
75
+ Exclude:
76
+ - "**/*.slim"
77
+
78
+ Layout/LineEndStringConcatenationIndentation:
79
+ Exclude:
80
+ - "**/*.slim"
81
+
82
+ Layout/LineLength:
83
+ Exclude:
84
+ - "**/*.slim"
85
+
86
+ Layout/MultilineArrayBraceLayout:
87
+ Exclude:
88
+ - "**/*.slim"
89
+
90
+ Layout/MultilineAssignmentLayout:
91
+ Exclude:
92
+ - "**/*.slim"
93
+
94
+ Layout/MultilineHashBraceLayout:
95
+ Exclude:
96
+ - "**/*.slim"
97
+
98
+ Layout/MultilineMethodCallBraceLayout:
99
+ Exclude:
100
+ - "**/*.slim"
101
+
102
+ Layout/MultilineMethodCallIndentation:
103
+ Exclude:
104
+ - "**/*.slim"
105
+
106
+ Layout/MultilineMethodDefinitionBraceLayout:
107
+ Exclude:
108
+ - "**/*.slim"
109
+
110
+ Layout/MultilineOperationIndentation:
111
+ Exclude:
112
+ - "**/*.slim"
113
+
114
+ Layout/ParameterAlignment:
115
+ Exclude:
116
+ - "**/*.slim"
117
+
118
+ Layout/TrailingEmptyLines:
119
+ Exclude:
120
+ - "**/*.slim"
121
+
122
+ Layout/TrailingWhitespace:
123
+ Exclude:
124
+ - "**/*.slim"
125
+
126
+ Lint/EmptyFile:
127
+ Exclude:
128
+ - "**/*.slim"
129
+
130
+ Lint/Syntax:
131
+ Exclude:
132
+ - "**/*.slim"
133
+
134
+ Lint/UselessAssignment:
135
+ Exclude:
136
+ - "**/*.slim"
137
+
138
+ Lint/Void:
139
+ Exclude:
140
+ - "**/*.slim"
141
+
142
+ Metrics/BlockLength:
143
+ Exclude:
144
+ - "**/*.slim"
145
+
146
+ Metrics/BlockNesting:
147
+ Exclude:
148
+ - "**/*.slim"
149
+
150
+ Naming/FileName:
151
+ Exclude:
152
+ - "**/*.slim"
153
+
154
+ Style/FrozenStringLiteralComment:
155
+ Exclude:
156
+ - "**/*.slim"
157
+
158
+ Style/IdenticalConditionalBranches:
159
+ Exclude:
160
+ - "**/*.slim"
161
+
162
+ Style/IfUnlessModifier:
163
+ Exclude:
164
+ - "**/*.slim"
165
+
166
+ Style/MultilineTernaryOperator:
167
+ Exclude:
168
+ - "**/*.slim"
169
+
170
+ Style/NestedTernaryOperator:
171
+ Exclude:
172
+ - "**/*.slim"
173
+
174
+ Style/Next:
175
+ Exclude:
176
+ - "**/*.slim"
177
+
178
+ Style/ParallelAssignment:
179
+ Exclude:
180
+ - "**/*.slim"
181
+
182
+ Style/RedundantParentheses:
183
+ Exclude:
184
+ - "**/*.slim"
185
+
186
+ Style/RescueModifier:
187
+ Exclude:
188
+ - "**/*.slim"
189
+
190
+ Style/Semicolon:
191
+ Exclude:
192
+ - "**/*.slim"
193
+
194
+ Style/TrailingCommaInArguments:
195
+ Exclude:
196
+ - "**/*.slim"
197
+
198
+ Style/TrailingCommaInArrayLiteral:
199
+ Exclude:
200
+ - "**/*.slim"
201
+
202
+ Style/TrailingCommaInHashLiteral:
203
+ Exclude:
204
+ - "**/*.slim"
205
+
206
+ Style/WhileUntilDo:
207
+ Exclude:
208
+ - "**/*.slim"
209
+
210
+ Style/WhileUntilModifier:
211
+ Exclude:
212
+ - "**/*.slim"
data/exe/super-slim ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "../lib/super_slim/cli"
5
+
6
+ exit SuperSlim::CLI.new.call(ARGV)
data/lib/super-slim.rb ADDED
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Bundler requires a gem by its name: super-slim, then super/slim.
4
+ require_relative "super_slim"
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SuperSlim
4
+ module AST
5
+ NEWLINE = :newline
6
+
7
+ # Structs, not Data: Data.new allocates two more objects per node and is 2.8x slower, on every template line.
8
+ Static = Struct.new(:text)
9
+ Text = Struct.new(:text)
10
+ TextBlock = Struct.new(:children)
11
+ InlineHtml = Struct.new(:text, :children)
12
+ Tag = Struct.new(:name, :attributes, :content)
13
+ Control = Struct.new(:code, :children)
14
+ Output = Struct.new(:code, :escape, :children)
15
+ Comment = Struct.new(:children)
16
+ Doctype = Struct.new(:type)
17
+ Embedded = Struct.new(:engine, :children, :attributes)
18
+
19
+ StaticAttribute = Struct.new(:name, :value)
20
+ QuotedAttribute = Struct.new(:name, :escape, :text)
21
+ CodeAttribute = Struct.new(:name, :escape, :code)
22
+ BooleanAttribute = Struct.new(:name)
23
+ Splat = Struct.new(:code)
24
+
25
+ def self.empty?(nodes)
26
+ nodes.all?(NEWLINE)
27
+ end
28
+
29
+ # Once compiled, a text block with no text leaves nothing behind: Slim then closes a void tag holding one.
30
+ def self.renders_nothing?(nodes)
31
+ nodes.all? { |node| node == NEWLINE || (node.is_a?(TextBlock) && renders_nothing?(node.children)) }
32
+ end
33
+ end
34
+ end