15
15
use Twig \Lexer ;
16
16
17
17
/**
18
- * Rewrites <twig:component> syntaxes to {% component %} syntaxes.
18
+ * Rewrites <twig:component> or <Component> syntaxes to {% component %} syntaxes.
19
19
*/
20
20
class TwigPreLexer
21
21
{
@@ -28,17 +28,34 @@ class TwigPreLexer
28
28
*/
29
29
private array $ currentComponents = [];
30
30
31
- public function __construct (int $ startingLine = 1 )
31
+ public function __construct (int $ startingLine = 1 , private readonly bool $ withShortTags = false )
32
32
{
33
33
$ this ->line = $ startingLine ;
34
34
}
35
35
36
36
public function preLexComponents (string $ input ): string
37
37
{
38
- if (!str_contains ($ input , '<twig: ' )) {
38
+ // tag may be:
39
+ // - prefixed: <twig:componentName>
40
+ // - short (jsx like): <ComponentName> (with a capital letter)
41
+
42
+ $ isPrefixedTags = str_contains ($ input , '<twig: ' );
43
+ $ isShortTags = $ this ->withShortTags && preg_match_all ('/<([A-Z][a-zA-Z0-9_:-]+)([^>]*)>/ ' , $ input , $ matches , \PREG_SET_ORDER );
44
+
45
+ if (!$ isPrefixedTags && !$ isShortTags ) {
39
46
return $ input ;
40
47
}
41
48
49
+ if ($ isShortTags ) {
50
+ $ componentNames = array_map (fn ($ match ) => $ match [1 ], $ matches );
51
+ $ componentNames = array_unique (array_filter ($ componentNames ));
52
+
53
+ // To simplify things in the rest of the class, we replace the component name with twig:<componentName>
54
+ foreach ($ componentNames as $ componentName ) {
55
+ $ input = preg_replace ('!<(/?) ' .preg_quote ($ componentName ).'! ' , '<$1twig: ' .lcfirst ($ componentName ), $ input );
56
+ }
57
+ }
58
+
42
59
$ this ->input = $ input = str_replace (["\r\n" , "\r" ], "\n" , $ input );
43
60
$ this ->length = \strlen ($ input );
44
61
$ output = '' ;
@@ -394,7 +411,7 @@ private function consumeBlock(string $componentName): string
394
411
}
395
412
$ blockContents = $ this ->consumeUntilEndBlock ();
396
413
397
- $ subLexer = new self ($ this ->line );
414
+ $ subLexer = new self ($ this ->line , $ this -> withShortTags );
398
415
$ output .= $ subLexer ->preLexComponents ($ blockContents );
399
416
400
417
$ this ->consume ($ closingTag );
0 commit comments