theo-rails 0.4.9 → 0.5.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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/theo-rails/theo.rb +62 -14
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a354561a6eaaa54fdcfe0b6c40f5c3e5a2fe183748beaa59eeec65cc268b2a13
4
- data.tar.gz: c7e7f95887c0529086469d5f659fc7626bd9efc4e5cda1f1a3cd7eb31c959e34
3
+ metadata.gz: 4484f097ca557a4007972199d45de0bbb90fcb0a92af7a2104c77594c06b2a2e
4
+ data.tar.gz: 03ed89bdc2f88aa202e78c74100d2059e9eb6169a32aa44cce28577ef81b9367
5
5
  SHA512:
6
- metadata.gz: cc7258020cf8eb358bb9c2a4427ba099ba24b320e57ffb6fb101790d866bbee67bed477a7c909f48df73edf269924e23ff99ecc1cb98840d05288ec6b22a5d96
7
- data.tar.gz: a5028cf66693c1a327f31ea4f192e99c36cfa1b6928db4372225c6e3130c3c7baa97dc43d04d1eb35e1b3a7342b909874d0fe9988e1bdc924840fa3683f63cf6
6
+ metadata.gz: 9ebc2bbe2787fa431f803aacca5634330d234a9d66eb4ed2bdb74cde7e721acf4e032dba170282bc73c5296bf88013604b0ef6f30cc2a5604373a1ab478645ef
7
+ data.tar.gz: 98fc003281e01a7fddefbf1f807983b826337a0a6a067d7b4e5452a16b48519b15e62bdf535234f2e15bd87cd7a48a97e3877058067a5a7d6bf489d2d39d94f7
@@ -1,12 +1,23 @@
1
1
  module Theo
2
2
  module Rails
3
- ATTRIBUTE_NAME = /(?<name>[\w:@_][-\w:@_]*)/
3
+ def self.attribute_value(name = 'value')
4
+ /(?:(?:"(?<#{name}>[^"]*)")|(?:'(?<#{name}>[^']*)'))/.source
5
+ end
6
+
7
+ ATTRIBUTE_NAME = /(?<name>[\w:@_%][-\w:@_]*)/
4
8
  ATTRIBUTE_VALUE = /(?:(?:"(?<value>[^"]*)")|(?:'(?<value>[^']*)'))/
