Skip to content

Commit 38a0955

Browse files
authored
Merge pull request #2 from phug-php/enable-renderer
Fix pug-php compatibility
2 parents c7f5a0c + 09eb421 commit 38a0955

260 files changed

Lines changed: 2201 additions & 25 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/Phug/Component/ComponentExtension.php

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
use Closure;
66
use Phug\AbstractPlugin;
77
use Phug\Ast\NodeInterface;
8+
use Phug\Compiler\Event\ElementEvent;
89
use Phug\Compiler\Event\NodeEvent;
910
use Phug\Compiler\Event\OutputEvent;
1011
use Phug\CompilerEvent;
12+
use Phug\Formatter\Element\CodeElement;
1113
use Phug\Parser\NodeInterface as ParserNodeInterface;
1214
use Phug\Parser\Node\CodeNode;
1315
use Phug\Parser\Node\KeywordNode;
@@ -89,6 +91,8 @@ protected function getCodeNode(NodeInterface $linkedNode, ParserNodeInterface $p
8991
$code->setValue($value);
9092
}
9193

94+
$code->noTransform = true;
95+
9296
return $code;
9397
}
9498

@@ -116,29 +120,21 @@ public function handleNodeEvent(NodeEvent $event): void
116120

117121
public function handleOutputEvent(OutputEvent $event): void
118122
{
119-
$event->setOutput(
120-
implode("\n", [
121-
'<?php',
122-
'$firstMixin = function (string ...$names) use (&$__pug_mixins) {',
123-
' foreach ($names as $name) {',
124-
' if (isset($__pug_mixins[$name])) {',
125-
' return $name;',
126-
' }',
127-
' }',
128-
' throw new \\InvalidArgumentException("No defined mixin/component in [".implode(", ", $names)."]");',
129-
'};',
130-
'$firstComponent = $firstMixin;',
131-
'?>',
132-
]).
133-
$event->getOutput()
134-
);
123+
$event->setOutput($this->parseOutput($event->getOutput()));
135124
}
136125

137126
public function attachEvents(): void
138127
{
139128
$compiler = $this->getCompiler();
140129
$compiler->attach(CompilerEvent::NODE, [$this, 'handleNodeEvent']);
141130
$compiler->attach(CompilerEvent::OUTPUT, [$this, 'handleOutputEvent']);
131+
$compiler->attach(CompilerEvent::ELEMENT, function (ElementEvent $event) {
132+
$code = $event->getElement();
133+
134+
if ($code instanceof CodeElement && ($node = $code->getOriginNode()) && ($node->noTransform ?? false)) {
135+
$code->preventFromTransformation();
136+
}
137+
});
142138
}
143139

144140
public function detachEvents(): void
@@ -147,4 +143,27 @@ public function detachEvents(): void
147143
$compiler->detach(CompilerEvent::NODE, [$this, 'handleNodeEvent']);
148144
$compiler->detach(CompilerEvent::OUTPUT, [$this, 'handleOutputEvent']);
149145
}
146+
147+
private function parseOutput(string $output): string
148+
{
149+
$mixinFunctionsCode = implode("\n", [
150+
'',
151+
'$firstMixin = function (string ...$names) use (&$__pug_mixins) {',
152+
' foreach ($names as $name) {',
153+
' if (isset($__pug_mixins[$name])) {',
154+
' return $name;',
155+
' }',
156+
' }',
157+
' throw new \\InvalidArgumentException("No defined mixin/component in [".implode(", ", $names)."]");',
158+
'};',
159+
'$firstComponent = $firstMixin;',
160+
'',
161+
]);
162+
163+
if (preg_match('/^(<\?(?:php)?\s+namespace\s\S.*)((\n[\s\S]*)?)$/U', $output, $matches)) {
164+
return $matches[1].$mixinFunctionsCode.$matches[2];
165+
}
166+
167+
return "<?php$mixinFunctionsCode?>$output";
168+
}
150169
}

tests/Phug/Component/ComponentExtensionTest.php

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,8 @@ class ComponentExtensionTest extends TestCase
3232
*/
3333
protected $readme = null;
3434

