haml2html 0.1.3 → 0.1.4
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 +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +1 -1
- data/lib/haml2html/converter.rb +146 -21
- data/lib/haml2html/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 14f09bc19dfb59cd98fd339e28b7a9a82031ff68a6f9bcb1f09bea25ad5eef24
|
|
4
|
+
data.tar.gz: 2dd302143f309d861781c904673a986c9525df51538538212194c148eb629929
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f64fb147af2fe01e270f30f5ada9c75776c3434cbd8cf3c724b5f6893edee8ec53462288b3349c0350bd3a90a0e66b5d1f16950849e1671da524abedebe557be
|
|
7
|
+
data.tar.gz: '04956657bb059627298a8e38502386229a2bdc8ca05f2af5687cf37783b4548ddf52562169c0fab171f1542795d32a1a9159d310cee821234d131b8be7230233'
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
|
@@ -79,7 +79,7 @@ end
|
|
|
79
79
|
- Ruby output and control flow: `=`, `!=`, `- if`, `- each do`, and similar blocks.
|
|
80
80
|
- Public comments and silent comments.
|
|
81
81
|
- `:plain`, `:escaped`, `:javascript`, `:css`, `:erb`, and `:ruby` filters.
|
|
82
|
-
-
|
|
82
|
+
- Literal dynamic Haml attribute hashes, including simple `class`, `data`, `aria`, and boolean attributes.
|
|
83
83
|
|
|
84
84
|
## Limitations
|
|
85
85
|
|
data/lib/haml2html/converter.rb
CHANGED
|
@@ -9,6 +9,12 @@ require_relative "diagnostic"
|
|
|
9
9
|
module Haml2html
|
|
10
10
|
class Converter
|
|
11
11
|
VOID_TAGS = %w[area base br col embed hr img input link meta param source track wbr].freeze
|
|
12
|
+
BOOLEAN_ATTRIBUTES = %w[
|
|
13
|
+
allowfullscreen async autofocus autoplay checked compact controls declare default defaultchecked defaultmuted
|
|
14
|
+
defaultselected defer disabled enabled formnovalidate hidden indeterminate inert ismap itemscope loop multiple
|
|
15
|
+
muted nohref nomodule noresize noshade novalidate nowrap open pauseonexit playsinline readonly required
|
|
16
|
+
reversed scoped seamless selected sortable truespeed typemustmatch visible
|
|
17
|
+
].freeze
|
|
12
18
|
SUPPORTED_FILTERS = %w[plain escaped javascript css erb ruby].freeze
|
|
13
19
|
|
|
14
20
|
attr_reader :diagnostics
|
|
@@ -106,12 +112,14 @@ module Haml2html
|
|
|
106
112
|
dynamic = dynamic_attributes_expression(value[:dynamic_attributes])
|
|
107
113
|
return static_attributes(attrs) unless dynamic
|
|
108
114
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
115
|
+
simple_attrs = simple_dynamic_attributes(dynamic)
|
|
116
|
+
unless simple_attrs
|
|
117
|
+
unsupported(node, "dynamic attributes", "only literal dynamic attribute hashes can be converted safely")
|
|
118
|
+
return static_attributes(attrs)
|
|
112
119
|
end
|
|
113
120
|
|
|
114
|
-
"
|
|
121
|
+
dynamic_class = simple_attrs.delete("class")
|
|
122
|
+
"#{static_attributes(attrs, dynamic_class: dynamic_class&.then { |attr| dynamic_attribute_value(attr) })}#{simple_attrs.values.map { |attr| dynamic_attribute(attr) }.join}"
|
|
115
123
|
end
|
|
116
124
|
|
|
117
125
|
def emit_script(node, indent)
|
|
@@ -195,12 +203,15 @@ module Haml2html
|
|
|
195
203
|
end.join
|
|
196
204
|
end
|
|
197
205
|
|
|
198
|
-
def
|
|
199
|
-
|
|
200
|
-
|
|
206
|
+
def dynamic_attribute(attr)
|
|
207
|
+
name = attr.fetch(:name)
|
|
208
|
+
if BOOLEAN_ATTRIBUTES.include?(name)
|
|
209
|
+
return attr.fetch(:value) ? " #{name}" : "" unless attr.fetch(:dynamic)
|
|
210
|
+
|
|
211
|
+
return %(<%= (#{attr.fetch(:value)}) ? " #{name}" : "" %>)
|
|
212
|
+
end
|
|
201
213
|
|
|
202
|
-
|
|
203
|
-
%( #{name}="#{value}")
|
|
214
|
+
%( #{name}="#{dynamic_attribute_value(attr)}")
|
|
204
215
|
end
|
|
205
216
|
|
|
206
217
|
def simple_dynamic_attributes(dynamic)
|
|
@@ -212,33 +223,147 @@ module Haml2html
|
|
|
212
223
|
return nil unless associations.is_a?(Array)
|
|
213
224
|
|
|
214
225
|
associations.each_with_object({}) do |association, attrs|
|
|
215
|
-
|
|
226
|
+
name = dynamic_attribute_name(association)
|
|
227
|
+
return nil unless name
|
|
228
|
+
|
|
229
|
+
if name == "data"
|
|
230
|
+
data_attrs = simple_prefixed_attributes("data", association[2], dynamic)
|
|
231
|
+
return nil unless data_attrs
|
|
232
|
+
|
|
233
|
+
attrs.merge!(data_attrs)
|
|
234
|
+
elsif name == "aria"
|
|
235
|
+
aria_attrs = simple_prefixed_attributes("aria", association[2], dynamic)
|
|
236
|
+
return nil unless aria_attrs
|
|
237
|
+
|
|
238
|
+
attrs.merge!(aria_attrs)
|
|
239
|
+
else
|
|
240
|
+
value = simple_dynamic_attribute_value(name, association[2], dynamic)
|
|
241
|
+
return nil unless value
|
|
242
|
+
|
|
243
|
+
attrs[name] = value.merge(name: name)
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
end
|
|
216
247
|
|
|
217
|
-
|
|
218
|
-
|
|
248
|
+
def dynamic_attribute_name(association)
|
|
249
|
+
return nil unless association&.first == :assoc_new
|
|
219
250
|
|
|
220
|
-
|
|
251
|
+
label = association[1]
|
|
252
|
+
return nil unless label&.first == :@label
|
|
253
|
+
|
|
254
|
+
label[1].delete_suffix(":")
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
def simple_prefixed_attributes(prefix, node, source)
|
|
258
|
+
return nil unless node&.first == :hash
|
|
259
|
+
|
|
260
|
+
associations = node.dig(1, 1)
|
|
261
|
+
return nil unless associations.is_a?(Array)
|
|
262
|
+
|
|
263
|
+
associations.each_with_object({}) do |association, attrs|
|
|
264
|
+
name = dynamic_attribute_name(association)
|
|
265
|
+
return nil unless name
|
|
266
|
+
|
|
267
|
+
value = simple_dynamic_attribute_value(name, association[2], source)
|
|
221
268
|
return nil unless value
|
|
269
|
+
next if !value.fetch(:dynamic) && [false, nil].include?(value.fetch(:value))
|
|
222
270
|
|
|
223
|
-
|
|
271
|
+
attr_name = "#{prefix}-#{name.tr("_", "-")}"
|
|
272
|
+
attrs[attr_name] = value.merge(name: attr_name)
|
|
224
273
|
end
|
|
225
274
|
end
|
|
226
275
|
|
|
227
|
-
def simple_dynamic_attribute_value(node)
|
|
276
|
+
def simple_dynamic_attribute_value(name, node, source)
|
|
228
277
|
case node&.first
|
|
229
278
|
when :string_literal
|
|
230
|
-
|
|
279
|
+
string = string_literal_content(node)
|
|
280
|
+
return nil unless string
|
|
281
|
+
|
|
282
|
+
{ dynamic: false, value: string }
|
|
283
|
+
when :symbol_literal
|
|
284
|
+
{ dynamic: false, value: symbol_literal_content(node) }
|
|
285
|
+
when :var_ref
|
|
286
|
+
if (keyword = node.dig(1, 1)) && %w[true false nil].include?(keyword)
|
|
287
|
+
return { dynamic: false, value: literal_keyword_value(keyword) }
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
expression = ruby_expression(node, source)
|
|
291
|
+
expression && { dynamic: true, value: expression }
|
|
231
292
|
when :vcall
|
|
232
|
-
|
|
233
|
-
|
|
293
|
+
expression = ruby_expression(node, source)
|
|
294
|
+
expression && { dynamic: true, value: expression }
|
|
295
|
+
when :array
|
|
296
|
+
return nil unless name == "class"
|
|
297
|
+
|
|
298
|
+
expression = class_names_expression(node, source)
|
|
299
|
+
expression && { dynamic: true, value: expression }
|
|
300
|
+
else
|
|
301
|
+
expression = ruby_expression(node, source)
|
|
302
|
+
expression && { dynamic: true, value: expression }
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def dynamic_attribute_value(attr)
|
|
307
|
+
value = attr.fetch(:value)
|
|
308
|
+
attr.fetch(:dynamic) ? "<%= #{value} %>" : escape_attr(value.to_s)
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
def class_names_expression(node, source)
|
|
312
|
+
values = node[1]
|
|
313
|
+
return "class_names" if values.nil? || values.empty?
|
|
314
|
+
|
|
315
|
+
args = values.map { |value| ruby_expression(value, source) }
|
|
316
|
+
return nil if args.any?(&:nil?)
|
|
317
|
+
|
|
318
|
+
"class_names(#{args.join(", ")})"
|
|
319
|
+
end
|
|
234
320
|
|
|
235
|
-
|
|
321
|
+
def ruby_expression(node, source)
|
|
322
|
+
case node&.first
|
|
323
|
+
when :string_literal
|
|
324
|
+
string = string_literal_content(node)
|
|
325
|
+
string&.inspect
|
|
326
|
+
when :symbol_literal
|
|
327
|
+
":#{symbol_literal_content(node)}"
|
|
328
|
+
when :var_ref, :vcall
|
|
329
|
+
node.dig(1, 1)
|
|
330
|
+
when :unary
|
|
331
|
+
expression = ruby_expression(node[2], source)
|
|
332
|
+
expression && "#{node[1]}#{expression}"
|
|
333
|
+
when :call
|
|
334
|
+
receiver = ruby_expression(node[1], source)
|
|
335
|
+
method = node.dig(3, 1)
|
|
336
|
+
receiver && method && "#{receiver}.#{method}"
|
|
337
|
+
when :method_add_arg
|
|
338
|
+
ruby_expression(node[1], source) if node[2]&.empty?
|
|
339
|
+
when :fcall
|
|
340
|
+
node.dig(1, 1)
|
|
236
341
|
end
|
|
237
342
|
end
|
|
238
343
|
|
|
239
344
|
def string_literal_content(node)
|
|
240
|
-
content = node
|
|
241
|
-
content
|
|
345
|
+
content = node[1]
|
|
346
|
+
return nil unless content&.first == :string_content
|
|
347
|
+
|
|
348
|
+
parts = content[1..] || []
|
|
349
|
+
return nil unless parts.all? { |part| part.is_a?(Array) && part.first == :@tstring_content }
|
|
350
|
+
|
|
351
|
+
parts.map { |part| part[1] }.join
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
def symbol_literal_content(node)
|
|
355
|
+
node.dig(1, 1, 1).to_s
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
def literal_keyword_value(keyword)
|
|
359
|
+
case keyword
|
|
360
|
+
when "true"
|
|
361
|
+
true
|
|
362
|
+
when "false"
|
|
363
|
+
false
|
|
364
|
+
when "nil"
|
|
365
|
+
nil
|
|
366
|
+
end
|
|
242
367
|
end
|
|
243
368
|
|
|
244
369
|
def dynamic_attributes_expression(dynamic)
|
data/lib/haml2html/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: haml2html
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kyle
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-05-
|
|
11
|
+
date: 2026-05-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: haml
|