Skip to content

Commit 3c7935d

Browse files
authored
Add support for inline post processing (#20)
Add support for inline post processing
1 parent e66dc25 commit 3c7935d

8 files changed

+159
-19
lines changed

src/Blade/CodeComponent.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55

66
namespace Torchlight\Blade;
77

8+
use Illuminate\Support\Arr;
89
use Illuminate\Support\Str;
910
use Illuminate\View\Component;
1011
use Torchlight\Block;
12+
use Torchlight\PostProcessors\SimpleSwapProcessor;
1113
use Torchlight\Torchlight;
1214

1315
class CodeComponent extends Component
@@ -30,13 +32,23 @@ class CodeComponent extends Component
3032
* @param null $contents
3133
* @param null $torchlightId
3234
*/
33-
public function __construct($language, $theme = null, $contents = null, $torchlightId = null)
35+
public function __construct($language, $theme = null, $contents = null, $swap = null, $postProcessors = [], $torchlightId = null)
3436
{
3537
$this->language = $language;
3638
$this->theme = $theme;
3739
$this->contents = $contents;
3840

3941
$this->block = Block::make($torchlightId)->language($this->language)->theme($this->theme);
42+
43+
$postProcessors = Arr::wrap($postProcessors);
44+
45+
if ($swap) {
46+
$postProcessors[] = SimpleSwapProcessor::make($swap);
47+
}
48+
49+
foreach ($postProcessors as $processor) {
50+
$this->block->addPostProcessor($processor);
51+
}
4052
}
4153

4254
public function withAttributes(array $attributes)

src/Block.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ class Block
3535
*/
3636
public $code;
3737

38+
/**
39+
* The post processors.
40+
*
41+
* @var array
42+
*/
43+
public $postProcessors = [];
44+
3845
/**
3946
* The highlighted code, wrapped in pre+code tags.
4047
*
@@ -171,6 +178,19 @@ public function code($code)
171178
return $this;
172179
}
173180

181+
/**
182+
* @param $processor
183+
* @return $this
184+
*/
185+
public function addPostProcessor($processor)
186+
{
187+
if ($processor) {
188+
$this->postProcessors[] = Torchlight::validatedPostProcessor($processor);
189+
}
190+
191+
return $this;
192+
}
193+
174194
/**
175195
* @param $wrapped
176196
* @return $this

src/Manager.php

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -109,20 +109,13 @@ public function overrideEnvironment($environment = null)
109109

110110
/**
111111
* @param array|string $classes
112-
*
113-
* @throws ConfigurationException
114112
*/
115113
public function addPostProcessors($classes)
116114
{
117115
$classes = Arr::wrap($classes);
118116

119117
foreach ($classes as $class) {
120-
if (!in_array(PostProcessor::class, class_implements($class))) {
121-
$class = is_string($class) ? $class : get_class($class);
122-
throw new ConfigurationException("Post-processor '$class' does not implement " . PostProcessor::class);
123-
}
124-
125-
$this->postProcessors[] = $class;
118+
$this->postProcessors[] = $this->validatedPostProcessor($class);
126119
}
127120
}
128121

@@ -131,24 +124,27 @@ public function addPostProcessors($classes)
131124
*/
132125
public function postProcessBlocks($blocks)
133126
{
127+
// Global post-processors
134128
foreach ($this->postProcessors as $processor) {
135-
$processor = app($processor);
136-
137-
// By default we do _not_ run post-processors when Laravel is compiling
138-
// views, because it could lead to data leaks if a post-processor swaps
139-
// user data in. If the developer understands this, they can turn
140-
// `processEvenWhenCompiling` on and we'll happily run them.
141-
$processWhenCompiling = property_exists($processor, 'processEvenWhenCompiling')
142-
&& $processor->processEvenWhenCompiling;
143-
144-
if ($this->currentlyCompilingViews && !$processWhenCompiling) {
129+
if ($this->shouldSkipProcessor($processor)) {
145130
continue;
146131
}
147132

148133
foreach ($blocks as $block) {
149134
$processor->process($block);
150135
}
151136
}
137+
138+
// Block specific post-processors
139+
foreach ($blocks as $block) {
140+
foreach ($block->postProcessors as $processor) {
141+
if ($this->shouldSkipProcessor($processor)) {
142+
continue;
143+
}
144+
145+
$processor->process($block);
146+
}
147+
}
152148
}
153149

154150
public function processFileContents($file)
@@ -245,4 +241,36 @@ public function findTorchlightIds($content)
245241

246242
return array_values(array_unique(Arr::get($matches, 1, [])));
247243
}
244+
245+
/**
246+
* @param $processor
247+
* @return PostProcessor
248+
*
249+
* @throws ConfigurationException
250+
*/
251+
public function validatedPostProcessor($processor)
252+
{
253+
if (is_string($processor)) {
254+
$processor = app($processor);
255+
}
256+
257+
if (!in_array(PostProcessor::class, class_implements($processor))) {
258+
$class = get_class($processor);
259+
throw new ConfigurationException("Post-processor '$class' does not implement " . PostProcessor::class);
260+
}
261+
262+
return $processor;
263+
}
264+
265+
protected function shouldSkipProcessor($processor)
266+
{
267+
// By default we do _not_ run post-processors when Laravel is compiling
268+
// views, because it could lead to data leaks if a post-processor swaps
269+
// user data in. If the developer understands this, they can turn
270+
// `processEvenWhenCompiling` on and we'll happily run them.
271+
$processWhenCompiling = property_exists($processor, 'processEvenWhenCompiling')
272+
&& $processor->processEvenWhenCompiling;
273+
274+
return $this->currentlyCompilingViews && !$processWhenCompiling;
275+
}
248276
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
/**
3+
* @author Aaron Francis <[email protected]|https://twitter.com/aarondfrancis>
4+
*/
5+
6+
namespace Torchlight\PostProcessors;
7+
8+
use Torchlight\Block;
9+
use Torchlight\Contracts\PostProcessor;
10+
11+
class SimpleSwapProcessor implements PostProcessor
12+
{
13+
public $swap = [];
14+
15+
public static function make($swap)
16+
{
17+
return new static($swap);
18+
}
19+
20+
public function __construct($swap)
21+
{
22+
$this->swap = $swap;
23+
}
24+
25+
public function process(Block $block)
26+
{
27+
$block->highlighted = str_replace(array_keys($this->swap), array_values($this->swap), $block->highlighted);
28+
}
29+
}

tests/MiddlewareAndComponentTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,40 @@ public function inline_keeps_its_spaces()
139139
);
140140
}
141141