35-
/**
36-
* @var Formatter
37-
*/
38-
protected $htmlFormatter;
39-
4035
protected function setUp(): void
4136
{
42-
$this->htmlFormatter = new Formatter;
43-
$this->htmlFormatter->setSpacesIndentationMethod(2);
44-
4537
preg_match(
4638
'/```php\n(?<php>[\s\S]+)\n```/U',
4739
$this->getReadmeContents(),
@@ -58,7 +50,9 @@ protected function renderAndFormat(string $code): string
5850

5951
protected function format(string $html): string
6052
{
61-
$html = trim($this->htmlFormatter->format($html));
53+
$htmlFormatter = new Formatter;
54+
$htmlFormatter->setSpacesIndentationMethod(2);
55+
$html = trim($htmlFormatter->format($html));
6256
$html = preg_replace('/\s+<em>\s*(.*\S)\s*<\/em>\s+/', ' <em>$1</em>', $html);
6357
$html = preg_replace('/<p>\s*(.*\S)\s*<\/p>/', '<p>$1</p>', $html);
6458

@@ -375,4 +369,57 @@ public function testWithPug()
375369
' | Content',
376370
]))));
377371
}
372+
373+
public function getPugPhpTestsTemplates(): array
374+
{
375+
return array_map(function ($file) {
376+
return [$file, substr($file, 0, -5).'.pug'];
377+
}, glob(__DIR__.'/../../templates/*.html'));
378+
}
379+
380+
/**
381+
* @dataProvider getPugPhpTestsTemplates
382+
*
383+
* @covers ::attachEvents
384+
* @covers ::parseOutput
385+
*
386+
* @param string $htmlFile Expected output template file
387+
* @param string $pugFile Input template file
388+
*
389+
* @throws Exception
390+
*/
391+
public function testPugPhpTestsTemplates(string $htmlFile, string $pugFile)
392+
{
393+
$pug = new Pug([
394+
'debug' => false,
395+
'pretty' => true,
396+
]);
397+
ComponentExtension::enable($pug);
398+
399+
$this->assertSame(
400+
$this->rawHtml(file_get_contents($htmlFile)),
401+
$this->rawHtml($pug->renderFile($pugFile, [])),
402+
basename($pugFile)
403+
);
404+
}
405+
406+
private function rawHtml($html)
407+
{
408+
$html = strtr($html, [
409+
"'" => '"',
410+
"\r" => '',
411+
]);
412+
$html = preg_replace('`\n{2,}`', "\n", $html);
413+
$html = preg_replace('`(?<!\n) {2,}`', ' ', $html);
414+
$html = preg_replace('` *$`m', '', $html);
415+
$html = $this->format($html);
416+
$html = preg_replace_callback('`(<(?:style|script)(?:[^>]*)>)([\s\S]+)(</(?:style|script)>)`', function ($matches) {
417+
[, $start, $content, $end] = $matches;
418+
$content = trim(preg_replace('`^ *`m', '', $content));
419+
420+
return "$start\n$content\n$end";
421+
}, $html);
422+
423+
return $html;
424+
}
378425
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<a b=')'></a>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
a(b=')')
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<foo data-items="{&quot;foo&quot;:&quot;bar&quot;,&quot;yah&quot;:42,&quot;yoh&quot;:&quot;yah: 42&quot;,&quot;bar&quot;:&quot;a'a\&quot;\\\&quot;\\'\\\\&quot;}"></foo>
2+
<foo data-items="{&quot;foo&quot;:&quot;#{foo}, \\#{foo}&quot;,&quot;bar&quot;:&quot;#{foo}, \\#{foo}&quot;}"></foo>
3+
<foo data-items="[&quot;#{foo} [a]&quot;,&quot;#{foo} =&gt;&quot;]"></foo>
4+
<foo data-items="{&quot;a\\\&quot;\\&quot;:&quot;a&quot;}"></foo>
5+
<foo a'="'a"></foo>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
- foo = 42
2+
foo(data-items={ foo: 'bar', yah: 42, "yoh": "yah: 42", bar :'a\'a"\"\\\'\\\\' })
3+
foo(data-items={ foo: '#{foo}, \#{foo}', bar: "#{foo}, \#{foo}" })
4+
foo(data-items=['#{foo} [a]', "#{foo} =>"])
5+
foo(data-items={"a\\\"\\": "a"})
6+
foo('a\''='\'a')

tests/templates/attrs-data.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<foo data-user="{&quot;name&quot;:&quot;tobi&quot;}"></foo>
2+
<foo data-items="[1,2,3]"></foo>
3+
<foo data-username="tobi"></foo>
4+
<foo data-username="tobi"></foo>
5+
<foo data-username="tobi"></foo>

tests/templates/attrs-data.pug

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
- user = {name: 'tobi'}
2+
foo(data-user=user)
3+
foo(data-items=[1,2,3])
4+
foo(data-username='tobi')
5+
foo("data-username"='tobi')
6+
foo('data-username'='tobi')
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<p answear="42"></p>
2+
<p answear="42"></p>
3+
<p answear="bar"></p>
4+
<p answear="bar"></p>
5+
<p answear="bar"></p>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
:php
2+
class FooClass {
3+
public function met() {
4+
return 42;
5+
}
6+
}
7+
$ob = (object) array('foo' => array());
8+
$ob->foo['bar'] = new FooClass();
9+
$foo = 'bar';
10+
p(answear=ob.foo.bar.met())
11+
p(answear=(ob.foo.bar.met()))
12+
p(answear=substr("foo-bar", strlen("foo") + 1))
13+
p(answear=substr("foo-bar", strlen(strtoupper("F") + "oo") + 1))
14+
p(answear=foo[0] + (substr(foo, 1 / 3 * (strlen(foo)))))

0 commit comments

Comments
 (0)