8
8
9
9
class ComponentLexer extends Lexer
10
10
{
11
- const ATTRIBUTES_REGEX = '(?<attributes>(?:\s+[\w\-:.@]+(=(?: \\\"[^ \\\"]* \\\"| \'[^ \']* \'|[^ \'\\\"=<>]+))?)*\s*) ' ;
12
- const COMPONENTS_REGEX = [
13
- 'open_tags ' => '/<\s*([A-Z][\w\-\:\.]+)\s* ' . self ::ATTRIBUTES_REGEX . '(\s?)+>/ ' ,
14
- 'close_tags ' => '/<\/\s*([A-Z][\w\-\:\.]+)\s*>/ ' ,
15
- 'self_close_tags ' => '/<\s*([A-Z][\w\-\:\.]+)\s* ' . self ::ATTRIBUTES_REGEX . '(\s?)+\/>/ ' ,
16
- ];
11
+ public const ATTRIBUTES_REGEX = '(?<attributes>(?:\s+[\w\-:.@]+(=(?: \\\"[^ \\\"]* \\\"| \'[^ \']* \'|[^ \'\\\"=<>]+))?)*\s*) ' ;
12
+ public const OPEN_TAGS_REGEX = '/<\s*x-(?<name>([[\w\-\:\.]+))\s* ' .self ::ATTRIBUTES_REGEX .'(\s?)+>/ ' ;
13
+ public const CLOSE_TAGS_REGEX = '/<\/\s*x-([\w\-\:\.]+)\s*>/ ' ;
14
+ public const SELF_CLOSE_TAGS_REGEX = '/<\s*x-(?<name>([\w\-\:\.]+))\s* ' .self ::ATTRIBUTES_REGEX .'(\s?)+\/>/ ' ;
15
+ public const BLOCK_TAGS_OPEN = '/<\s*x-block\s+name=("| \')(?<name>([\w\-\:\.]+))("| \')\s*>/ ' ;
16
+ public const BLOCK_TAGS_CLOSE = '/<\s*\/\s*x-block\s*>/ ' ;
17
+ public const ATTRIBUTE_BAG_REGEX = '/(?:^|\s+)\{\{\s*(attributes(?:.+?(?<!\s))?)\s*\}\}/x ' ;
18
+ public const ATTRIBUTE_KEY_VALUE_REGEX = '/(?<attribute>[\w\-:.@]+)(=(?<value>(\"[^\"]+\"| \\\'[^ \\\']+ \\\'|[^\s>]+)))?/x ' ;
17
19
18
20
public function tokenize (Source $ source ): TokenStream
19
21
{
@@ -30,6 +32,8 @@ public function tokenize(Source $source): TokenStream
30
32
31
33
private function preparsed (string $ value )
32
34
{
35
+ $ value = $ this ->lexBlockTags ($ value );
36
+ $ value = $ this ->lexBlockTagsClose ($ value );
33
37
$ value = $ this ->lexSelfCloseTag ($ value );
34
38
$ value = $ this ->lexOpeningTags ($ value );
35
39
$ value = $ this ->lexClosingTag ($ value );
@@ -40,81 +44,83 @@ private function preparsed(string $value)
40
44
private function lexOpeningTags (string $ value )
41
45
{
42
46
return preg_replace_callback (
43
- self ::COMPONENTS_REGEX [ ' open_tags ' ] ,
47
+ self ::OPEN_TAGS_REGEX ,
44
48
function (array $ matches ) {
45
- $ name = lcfirst ( $ matches [1 ]) ;
49
+ $ name = $ matches [' name ' ] ;
46
50
$ attributes = $ this ->getAttributesFromAttributeString ($ matches ['attributes ' ]);
47
51
48
- return " {% component " . $ name . " with " . $ attributes . " %} " ;
52
+ return ' {% component ' . $ name. ' with ' . $ attributes. ' %} ' ;
49
53
},
50
54
$ value
51
-
52
55
);
53
56
}
54
57
55
58
private function lexClosingTag (string $ value )
56
59
{
57
- return preg_replace (self ::COMPONENTS_REGEX [ ' close_tags ' ] , '{% endcomponent %} ' , $ value );
60
+ return preg_replace (self ::CLOSE_TAGS_REGEX , '{% endcomponent %} ' , $ value );
58
61
}
59
62
60
63
private function lexSelfCloseTag (string $ value )
61
64
{
62
65
return preg_replace_callback (
63
- self ::COMPONENTS_REGEX [ ' self_close_tags ' ] ,
66
+ self ::SELF_CLOSE_TAGS_REGEX ,
64
67
function (array $ matches ) {
65
- $ name = lcfirst ( $ matches [1 ]) ;
68
+ $ name = $ matches [' name ' ] ;
66
69
$ attributes = $ this ->getAttributesFromAttributeString ($ matches ['attributes ' ]);
67
70
68
- return "{{ component(' " . $ name . "', " . $ attributes . ") }} " ;
71
+ return "{{ component(' " .$ name ."', " .$ attributes .') }} ' ;
72
+ },
73
+ $ value
74
+ );
75
+ }
76
+
77
+ private function lexBlockTags (string $ value )
78
+ {
79
+ return preg_replace_callback (
80
+ self ::BLOCK_TAGS_OPEN ,
81
+ function (array $ matches ) {
82
+ $ name = $ matches ['name ' ];
83
+
84
+ return '{% block ' .$ name .' %} ' ;
69
85
},
70
86
$ value
71
87
);
72
88
}
73
89
90
+ private function lexBlockTagsClose (string $ value )
91
+ {
92
+ return preg_replace (
93
+ self ::BLOCK_TAGS_CLOSE ,
94
+ '{% endblock %} ' ,
95
+ $ value
96
+ );
97
+ }
98
+
74
99
protected function getAttributesFromAttributeString (string $ attributeString )
75
100
{
76
101
$ attributeString = $ this ->parseAttributeBag ($ attributeString );
77
102
78
- $ pattern = '/
79
- (?<attribute>[\w\-:.@]+)
80
- (
81
- =
82
- (?<value>
83
- (
84
- \"[^\"]+\"
85
- |
86
- \\\'[^ \\\']+ \\\'
87
- |
88
- [^\s>]+
89
- )
90
- )
91
- )?
92
- /x ' ;
93
-
94
- if (! preg_match_all ($ pattern , $ attributeString , $ matches , PREG_SET_ORDER )) {
103
+ if (!preg_match_all (self ::ATTRIBUTE_KEY_VALUE_REGEX , $ attributeString , $ matches , \PREG_SET_ORDER )) {
95
104
return '{} ' ;
96
105
}
97
106
98
-
99
107
$ attributes = [];
100
-
101
108
foreach ($ matches as $ match ) {
102
109
$ attribute = $ match ['attribute ' ];
103
110
$ value = $ match ['value ' ] ?? null ;
104
111
105
- if (is_null ( $ value) ) {
112
+ if (null === $ value ) {
106
113
$ value = 'true ' ;
107
114
}
108
115
109
-
110
- if (strpos ($ attribute , ": " ) === 0 ) {
111
- $ attribute = str_replace (": " , "" , $ attribute );
116
+ if (str_starts_with ($ attribute , ': ' )) {
117
+ $ attribute = str_replace (': ' , '' , $ attribute );
112
118
$ value = $ this ->stripQuotes ($ value );
113
119
}
114
120
115
121
$ valueWithoutQuotes = $ this ->stripQuotes ($ value );
116
122
117
- if (( strpos ( $ valueWithoutQuotes , '{{ ' ) === 0 ) && (strpos ($ valueWithoutQuotes , '}} ' ) === strlen ($ valueWithoutQuotes ) - 2 )) {
123
+ if (str_starts_with ( $ valueWithoutQuotes , '{{ ' ) && (strpos ($ valueWithoutQuotes , '}} ' ) === \ strlen ($ valueWithoutQuotes ) - 2 )) {
118
124
$ value = substr ($ valueWithoutQuotes , 2 , -2 );
119
125
} else {
120
126
$ value = $ value ;
@@ -123,29 +129,24 @@ protected function getAttributesFromAttributeString(string $attributeString)
123
129
$ attributes [$ attribute ] = $ value ;
124
130
}
125
131
126
- $ out = " { " ;
132
+ $ out = ' { ' ;
127
133
foreach ($ attributes as $ key => $ value ) {
128
134
$ key = "' $ key' " ;
129
135
$ out .= "$ key: $ value, " ;
130
- };
136
+ }
131
137
132
- return rtrim ($ out , ', ' ) . " } " ;
138
+ return rtrim ($ out , ', ' ). ' } ' ;
133
139
}
134
140
135
141
public function stripQuotes (string $ value )
136
142
{
137
- return strpos ($ value , '" ' ) === 0 || strpos ($ value , '\'' ) === 0
143
+ return str_starts_with ($ value , '" ' ) || str_starts_with ($ value , '\'' )
138
144
? substr ($ value , 1 , -1 )
139
145
: $ value ;
140
146
}
141
147
142
148
protected function parseAttributeBag (string $ attributeString )
143
149
{
144
- $ pattern = "/
145
- (?:^|\s+) # start of the string or whitespace between attributes
146
- \{\{\s*(attributes(?:.+?(?<!\s))?)\s*\}\} # exact match of attributes variable being echoed
147
- /x " ;
148
-
149
- return preg_replace ($ pattern , ' :attributes="$1" ' , $ attributeString );
150
+ return preg_replace (self ::ATTRIBUTE_BAG_REGEX , ' :attributes="$1" ' , $ attributeString );
150
151
}
151
- }
152
+ }
0 commit comments