142+
/** @test */
143+
public function inline_swaps_run()
144+
{
145+
$this->fakeSuccessfulResponse('component', [
146+
'classes' => 'torchlight',
147+
'styles' => 'background-color: #292D3E;',
148+
'highlighted' => 'echo "hello world"',
149+
]);
150+
151+
$response = $this->getView('an-inline-component-with-swaps.blade.php');
152+
153+
$this->assertEquals(
154+
'this is <code class="torchlight" style="background-color: #292D3E;">echo "goodbye world"</code> inline',
155+
$response->content()
156+
);
157+
}
158+
159+
/** @test */
160+
public function inline_processors_run()
161+
{
162+
$this->fakeSuccessfulResponse('component', [
163+
'classes' => 'torchlight',
164+
'styles' => 'background-color: #292D3E;',
165+
'highlighted' => 'echo "hello world"',
166+
]);
167+
168+
$response = $this->getView('an-inline-component-with-post-processors.blade.php');
169+
170+
$this->assertEquals(
171+
'this is <code class="torchlight" style="background-color: #292D3E;">echo "goodbye world"</code> inline',
172+
$response->content()
173+
);
174+
}
175+
142176
/** @test */
143177
public function language_can_be_set_via_component()
144178
{

tests/PostProcessorTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Torchlight\Block;
99
use Torchlight\Contracts\PostProcessor;
1010
use Torchlight\Exceptions\ConfigurationException;
11+
use Torchlight\PostProcessors\SimpleSwapProcessor;
1112
use Torchlight\Torchlight;
1213

1314
class PostProcessorTest extends BaseTest
@@ -106,6 +107,19 @@ public function they_run_in_order()
106107
$this->assertEquals($blocks[0]->highlighted, '<div class=\'highlighted\'>echo "goodbye cruel world";</div>');
107108
}
108109

110+
/** @test */
111+
public function it_runs_inline_post_processors()
112+
{
113+
$this->fakeSuccessfulResponse('id');
114+
115+
$blocks = Torchlight::highlight(
116+
Block::make('id')->language('php')->code('echo "hello world";')
117+
->addPostProcessor(SimpleSwapProcessor::make(['hello world' => 'goodbye world']))
118+
);
119+
120+
$this->assertEquals($blocks[0]->highlighted, '<div class=\'highlighted\'>echo "goodbye world";</div>');
121+
}
122+
109123
/** @test */
110124
public function must_implement_interface()
111125
{
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@php($p = \Torchlight\PostProcessors\SimpleSwapProcessor::make(['hello' => 'goodbye']))
2+
this is <x-torchlight-code torchlight-id='component' language='php' :post-processors='$p'>echo "hello world"</x-torchlight-code> inline
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
this is <x-torchlight-code torchlight-id='component' language='php' :swap='["hello" => "goodbye"]'>echo "hello world"</x-torchlight-code> inline

0 commit comments

Comments
 (0)