Skip to content

Commit 36be90a

Browse files
committed
[FEATURE] Keep TypoScript format
Resolves: #197
1 parent 2ef9813 commit 36be90a

17 files changed

+294
-18
lines changed

README.md

+20
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,26 @@ return FractorConfiguration::configure()
116116
])
117117
```
118118

119+
If you want to adjust the format of your typoscript files, you can configure it this way:
120+
121+
```php
122+
<?php
123+
124+
use a9f\Fractor\Configuration\FractorConfiguration;
125+
use a9f\FractorTypoScript\Configuration\TypoScriptProcessorOption;
126+
use Helmich\TypoScriptParser\Parser\Printer\PrettyPrinterConfiguration;
127+
128+
return FractorConfiguration::configure()
129+
->withOptions([
130+
TypoScriptProcessorOption::INDENT_SIZE => 2,
131+
TypoScriptProcessorOption::INDENT_CHARACTER => PrettyPrinterConfiguration::INDENTATION_STYLE_SPACES,
132+
//TypoScriptProcessorOption::INDENT_CHARACTER => 'auto', // this detects the indent from the file and keeps it
133+
TypoScriptProcessorOption::ADD_CLOSING_GLOBAL => false,
134+
TypoScriptProcessorOption::INCLUDE_EMPTY_LINE_BREAKS => true,
135+
TypoScriptProcessorOption::INDENT_CONDITIONS => true,
136+
])
137+
```
138+
119139
## Processing
120140

121141
Execute Fractor from the command line, passing the path to your configuration file as an argument:

packages/fractor-typoscript/config/application.php

+6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
declare(strict_types=1);
44

55
use a9f\FractorTypoScript\Contract\TypoScriptFractor;
6+
use a9f\FractorTypoScript\Factory\PrettyPrinterFormatFactory;
67
use a9f\FractorTypoScript\TypoScriptFileProcessor;
8+
use a9f\FractorTypoScript\ValueObject\TypoScriptPrettyPrinterFormatConfiguration;
79
use Helmich\TypoScriptParser\Parser\Parser;
810
use Helmich\TypoScriptParser\Parser\Printer\PrettyPrinter;
911
use Helmich\TypoScriptParser\Tokenizer\Tokenizer;
@@ -26,7 +28,11 @@
2628
->public();
2729
$services->set(PrettyPrinter::class);
2830

31+
$services->set('fractor.typoscript_processor.pretty_printer', TypoScriptPrettyPrinterFormatConfiguration::class)
32+
->factory([service(PrettyPrinterFormatFactory::class), 'create']);
33+
2934
$services->set(TypoScriptFileProcessor::class)
35+
->arg('$typoScriptPrettyPrinterFormatConfiguration', service('fractor.typoscript_processor.pretty_printer'))
3036
->arg('$rules', tagged_iterator('fractor.typoscript_rule'));
3137

3238
$containerBuilder->registerForAutoconfiguration(TypoScriptFractor::class)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace a9f\FractorTypoScript\Configuration;
6+
7+
final class TypoScriptProcessorOption
8+
{
9+
public const INDENT_SIZE = 'typoscript-processor-indent-size';
10+
11+
public const INDENT_CHARACTER = 'typoscript-processor-indent-character';
12+
13+
public const ADD_CLOSING_GLOBAL = 'typoscript-processor-add-closing-global';
14+
15+
public const INCLUDE_EMPTY_LINE_BREAKS = 'typoscript-processor-include-empty-line-breaks';
16+
17+
public const INDENT_CONDITIONS = 'typoscript-processor-indent-conditions';
18+
}

packages/fractor-typoscript/src/Factory/PrettyPrinterConfigurationFactory.php

+32-9
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,46 @@
66

77
use a9f\Fractor\Application\ValueObject\File;
88
use a9f\Fractor\ValueObject\Indent;
9+
use a9f\FractorTypoScript\ValueObject\TypoScriptPrettyPrinterFormatConfiguration;
910
use Helmich\TypoScriptParser\Parser\Printer\PrettyPrinterConfiguration;
1011

1112
final class PrettyPrinterConfigurationFactory
1213
{
13-
public function createPrettyPrinterConfiguration(File $file): PrettyPrinterConfiguration
14-
{
15-
// keep original TypoScript format
16-
$indent = Indent::fromFile($file);
17-
14+
public function createPrettyPrinterConfiguration(
15+
File $file,
16+
TypoScriptPrettyPrinterFormatConfiguration $prettyPrinterFormatConfiguration
17+
): PrettyPrinterConfiguration {
1818
$prettyPrinterConfiguration = PrettyPrinterConfiguration::create();
1919

20-
if ($indent->isSpace()) {
21-
$prettyPrinterConfiguration = $prettyPrinterConfiguration->withSpaceIndentation($indent->length());
22-
} else {
20+
if ($prettyPrinterFormatConfiguration->getStyle() === 'auto') {
21+
// keep original TypoScript format
22+
$indent = Indent::fromFile($file);
23+
24+
if ($indent->isSpace()) {
25+
$prettyPrinterConfiguration = $prettyPrinterConfiguration->withSpaceIndentation($indent->length());
26+
} else {
27+
$prettyPrinterConfiguration = $prettyPrinterConfiguration->withTabs();
28+
}
29+
} elseif ($prettyPrinterFormatConfiguration->getStyle() === PrettyPrinterConfiguration::INDENTATION_STYLE_TABS) {
2330
$prettyPrinterConfiguration = $prettyPrinterConfiguration->withTabs();
31+
} else {
32+
$prettyPrinterConfiguration = $prettyPrinterConfiguration->withSpaceIndentation(
33+
$prettyPrinterFormatConfiguration->getSize()
34+
);
35+
}
36+
37+
if ($prettyPrinterFormatConfiguration->shouldIndentConditions()) {
38+
$prettyPrinterConfiguration = $prettyPrinterConfiguration->withIndentConditions();
39+
}
40+
41+
if ($prettyPrinterFormatConfiguration->shouldAddClosingGlobal()) {
42+
$prettyPrinterConfiguration = $prettyPrinterConfiguration->withClosingGlobalStatement();
43+
}
44+
45+
if ($prettyPrinterFormatConfiguration->shouldIncludeEmptyLineBreaks()) {
46+
return $prettyPrinterConfiguration->withEmptyLineBreaks();
2447
}
2548

26-
return $prettyPrinterConfiguration->withEmptyLineBreaks();
49+
return $prettyPrinterConfiguration;
2750
}
2851
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace a9f\FractorTypoScript\Factory;
6+
7+
use a9f\FractorTypoScript\Configuration\TypoScriptProcessorOption;
8+
use a9f\FractorTypoScript\ValueObject\TypoScriptPrettyPrinterFormatConfiguration;
9+
use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;
10+
11+
final readonly class PrettyPrinterFormatFactory
12+
{
13+
public function __construct(
14+
private ContainerBagInterface $parameterBag
15+
) {
16+
}
17+
18+
public function create(): TypoScriptPrettyPrinterFormatConfiguration
19+
{
20+
$size = $this->parameterBag->has(TypoScriptProcessorOption::INDENT_SIZE)
21+
? $this->parameterBag->get(TypoScriptProcessorOption::INDENT_SIZE)
22+
: 4;
23+
24+
$style = $this->parameterBag->has(TypoScriptProcessorOption::INDENT_CHARACTER)
25+
? $this->parameterBag->get(TypoScriptProcessorOption::INDENT_CHARACTER)
26+
: 'auto';
27+
28+
$addClosingGlobal = $this->parameterBag->has(TypoScriptProcessorOption::ADD_CLOSING_GLOBAL)
29+
? $this->parameterBag->get(TypoScriptProcessorOption::ADD_CLOSING_GLOBAL)
30+
: true;
31+
32+
$includeEmptyLineBreaks = $this->parameterBag->has(TypoScriptProcessorOption::INCLUDE_EMPTY_LINE_BREAKS)
33+
? $this->parameterBag->get(TypoScriptProcessorOption::INCLUDE_EMPTY_LINE_BREAKS)
34+
: true;
35+
36+
$indentConditions = $this->parameterBag->has(TypoScriptProcessorOption::INDENT_CONDITIONS)
37+
? $this->parameterBag->get(TypoScriptProcessorOption::INDENT_CONDITIONS)
38+
: false;
39+
40+
return TypoScriptPrettyPrinterFormatConfiguration::fromValues(
41+
$size,
42+
$style,
43+
$addClosingGlobal,
44+
$includeEmptyLineBreaks,
45+
$indentConditions
46+
);
47+
}
48+
}

packages/fractor-typoscript/src/TypoScriptFileProcessor.php

+7-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use a9f\Fractor\Application\ValueObject\File;
99
use a9f\FractorTypoScript\Contract\TypoScriptFractor;
1010
use a9f\FractorTypoScript\Factory\PrettyPrinterConfigurationFactory;
11+
use a9f\FractorTypoScript\ValueObject\TypoScriptPrettyPrinterFormatConfiguration;
1112
use Helmich\TypoScriptParser\Parser\ParseError;
1213
use Helmich\TypoScriptParser\Parser\Parser;
1314
use Helmich\TypoScriptParser\Parser\Printer\PrettyPrinter;
@@ -28,7 +29,8 @@ public function __construct(
2829
private iterable $rules,
2930
private Parser $parser,
3031
private PrettyPrinter $printer,
31-
private PrettyPrinterConfigurationFactory $prettyPrinterConfigurationFactory
32+
private PrettyPrinterConfigurationFactory $prettyPrinterConfigurationFactory,
33+
private TypoScriptPrettyPrinterFormatConfiguration $typoScriptPrettyPrinterFormatConfiguration
3234
) {
3335
$this->output = new BufferedOutput();
3436
}
@@ -47,7 +49,10 @@ public function handle(File $file, iterable $appliedRules): void
4749
$statements = $statementsIterator->traverseDocument($file, $statements);
4850

4951
$this->printer->setPrettyPrinterConfiguration(
50-
$this->prettyPrinterConfigurationFactory->createPrettyPrinterConfiguration($file)
52+
$this->prettyPrinterConfigurationFactory->createPrettyPrinterConfiguration(
53+
$file,
54+
$this->typoScriptPrettyPrinterFormatConfiguration
55+
)
5156
);
5257
$this->printer->printStatements($statements, $this->output);
5358

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace a9f\FractorTypoScript\ValueObject;
6+
7+
final readonly class TypoScriptPrettyPrinterFormatConfiguration
8+
{
9+
public function __construct(
10+
private int $size,
11+
private string $style,
12+
private bool $addClosingGlobal,
13+
private bool $includeEmptyLineBreaks,
14+
private bool $indentConditions
15+
) {
16+
}
17+
18+
/**
19+
* @phpstan-param \Helmich\TypoScriptParser\Parser\Printer\PrettyPrinterConfiguration::INDENTATION_STYLE_* $style
20+
*/
21+
public static function fromValues(
22+
int $size,
23+
string $style,
24+
bool $addClosingGlobal,
25+
bool $includeEmptyLineBreaks,
26+
bool $indentConditions
27+
): self {
28+
return new self($size, $style, $addClosingGlobal, $includeEmptyLineBreaks, $indentConditions);
29+
}
30+
31+
public function getSize(): int
32+
{
33+
return $this->size;
34+
}
35+
36+
public function getStyle(): string
37+
{
38+
return $this->style;
39+
}
40+
41+
public function shouldAddClosingGlobal(): bool
42+
{
43+
return $this->addClosingGlobal;
44+
}
45+
46+
public function shouldIncludeEmptyLineBreaks(): bool
47+
{
48+
return $this->includeEmptyLineBreaks;
49+
}
50+
51+
public function shouldIndentConditions(): bool
52+
{
53+
return $this->indentConditions;
54+
}
55+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace a9f\FractorTypoScript\Tests\Fixtures;
6+
7+
use a9f\FractorTypoScript\AbstractTypoScriptFractor;
8+
use a9f\FractorTypoScript\TypoScriptStatementsIterator;
9+
use Helmich\TypoScriptParser\Parser\AST\Operator\Assignment;
10+
use Helmich\TypoScriptParser\Parser\AST\Statement;
11+
use Symfony\Component\DependencyInjection\Exception\BadMethodCallException;
12+
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
13+
14+
final class DummyTypoScriptFractorRule extends AbstractTypoScriptFractor
15+
{
16+
public function refactor(Statement $statement): null|Statement|int
17+
{
18+
if (! $statement instanceof Assignment) {
19+
return null;
20+
}
21+
22+
if ($statement->object->absoluteName !== 'config.spamProtectEmailAddresses'
23+
|| $statement->value->value !== 'ascii'
24+
) {
25+
return null;
26+
}
27+
28+
return TypoScriptStatementsIterator::REMOVE_NODE;
29+
}
30+
31+
public function getRuleDefinition(): RuleDefinition
32+
{
33+
throw new BadMethodCallException('Not implemented yet');
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
page = PAGE
2+
page.10 = TEXT
3+
page.10.value = german
4+
5+
[siteLanguage('languageId') == 1]
6+
page.10.value = english
7+
[global]
8+
9+
config.spamProtectEmailAddresses = ascii
10+
-----
11+
page = PAGE
12+
page.10 = TEXT
13+
page.10.value = german
14+
15+
[siteLanguage('languageId') == 1]
16+
page.10.value = english
17+
[global]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace a9f\FractorTypoScript\Tests\TypoScriptFileProcessor;
6+
7+
use a9f\Fractor\Testing\PHPUnit\AbstractFractorTestCase;
8+
use a9f\FractorTypoScript\Tests\Fixtures\DummyTypoScriptFractorRule;
9+
use PHPUnit\Framework\Attributes\DataProvider;
10+
11+
class TypoScriptFileProcessorTest extends AbstractFractorTestCase
12+
{
13+
#[DataProvider('provideData')]
14+
public function test(string $filePath): void
15+
{
16+
$this->doTestFile($filePath);
17+
$this->assertThatRuleIsApplied($filePath, DummyTypoScriptFractorRule::class);
18+
}
19+
20+
public static function provideData(): \Iterator
21+
{
22+
return self::yieldFilesFromDirectory(__DIR__ . '/Fixtures', '*.typoscript');
23+
}
24+
25+
public function provideConfigFilePath(): ?string
26+
{
27+
return __DIR__ . '/config/fractor.php';
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use a9f\Fractor\Configuration\FractorConfiguration;
6+
use a9f\FractorTypoScript\Configuration\TypoScriptProcessorOption;
7+
use a9f\FractorTypoScript\Tests\Fixtures\DummyTypoScriptFractorRule;
8+
use Helmich\TypoScriptParser\Parser\Printer\PrettyPrinterConfiguration;
9+
10+
return FractorConfiguration::configure()
11+
->withOptions([
12+
TypoScriptProcessorOption::INDENT_SIZE => 4,
13+
TypoScriptProcessorOption::INDENT_CHARACTER => PrettyPrinterConfiguration::INDENTATION_STYLE_SPACES,
14+
//TypoScriptProcessorOption::INDENT_CHARACTER => 'auto',
15+
TypoScriptProcessorOption::ADD_CLOSING_GLOBAL => false,
16+
TypoScriptProcessorOption::INCLUDE_EMPTY_LINE_BREAKS => true,
17+
TypoScriptProcessorOption::INDENT_CONDITIONS => true,
18+
])
19+
->withRules([DummyTypoScriptFractorRule::class]);

packages/fractor-typoscript/tests/Fixture/StatementCollectingVisitor.php packages/fractor-typoscript/tests/TypoScriptStatementsIterator/Fixture/StatementCollectingVisitor.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
declare(strict_types=1);
44

5-
namespace a9f\FractorTypoScript\Tests\Fixture;
5+
namespace a9f\FractorTypoScript\Tests\TypoScriptStatementsIterator\Fixture;
66

77
use a9f\Fractor\Application\ValueObject\File;
88
use a9f\FractorTypoScript\Contract\TypoScriptNodeVisitor;

packages/fractor-typoscript/tests/TypoScriptStatementsIteratorTest.php packages/fractor-typoscript/tests/TypoScriptStatementsIterator/TypoScriptStatementsIteratorTest.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
declare(strict_types=1);
44

5-
namespace a9f\FractorTypoScript\Tests;
5+
namespace a9f\FractorTypoScript\Tests\TypoScriptStatementsIterator;
66

77
use a9f\Fractor\Application\ValueObject\File;
88
use a9f\Fractor\DependencyInjection\ContainerContainerBuilder;
99
use a9f\Fractor\Exception\ShouldNotHappenException;
10-
use a9f\FractorTypoScript\Tests\Fixture\StatementCollectingVisitor;
10+
use a9f\FractorTypoScript\Tests\TypoScriptStatementsIterator\Fixture\StatementCollectingVisitor;
1111
use a9f\FractorTypoScript\TypoScriptStatementsIterator;
1212
use Helmich\TypoScriptParser\Parser\Parser;
1313
use PHPUnit\Framework\Attributes\Test;

packages/fractor-typoscript/tests/config/config.php packages/fractor-typoscript/tests/TypoScriptStatementsIterator/config/config.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
77

88
return static function (ContainerConfigurator $containerConfigurator, ContainerBuilder $containerBuilder): void {
9-
$containerConfigurator->import(__DIR__ . '/../../config/application.php');
9+
$containerConfigurator->import(__DIR__ . '/../../../config/application.php');
1010
};

0 commit comments

Comments
 (0)