5
- ATTRIBUTE = /(?:(?:#{ATTRIBUTE_NAME.source}\s*=\s*#{ATTRIBUTE_VALUE.source})|#{ATTRIBUTE_NAME.source})/
6
- DYNAMIC_ATTRIBUTE = /(?:(?:#{ATTRIBUTE_NAME.source}\s*%=\s*#{ATTRIBUTE_VALUE.source})|(?:#{ATTRIBUTE_NAME.source}%))/
9
+ ATTRIBUTE = /(?:(?:#{ATTRIBUTE_NAME.source}\s*=\s*#{attribute_value})|#{ATTRIBUTE_NAME.source})/
10
+ DYNAMIC_ATTRIBUTE = /(?:(?:#{ATTRIBUTE_NAME.source}\s*%=\s*#{attribute_value('dynvalue')})|(?:#{ATTRIBUTE_NAME.source}%))/
7
11
  RESERVED_ATTRIBUTE_NAME = %w[alias and begin break case class def do else elsif end ensure false for if in module next nil not or redo rescue retry return self super then true undef unless until when while yield].to_set
12
+ CLASS_ATTRIBUTE=/(?:\s+class\s*=\s*#{attribute_value})/
13
+ STYLE_ATTRIBUTE=/(?:\s+style\s*=\s*#{attribute_value})/
8
14
  ATTRIBUTES = /(?<attrs>(?:\s+#{ATTRIBUTE.source})*)/
9
- LITERAL_ATTRIBUTES = %i[path as yields collection].freeze
15
+ ATTRIBUTES_INCLUDING_DYNAMIC = /(?<attrs>(?:\s+#{ATTRIBUTE.source}|#{DYNAMIC_ATTRIBUTE.source})*)/
16
+ TAG_WITH_DYNAMIC_ATTRIBUTE = /(?:<\w+#{ATTRIBUTES_INCLUDING_DYNAMIC.source}\s+#{DYNAMIC_ATTRIBUTE.source}#{ATTRIBUTES_INCLUDING_DYNAMIC.source}\s*\/?>)/m
17
+ SPECIAL_ATTRIBUTES = %i[%path %as %yields %collection %if].freeze
18
+ VOID_TAGS=%i[area base br col embed hr img input link meta source track wbr]
19
+ IF_SPECIAL_ATTRIBUTE = /(?<special> %if\s*=\s*#{attribute_value('specvalue')})/
20
+ TAG_WITH_IF_SPECIAL_ATTRIBUTE = /(?:<(?<tag>\w+)#{ATTRIBUTES.source}\s*#{IF_SPECIAL_ATTRIBUTE.source}#{ATTRIBUTES.source}\s*>.*?<\/\k<tag>>)|(?:<(?<tag>\w+)#{ATTRIBUTES.source}\s*#{IF_SPECIAL_ATTRIBUTE.source}#{ATTRIBUTES.source}\s*\/>)|(?:<(?<tag>#{VOID_TAGS.join('|')})#{ATTRIBUTES.source}\s*#{IF_SPECIAL_ATTRIBUTE.source}#{ATTRIBUTES.source}\s*>)/m
10
21
  PARTIAL_TAG = /(?:(?<partial>[A-Z]\w+)|(?<partial>_[\w-]+))/
11
22
  PARTIAL = /(?:<#{PARTIAL_TAG.source}#{ATTRIBUTES.source}\s*>(?<content>.*?)<\/\k<partial>>)|(?:<#{PARTIAL_TAG.source}#{ATTRIBUTES.source}\s*\/>)/m
12
23
  DYNAMIC_EXPRESSION = /^<%=([^%]*)%>$/
@@ -14,15 +25,52 @@ module Theo
14
25
  class Theo
15
26
  def process(source)
16
27
  # Attributes
17
- source = source.gsub(DYNAMIC_ATTRIBUTE) do |_|
28
+ source = source.gsub(TAG_WITH_DYNAMIC_ATTRIBUTE) do |_|
18
29
  match = Regexp.last_match
19
30
 
20
- name = match[:name]
31
+ tag = match[0]
32
+
33
+ remove_attributes = []
34
+
35
+ tag = tag.gsub(DYNAMIC_ATTRIBUTE) do |_|
36
+ match = Regexp.last_match
37
+
38
+ name = match[:name]
39
+
40
+ # See https://island94.org/2024/06/rails-strict-locals-local_assigns-and-reserved-keywords for more info
41
+ value = match[:dynvalue] || (RESERVED_ATTRIBUTE_NAME.include?(name) ? "binding.local_variable_get('#{name}')" : name)
42
+
43
+ if name == 'class'
44
+ class_attribute = CLASS_ATTRIBUTE.match(tag)
45
+
46
+ if class_attribute
47
+ remove_attributes += [class_attribute[0]]
48
+ next "#{name}=\"<%= (#{value}).to_s + ' #{class_attribute[:value]}' %>\""
49
+ end
50
+ end
51
+
52
+ if name == 'style'
53
+ style_attribute = STYLE_ATTRIBUTE.match(tag)
54
+
55
+ if style_attribute
56
+ remove_attributes += [style_attribute[0]]
57
+ next "#{name}=\"<%= (#{value}).to_s + '; #{style_attribute[:value]}' %>\""
58
+ end
59
+ end
60
+
61
+ "#{name}=\"<%= #{value} %>\""
62
+ end
21
63
 
22
- # See https://island94.org/2024/06/rails-strict-locals-local_assigns-and-reserved-keywords for more info
23
- value = match[:value] || (RESERVED_ATTRIBUTE_NAME.include?(name) ? "binding.local_variable_get('#{name}')" : name)
64
+ remove_attributes.each { |remove_attribute| tag = tag.sub(remove_attribute, '') }
65
+
66
+ tag
67
+ end
68
+
69
+ # Specials
70
+ source = source.gsub(TAG_WITH_IF_SPECIAL_ATTRIBUTE) do |_|
71
+ match = Regexp.last_match
24
72
 
25
- "#{name}=\"<%= #{value} %>\""
73
+ "<% if #{match[:specvalue]} %>\n#{match[0].sub(match[:special], '')}\n<% end %>" \
26
74
  end
27
75
 
28
76
  # Partials
@@ -36,12 +84,12 @@ module Theo
36
84
 
37
85
  attributes = process_attributes(attributes)
38
86
 
39
- path = attributes.delete(:path)
87
+ path = attributes.delete(:'%path')
40
88
 
41
- collection = attributes.delete(:collection)
42
- as = attributes.delete(:as)
89
+ collection = attributes.delete(:'%collection')
90
+ as = attributes.delete(:'%as')
43
91
 
44
- yields = attributes.delete(:yields)
92
+ yields = attributes.delete(:'%yields')
45
93
  yields = " |#{yields}|" if yields
46
94
 
47
95
  locals = attributes.empty? ? '' : attributes.map { |k, v| "'#{k}': #{v}" }.join(', ')
@@ -86,7 +134,7 @@ module Theo
86
134
  .map do |attr|
87
135
  name = attr[:name].to_sym
88
136
  value = attr[:value]
89
- value = attribute(value) unless LITERAL_ATTRIBUTES.include?(name)
137
+ value = attribute(value) unless SPECIAL_ATTRIBUTES.include?(name)
90
138
  [name, value]
91
139
  end
92
140
  .to_h
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: theo-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.9
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jarek Lipski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-02-22 00:00:00.000000000 Z
11
+ date: 2025-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport