css_inline 0.22.0-aarch64-linux → 0.23.0-aarch64-linux

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3ec4e3b75bba2eec0ad80c084471afcab93e1a4d7613dfb7db6a88b42e79baf4
4
- data.tar.gz: 0d2748ac878c180d1e34af95cc4db6df78095959644d1beb3fb628192a2a7bcc
3
+ metadata.gz: 5afaeed32beccd785ec395587e277e5c52a2090770931a83527a060538591531
4
+ data.tar.gz: 92af0aa71a9a68c240619ee4e64865ae5ffee515b114041843323177d4497b60
5
5
  SHA512:
6
- metadata.gz: e529a5effd01d7b1cf4100fb6e66bc1e122aac92a11b23d9791bc939e25fb9a8915fb7068fbdc9aa663d1d90a305c7816c7b3e007e20669761390819273ab20a
7
- data.tar.gz: 7b88264915509b788615ece2a2a45e58b03a74a06b97522980763aada484776c8a05d242b1676707350101e0ffb8307ea78e630d35de920af1eb55f5cc16b5f3
6
+ metadata.gz: bd769ed0b9c12ccaa52ddb7e4ce4760d0b0127b35b81a3ee386aebcd3cbcfb0383d795ccc3165a2af52ffbec48aad9641e7acefb3d85303606b7a6809c472451
7
+ data.tar.gz: 2fb13ec52e3eb2d47872a1cdbc54d0d37cb68e55a47b26c543c4434944ed166d182d48fc91d658894b33c323d9e255165a55ccdf067222cdaf1af996dea579e7
data/README.md CHANGED
@@ -5,11 +5,10 @@
5
5
  [<img alt="codecov.io" src="https://img.shields.io/codecov/c/gh/Stranger6667/css-inline?logo=codecov&style=flat-square&token=tOzvV4kDY0" height="20">](https://app.codecov.io/github/Stranger6667/css-inline)
6
6
  [<img alt="gitter" src="https://img.shields.io/gitter/room/Stranger6667/css-inline?style=flat-square" height="20">](https://gitter.im/Stranger6667/css-inline)
7
7
 
8
- `css_inline` is a high-performance library for inlining CSS into HTML 'style' attributes.
8
+ `css_inline` moves CSS from `<style>` and `<link>` tags into HTML `style` attributes.
9
+ Use it to prepare HTML emails or to embed HTML into third-party web pages.
9
10
 
10
- This library is designed for scenarios such as preparing HTML emails or embedding HTML into third-party web pages.
11
-
12
- For instance, the library transforms HTML like this:
11
+ It turns this HTML:
13
12
 
14
13
  ```html
15
14
  <html>
@@ -28,36 +27,45 @@ into:
28
27
  <html>
29
28
  <head></head>
30
29
  <body>
31
- <h1 style="color:blue;">Big Text</h1>
30
+ <h1 style="color: blue;">Big Text</h1>
32
31
  </body>
33
32
  </html>
34
33
  ```
35
34
 
36
- - Uses reliable components from Mozilla's Servo project
35
+ - Parses and matches CSS with components from Mozilla's Servo project
37
36
  - Inlines CSS from `style` and `link` tags
38
37
  - Removes `style` and `link` tags
39
38
  - Resolves external stylesheets (including local files)
40
- - Optionally caches external stylesheets
39
+ - Caches external stylesheets (opt-in)
41
40
  - Can process multiple documents in parallel
42
41
  - Works on Linux, Windows, and macOS
43
42
  - Supports HTML5 & CSS3
44
- - Tested on Ruby 3.2, 3.3, and 3.4.
43
+ - Tested on Ruby 3.2, 3.3, 3.4, and 4.0
45
44
 
46
45
  ## Playground
47
46
 
48
- If you'd like to try `css-inline`, you can check the WebAssembly-powered [playground](https://css-inline.org/) to see the results instantly.
47
+ Try `css-inline` in the WebAssembly-powered [playground](https://css-inline.org/).
49
48
 
50
49
  ## Installation
51
50
 
52
- Add this line to your application's `Gemfile`:
51
+ Add this line to your application's `Gemfile` and run `bundle install`:
53
52
 
54
- ```
53
+ ```ruby
55
54
  gem 'css_inline'
56
55
  ```
57
56
 
57
+ Or install it directly:
58
+
59
+ ```sh
60
+ gem install css_inline
61
+ ```
62
+
63
+ RubyGems ships precompiled native gems for Ruby 3.2 to 4.0 on Linux (x86_64, aarch64, glibc and musl), macOS (x86_64, arm64) and Windows (x64 UCRT).
64
+ On other platforms, `gem install` builds the extension from source and needs a Rust toolchain.
65
+
58
66
  ## Usage
59
67
 
60
- To inline CSS in an HTML document:
68
+ Inline CSS in an HTML document:
61
69
 
62
70
  ```ruby
63
71
  require 'css_inline'
@@ -66,39 +74,39 @@ html = "<html><head><style>h1 { color:blue; }</style></head><body><h1>Big Text</
66
74
  inlined = CSSInline.inline(html)
67
75
 
68
76
  puts inlined
69
- # Outputs: "<html><head></head><body><h1 style=\"color:blue;\">Big Text</h1></body></html>"
77
+ # <html><head></head><body><h1 style="color: blue;">Big Text</h1></body></html>
70
78
  ```
71
79
 
72
- Note that `css-inline` automatically adds missing `html` and `body` tags, so the output is a valid HTML document.
80
+ `css-inline` adds missing `html`, `head` and `body` tags, so the output is a valid HTML document.
73
81
 
74
- Alternatively, you can inline CSS into an HTML fragment. Structural tags (`<html>`, `<head>`, `<body>`) are stripped from the output; only their contents are preserved. Use `CSSInline.inline` if you need to keep the full document structure:
82
+ To inline CSS into an HTML fragment, use `inline_fragment`. It strips structural tags (`<html>`, `<head>`, `<body>`) from the output and keeps their contents. Use `CSSInline.inline` to keep the full document structure:
75
83
 
76
84
  ```ruby
77
85
  require 'css_inline'
78
86
 
79
- fragment = """
80
- <main>
81
- <h1>Hello</h1>
82
- <section>
83
- <p>who am i</p>
84
- </section>
85
- </main>
86
- """
87
-
88
- css = """
89
- p {
90
- color: red;
91
- }
92
-
93
- h1 {
94
- color: blue;
95
- }
96
- """
87
+ fragment = <<~HTML
88
+ <main>
89
+ <h1>Hello</h1>
90
+ <section>
91
+ <p>who am i</p>
92
+ </section>
93
+ </main>
94
+ HTML
95
+
96
+ css = <<~CSS
97
+ p {
98
+ color: red;
99
+ }
100
+
101
+ h1 {
102
+ color: blue;
103
+ }
104
+ CSS
97
105
 
98
106
  inlined = CSSInline.inline_fragment(fragment, css)
99
107
 
100
108
  puts inlined
101
- # HTML becomes this:
109
+ # Output:
102
110
  # <main>
103
111
  # <h1 style="color: blue;">Hello</h1>
104
112
  # <section>
@@ -107,23 +115,27 @@ puts inlined
107
115
  # </main>
108
116
  ```
109
117
 
110
- When there is a need to inline multiple HTML documents simultaneously, `css_inline` offers `inline_many` and `inline_many_fragments` functions.
111
- This feature allows for concurrent processing of several inputs, significantly improving performance when dealing with a large number of documents.
118
+ To inline many documents in parallel, use `inline_many` and `inline_many_fragments`:
112
119
 
113
120
  ```ruby
114
121
  require 'css_inline'
115
122
 
116
123
  inlined = CSSInline.inline_many(["...", "..."])
124
+ inlined = CSSInline.inline_many_fragments(["<h1>...</h1>", "<p>...</p>"], ["h1 { color: blue; }", "p { color: red; }"])
117
125
  ```
118
126
 
119
- Under the hood, `inline_many`, spawns threads at the Rust layer to handle the parallel processing of inputs.
120
- This results in faster execution times compared to employing parallel processing techniques at the Ruby level.
127
+ `inline_many_fragments` pairs HTML and CSS by index.
128
+
129
+ **Warning**: pass arrays of equal length. If they differ, `inline_many_fragments` drops the extra items of the longer array without an error.
121
130
 
122
- **Note**: To fully benefit from `inline_many`, you should run your application on a multicore machine.
131
+ If one input fails, the whole call raises and returns no results.
132
+
133
+ Both functions process inputs on a Rust thread pool ([rayon](https://github.com/rayon-rs/rayon)), one thread per CPU core.
134
+ Ruby threads can't run this CPU-bound work in parallel because of the Global VM Lock, so `inline_many` gains over a Ruby loop only on a multicore machine.
123
135
 
124
136
  ## Configuration
125
137
 
126
- For customization options use the `CSSInliner` class:
138
+ Pass options as keyword arguments to `CSSInline::CSSInliner.new`:
127
139
 
128
140
  ```ruby
129
141
  require 'css_inline'
@@ -132,21 +144,26 @@ inliner = CSSInline::CSSInliner.new(keep_style_tags: true)
132
144
  inliner.inline("...")
133
145
  ```
134
146
 
135
- - `inline_style_tags`. Specifies whether to inline CSS from "style" tags. Default: `true`
136
- - `keep_style_tags`. Specifies whether to keep "style" tags after inlining. Default: `false`
137
- - `keep_link_tags`. Specifies whether to keep "link" tags after inlining. Default: `false`
138
- - `keep_at_rules`. Specifies whether to keep "at-rules" (starting with `@`) after inlining. Default: `false`
139
- - `minify_css`. Specifies whether to remove trailing semicolons and spaces between properties and values. Default: `false`
140
- - `base_url`. The base URL used to resolve relative URLs. If you'd like to load stylesheets from your filesystem, use the `file://` scheme. Default: `nil`
141
- - `load_remote_stylesheets`. Specifies whether remote stylesheets should be loaded. Default: `true`
142
- - `cache`. Specifies caching options for external stylesheets (for example, `StylesheetCache(size: 5)`). Default: `nil`
143
- - `extra_css`. Extra CSS to be inlined. Default: `nil`
144
- - `preallocate_node_capacity`. **Advanced**. Preallocates capacity for HTML nodes during parsing. This can improve performance when you have an estimate of the number of nodes in your HTML document. Default: `32`
145
- - `remove_inlined_selectors`. Specifies whether to remove selectors that were successfully inlined from `<style>` blocks. Default: `false`
146
- - `apply_width_attributes`. Specifies whether to add `width` HTML attributes from CSS `width` properties on supported elements (`table`, `td`, `th`, `img`). Default: `false`
147
- - `apply_height_attributes`. Specifies whether to add `height` HTML attributes from CSS `height` properties on supported elements (`table`, `td`, `th`, `img`). Default: `false`
148
-
149
- You can also skip CSS inlining for an HTML tag by adding the `data-css-inline="ignore"` attribute to it:
147
+ A `CSSInliner` instance has the same four methods as the module: `inline`, `inline_fragment`, `inline_many` and `inline_many_fragments`.
148
+ Reuse one instance to share its stylesheet cache across calls.
149
+ The module functions accept the same keyword arguments, for example `CSSInline.inline(html, keep_style_tags: true)`.
150
+
151
+ - `inline_style_tags`. Inline CSS from `style` tags. Default: `true`
152
+ - `keep_style_tags`. Keep `style` tags after inlining. Default: `false`
153
+ - `keep_link_tags`. Keep `link` tags after inlining. Default: `false`
154
+ - `keep_at_rules`. Keep at-rules (starting with `@`) after inlining. Default: `false`
155
+ - `minify_css`. Remove trailing semicolons and spaces between properties and values. Default: `false`
156
+ - `base_url`. Base URL for resolving relative URLs. Use the `file://` scheme to load stylesheets from the filesystem. Default: `nil`
157
+ - `load_remote_stylesheets`. Load stylesheets from `link` tags, over the network or from `file://` paths. Default: `true`
158
+ - `cache`. Cache for external stylesheets, for example `CSSInline::StylesheetCache.new(size: 5)`. Default: `nil`
159
+ - `extra_css`. Extra CSS to inline. Default: `nil`
160
+ - `preallocate_node_capacity`. **Advanced**. Number of HTML nodes to preallocate during parsing. Set it to your expected node count to avoid reallocations. Default: `32`
161
+ - `remove_inlined_selectors`. Remove inlined selectors from `<style>` blocks. Default: `false`
162
+ - `apply_width_attributes`. Add `width` HTML attributes from CSS `width` properties on `table`, `td`, `th` and `img`. Default: `false`
163
+ - `apply_height_attributes`. Add `height` HTML attributes from CSS `height` properties on `table`, `td`, `th` and `img`. Default: `false`
164
+ - `resolve_css_variables`. Replace `var()` references with the values of the custom properties they refer to and drop the `--*` declarations. Default: `false`
165
+
166
+ To skip CSS inlining for an HTML tag, add the `data-css-inline="ignore"` attribute to it:
150
167
 
151
168
  ```html
152
169
  <head>
@@ -158,7 +175,7 @@ You can also skip CSS inlining for an HTML tag by adding the `data-css-inline="i
158
175
  </body>
159
176
  ```
160
177
 
161
- The `data-css-inline="ignore"` attribute also allows you to skip `link` and `style` tags:
178
+ The same attribute on a `link` or `style` tag skips that stylesheet:
162
179
 
163
180
  ```html
164
181
  <head>
@@ -170,9 +187,9 @@ The `data-css-inline="ignore"` attribute also allows you to skip `link` and `sty
170
187
  </body>
171
188
  ```
172
189
 
173
- Alternatively, you may keep `style` from being removed by using the `data-css-inline="keep"` attribute.
174
- This is useful if you want to keep `@media` queries for responsive emails in separate `style` tags.
175
- Such tags will be kept in the resulting HTML even if the `keep_style_tags` option is set to `false`.
190
+ To keep a `style` tag in the output, add the `data-css-inline="keep"` attribute.
191
+ Use it to keep `@media` queries for responsive emails in separate `style` tags.
192
+ `css-inline` keeps such tags even when `keep_style_tags` is `false`.
176
193
 
177
194
  ```html
178
195
  <head>
@@ -184,14 +201,13 @@ Such tags will be kept in the resulting HTML even if the `keep_style_tags` optio
184
201
  </body>
185
202
  ```
186
203
 
187
- Another possibility is to set `keep_at_rules` option to `true`. At-rules cannot be inlined into HTML therefore they
188
- get removed by default. This is useful if you want to keep at-rules, e.g. `@media` queries for responsive emails in
189
- separate `style` tags but inline any styles which can be inlined.
190
- Such tags will be kept in the resulting HTML even if the `keep_style_tags` option is explicitly set to `false`.
204
+ Another way is the `keep_at_rules` option. At-rules can't go into `style` attributes, so `css-inline` removes them by default.
205
+ With `keep_at_rules: true`, it inlines regular rules and keeps at-rules, such as `@media` queries, in `style` tags.
206
+ It keeps these tags even when `keep_style_tags` is `false`.
191
207
 
192
208
  ```html
193
209
  <head>
194
- <!-- With keep_at_rules=true "color:blue" will get inlined into <h1> but @media will be kept in <style> -->
210
+ <!-- With keep_at_rules: true, "color:blue" will get inlined into <h1> but @media will be kept in <style> -->
195
211
  <style>h1 { color: blue; } @media (max-width: 600px) { h1 { font-size: 18px; } }</style>
196
212
  </head>
197
213
  <body>
@@ -199,12 +215,11 @@ Such tags will be kept in the resulting HTML even if the `keep_style_tags` optio
199
215
  </body>
200
216
  ```
201
217
 
202
- If you set the the `minify_css` option to `true`, the inlined styles will be minified by removing trailing semicolons
203
- and spaces between properties and values.
218
+ With `minify_css: true`, `css-inline` removes trailing semicolons and spaces between properties and values in inlined styles.
204
219
 
205
220
  ```html
206
221
  <head>
207
- <!-- With minify_css=true, the <h1> will have `style="color:blue;font-weight:bold"` -->
222
+ <!-- With minify_css: true, the <h1> will have `style="color:blue;font-weight:bold"` -->
208
223
  <style>h1 { color: blue; font-weight: bold; }</style>
209
224
  </head>
210
225
  <body>
@@ -212,17 +227,20 @@ and spaces between properties and values.
212
227
  </body>
213
228
  ```
214
229
 
215
- If you'd like to load stylesheets from your filesystem, use the `file://` scheme:
230
+ To load stylesheets from the filesystem, use the `file://` scheme.
231
+ `css-inline` treats a `file://` URL without a third slash, such as `file://styles/email/`, as a path relative to the current working directory.
232
+ Standard URL parsers read `styles` there as a host, so this form is specific to `css-inline`.
233
+ For an absolute path, use three slashes: `file:///path/to/styles/`.
216
234
 
217
235
  ```ruby
218
236
  require 'css_inline'
219
237
 
220
- # styles/email is relative to the current directory
238
+ # Loads stylesheets from ./styles/email/
221
239
  inliner = CSSInline::CSSInliner.new(base_url: "file://styles/email/")
222
240
  inliner.inline("...")
223
241
  ```
224
242
 
225
- You can also cache external stylesheets to avoid excessive network requests:
243
+ To avoid repeated network requests, cache external stylesheets:
226
244
 
227
245
  ```ruby
228
246
  require 'css_inline'
@@ -233,32 +251,45 @@ inliner = CSSInline::CSSInliner.new(
233
251
  inliner.inline("...")
234
252
  ```
235
253
 
236
- Caching is disabled by default.
254
+ The cache covers every `link` stylesheet, `file://` included. `size` is the number of stylesheets to keep (default: `8`). When the cache is full, it evicts the least recently used stylesheet.
255
+ Caching is off by default.
237
256
 
238
- ## Performance
257
+ ## Errors
239
258
 
240
- This library uses components from Mozilla's Servo project for CSS parsing and matching.
241
- Performance benchmarks show 50-100x faster execution than `roadie` and `premailer`.
259
+ All functions raise `ArgumentError` when they can't load a stylesheet (missing file, network error), can't parse one, or get an invalid `base_url`:
242
260
 
243
- The table below shows benchmark results comparing `css_inline`, `roadie`, and `premailer` on typical HTML documents:
261
+ ```ruby
262
+ require 'css_inline'
244
263
 
245
- | | Size | `css_inline 0.19.0` | `roadie 5.2.1` | `premailer 1.21.0` |
264
+ begin
265
+ CSSInline.inline('<link rel="stylesheet" href="missing.css"><h1>Hi</h1>')
266
+ rescue ArgumentError => e
267
+ puts e.message
268
+ # Missing stylesheet file: missing.css
269
+ end
270
+ ```
271
+
272
+ ## Performance
273
+
274
+ `css_inline` runs 8.1x to 354x faster than `roadie` and 57x to 123x faster than `premailer` on these documents:
275
+
276
+ | | Size | `css_inline 0.22.0` | `roadie 5.2.1` | `premailer 1.27.0` |
246
277
  |-------------------|---------|---------------------|-------------------------|-------------------------|
247
- | Basic usage | 230 B | 6.07 µs | 173.50 µs (**28.60x**) | 345.30 µs (**56.91x**) |
248
- | Realistic email 1 | 8.58 KB | 91.23 µs | 713.40 µs (**7.82x**) | 6.80 ms (**74.53x**) |
249
- | Realistic email 2 | 4.3 KB | 57.56 µs | 1.99 ms (**34.56x**) | ERROR |
250
- | GitHub Page | 1.81 MB | 21.61 ms | 8.20 s (**379.45x**) | 2.40 s (**111.06x**) |
278
+ | Basic usage | 230 B | 5.84 µs | 168.88 µs (**28.92x**) | 331.07 µs (**56.69x**) |
279
+ | Realistic email 1 | 8.58 KB | 87.66 µs | 713.78 µs (**8.14x**) | 6.95 ms (**79.28x**) |
280
+ | Realistic email 2 | 4.30 KB | 50.45 µs | 1.98 ms (**39.25x**) | ERROR |
281
+ | GitHub Page | 1.81 MB | 19.01 ms | 6.73 s (**354.02x**) | 2.34 s (**123.09x**) |
251
282
 
252
- Please refer to the `test/bench.rb` file to review the benchmark code.
253
- The results displayed above were measured using stable `rustc 1.91` on Ruby `3.4.7`.
283
+ `premailer` fails on "Realistic email 2" with `ArgumentError: Cannot parse 0 calc((100% - 500px) / 2)`.
254
284
 
255
- ## Further reading
285
+ Inputs come from [`benchmarks/benchmarks.json`](https://github.com/Stranger6667/css-inline/blob/master/benchmarks/benchmarks.json): Basic usage is `simple`, Realistic email 1 and 2 are `big_email_1` and `big_email_2`, GitHub Page is `big_page`.
286
+ The benchmark code is in [`test/bench.rb`](https://github.com/Stranger6667/css-inline/blob/master/crates/css-inline-ruby/test/bench.rb) and uses [`benchmark-ips`](https://github.com/evanphx/benchmark-ips) (5 s per case; `roadie` completes one run on the GitHub page in that time).
287
+ We measured these results with stable `rustc 1.99` on Ruby `3.4.8`, Ryzen 9 9950X.
256
288
 
257
- If you want to know how this library was created & how it works internally, you could take a look at these articles:
289
+ ## Further reading
258
290
 
259
- - [Rust crate](https://dygalo.dev/blog/rust-for-a-pythonista-2/)
260
- - [Python bindings](https://dygalo.dev/blog/rust-for-a-pythonista-3/)
291
+ - [How the Rust crate works](https://dygalo.dev/blog/rust-for-a-pythonista-2/)
261
292
 
262
293
  ## License
263
294
 
264
- This project is licensed under the terms of the [MIT license](https://opensource.org/licenses/MIT).
295
+ [MIT license](https://opensource.org/licenses/MIT).
Binary file
Binary file
Binary file
Binary file