Skip to content

Commit c658586

Browse files
authored
Merge pull request #1 from weaverryan/refactor-twig-component-syntax
Add Ryan PreLexer work
2 parents 01df60f + f5f14fe commit c658586

File tree

3 files changed

+355
-122
lines changed

3 files changed

+355
-122
lines changed

src/TwigComponent/src/Twig/ComponentLexer.php

Lines changed: 3 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,11 @@ class ComponentLexer extends Lexer
3434
public const BLOCK_TAGS_CLOSE = '/<\s*\/\s*t:block\s*>/';
3535
public const ATTRIBUTE_BAG_REGEX = '/(?:^|\s+)\{\{\s*(attributes(?:.+?(?<!\s))?)\s*\}\}/x';
3636
public const ATTRIBUTE_KEY_VALUE_REGEX = '/(?<attribute>[\w\-:.@]+)(=(?<value>(\"[^\"]+\"|\\\'[^\\\']+\\\'|[^\s>]+)))?/x';
37-
37+
3838
public function tokenize(Source $source): TokenStream
3939
{
40-
$preparsed = $this->preparsed($source->getCode());
40+
$preLexer = new TwigPreLexer();
41+
$preparsed = $preLexer->preLexComponents($source->getCode());
4142

4243
return parent::tokenize(
4344
new Source(
@@ -47,124 +48,4 @@ public function tokenize(Source $source): TokenStream
4748
)
4849
);
4950
}
50-
51-
private function preparsed(string $value)
52-
{
53-
$value = $this->lexBlockTags($value);
54-
$value = $this->lexBlockTagsClose($value);
55-
$value = $this->lexSelfCloseTag($value);
56-
$value = $this->lexOpeningTags($value);
57-
$value = $this->lexClosingTag($value);
58-
59-
return $value;
60-
}
61-
62-
private function lexOpeningTags(string $value)
63-
{
64-
return preg_replace_callback(
65-
self::OPEN_TAGS_REGEX,
66-
function (array $matches) {
67-
$name = $matches['name'];
68-
$attributes = $this->getAttributesFromAttributeString($matches['attributes']);
69-
70-
return '{% component '.$name.' with '.$attributes.'%}';
71-
},
72-
$value
73-
);
74-
}
75-
76-
private function lexClosingTag(string $value)
77-
{
78-
return preg_replace(self::CLOSE_TAGS_REGEX, '{% endcomponent %}', $value);
79-
}
80-
81-
private function lexSelfCloseTag(string $value)
82-
{
83-
return preg_replace_callback(
84-
self::SELF_CLOSE_TAGS_REGEX,
85-
function (array $matches) {
86-
$name = $matches['name'];
87-
$attributes = $this->getAttributesFromAttributeString($matches['attributes']);
88-
89-
return "{{ component('".$name."', ".$attributes.') }}';
90-
},
91-
$value
92-
);
93-
}
94-
95-
private function lexBlockTags(string $value)
96-
{
97-
return preg_replace_callback(
98-
self::BLOCK_TAGS_OPEN,
99-
function (array $matches) {
100-
$name = $matches['name'];
101-
102-
return '{% block '.$name.' %}';
103-
},
104-
$value
105-
);
106-
}
107-
108-
private function lexBlockTagsClose(string $value)
109-
{
110-
return preg_replace(
111-
self::BLOCK_TAGS_CLOSE,
112-
'{% endblock %}',
113-
$value
114-
);
115-
}
116-
117-
protected function getAttributesFromAttributeString(string $attributeString)
118-
{
119-
$attributeString = $this->parseAttributeBag($attributeString);
120-
121-
if (!preg_match_all(self::ATTRIBUTE_KEY_VALUE_REGEX, $attributeString, $matches, \PREG_SET_ORDER)) {
122-
return '{}';
123-
}
124-
125-
$attributes = [];
126-
foreach ($matches as $match) {
127-
$attribute = $match['attribute'];
128-
$value = $match['value'] ?? null;
129-
130-
if (null === $value) {
131-
$value = 'true';
132-
}
133-
134-
if (str_starts_with($attribute, ':')) {
135-
$attribute = str_replace(':', '', $attribute);
136-
$value = $this->stripQuotes($value);
137-
}
138-
139-
$valueWithoutQuotes = $this->stripQuotes($value);
140-
141-
if (str_starts_with($valueWithoutQuotes, '{{') && (strpos($valueWithoutQuotes, '}}') === \strlen($valueWithoutQuotes) - 2)) {
142-
$value = substr($valueWithoutQuotes, 2, -2);
143-
} else {
144-
$value = $value;
145-
}
146-
147-
$attributes[$attribute] = $value;
148-
}
149-
150-
$out = '{';
151-
foreach ($attributes as $key => $value) {
152-
$key = "'$key'";
153-
$out .= "$key: $value,";
154-
}
155-
156-
return rtrim($out, ',').'}';
157-
}
158-
159-
public function stripQuotes(string $value)
160-
{
161-
return str_starts_with($value, '"') || str_starts_with($value, '\'')
162-
? substr($value, 1, -1)
163-
: $value;
164-
}
165-
166-
protected function parseAttributeBag(string $attributeString)
167-
{
168-
return preg_replace(self::ATTRIBUTE_BAG_REGEX, ' :attributes="$1"', $attributeString);
169-
}
17051
}

0 commit comments

Comments
 (0)