diff --git a/composer.json b/composer.json
index 01343823f..08660fc26 100644
--- a/composer.json
+++ b/composer.json
@@ -117,6 +117,7 @@
"Tempest\\Cache\\Tests\\": "src/Tempest/Cache/tests",
"Tempest\\Clock\\Tests\\": "src/Tempest/Clock/tests",
"Tempest\\CommandBus\\Tests\\": "src/Tempest/CommandBus/tests",
+ "Tempest\\Console\\Tests\\": "src/Tempest/Console/tests",
"Tempest\\Container\\Tests\\": "src/Tempest/Container/tests",
"Tempest\\Core\\Tests\\": "src/Tempest/Core/tests",
"Tempest\\Database\\Tests\\": "src/Tempest/Database/tests",
diff --git a/src/Tempest/Console/composer.json b/src/Tempest/Console/composer.json
index 51ee0b396..fa17699ad 100644
--- a/src/Tempest/Console/composer.json
+++ b/src/Tempest/Console/composer.json
@@ -21,6 +21,11 @@
"Tempest\\Console\\": "src"
}
},
+ "autoload-dev": {
+ "psr-4": {
+ "Tempest\\Console\\Tests\\": "tests"
+ }
+ },
"bin": [
"bin/tempest"
]
diff --git a/src/Tempest/Console/src/Highlight/DynamicTokenType.php b/src/Tempest/Console/src/Highlight/DynamicTokenType.php
new file mode 100644
index 000000000..59dbd7a5e
--- /dev/null
+++ b/src/Tempest/Console/src/Highlight/DynamicTokenType.php
@@ -0,0 +1,46 @@
+style)
+ ->lower()
+ ->replace(['_', '-'], '');
+
+ foreach (TerminalStyle::cases() as $case) {
+ $normalizedCase = str($case->name)
+ ->lower()
+ ->replace(['_', '-'], '');
+
+ if ($normalizedCase->equals($normalizedStyle)) {
+ return $case;
+ }
+ }
+
+ return TerminalStyle::RESET;
+ }
+
+ public function getValue(): string
+ {
+ return '';
+ }
+
+ public function canContain(TokenType $other): bool
+ {
+ return false;
+ }
+}
diff --git a/src/Tempest/Console/src/Highlight/TempestConsoleLanguage/Injections/DynamicInjection.php b/src/Tempest/Console/src/Highlight/TempestConsoleLanguage/Injections/DynamicInjection.php
new file mode 100644
index 000000000..12949c08c
--- /dev/null
+++ b/src/Tempest/Console/src/Highlight/TempestConsoleLanguage/Injections/DynamicInjection.php
@@ -0,0 +1,60 @@
+\", $after)
+ ->toString(),
+ subject: $matches[0],
+ );
+
+ if (preg_match($pattern, $result)) {
+ return $this->parse($result, $highlighter)->content;
+ }
+
+ return $result;
+ },
+ subject: $content,
+ );
+
+ return new ParsedInjection($result ?? $content);
+ }
+}
diff --git a/src/Tempest/Console/src/Highlight/TempestConsoleLanguage/TempestConsoleLanguage.php b/src/Tempest/Console/src/Highlight/TempestConsoleLanguage/TempestConsoleLanguage.php
index 382cdcb73..67139e55c 100644
--- a/src/Tempest/Console/src/Highlight/TempestConsoleLanguage/TempestConsoleLanguage.php
+++ b/src/Tempest/Console/src/Highlight/TempestConsoleLanguage/TempestConsoleLanguage.php
@@ -5,6 +5,7 @@
namespace Tempest\Console\Highlight\TempestConsoleLanguage;
use Tempest\Console\Highlight\TempestConsoleLanguage\Injections\CommentInjection;
+use Tempest\Console\Highlight\TempestConsoleLanguage\Injections\DynamicInjection;
use Tempest\Console\Highlight\TempestConsoleLanguage\Injections\EmphasizeInjection;
use Tempest\Console\Highlight\TempestConsoleLanguage\Injections\ErrorInjection;
use Tempest\Console\Highlight\TempestConsoleLanguage\Injections\H1Injection;
@@ -39,6 +40,7 @@ public function getInjections(): array
new H1Injection(),
new H2Injection(),
new SuccessInjection(),
+ new DynamicInjection(),
];
}
diff --git a/src/Tempest/Console/src/Highlight/TempestTerminalTheme.php b/src/Tempest/Console/src/Highlight/TempestTerminalTheme.php
index af6c40b5f..89c0753f2 100644
--- a/src/Tempest/Console/src/Highlight/TempestTerminalTheme.php
+++ b/src/Tempest/Console/src/Highlight/TempestTerminalTheme.php
@@ -16,6 +16,10 @@
public function before(TokenType $tokenType): string
{
+ if ($tokenType instanceof DynamicTokenType) {
+ return $this->style($tokenType->getStyle());
+ }
+
return match ($tokenType) {
TokenTypeEnum::KEYWORD => $this->style(TerminalStyle::FG_DARK_BLUE),
TokenTypeEnum::PROPERTY => $this->style(TerminalStyle::FG_DARK_GREEN),
diff --git a/src/Tempest/Console/tests/TempestConsoleLanguage/Injections/DynamicInjectionTest.php b/src/Tempest/Console/tests/TempestConsoleLanguage/Injections/DynamicInjectionTest.php
new file mode 100644
index 000000000..7500edb16
--- /dev/null
+++ b/src/Tempest/Console/tests/TempestConsoleLanguage/Injections/DynamicInjectionTest.php
@@ -0,0 +1,38 @@
+foo', "\e[96mfoo\e[0m"])]
+ #[TestWith(['', "\e[101mfoo\e[0m"])]
+ #[TestWith(['', "\e[1mfoo\e[0m"])]
+ #[TestWith(['', "\e[4mfoo\e[0m"])]
+ #[TestWith(['', "\e[0mfoo\e[0m"])]
+ #[TestWith(['', "\e[7mfoo\e[0m"])]
+ #[TestWith(['', "\e[46m\e[96m\e[4mTempest\e[0m\e[0m\e[0m"])]
+ #[TestWith(['', "\e[46m\e[96m\e[4mTempest\e[0m\e[0m\e[0m"])]
+ #[TestWith(['', "\e[96m\e[41mfoo\e[0m\e[0m"])]
+ #[Test]
+ public function language(string $content, string $expected): void
+ {
+ $highlighter = new Highlighter(new TempestTerminalTheme());
+
+ $this->assertSame(
+ $expected,
+ (new DynamicInjection())->parse($content, $highlighter)->content,
+ );
+ }
+}
diff --git a/tests/Integration/Console/Highlight/TempestConsoleLanguage/TempestConsoleLanguageTest.php b/tests/Integration/Console/Highlight/TempestConsoleLanguage/TempestConsoleLanguageTest.php
new file mode 100644
index 000000000..daa2bbe74
--- /dev/null
+++ b/tests/Integration/Console/Highlight/TempestConsoleLanguage/TempestConsoleLanguageTest.php
@@ -0,0 +1,38 @@
+foo', "\e[96mfoo\e[0m"])]
+ #[TestWith(['', "\e[101mfoo\e[0m"])]
+ #[TestWith(['', "\e[1mfoo\e[0m"])]
+ #[TestWith(['', "\e[4mfoo\e[0m"])]
+ #[TestWith(['', "\e[0mfoo\e[0m"])]
+ #[TestWith(['', "\e[7mfoo\e[0m"])]
+ #[TestWith(['', "\e[46m\e[96m\e[4mTempest\e[0m\e[0m\e[0m"])]
+ #[TestWith(['', "\e[46m\e[96m\e[4mTempest\e[0m\e[0m\e[0m"])]
+ #[TestWith(['', "\e[96m\e[41mfoo\e[0m\e[0m"])]
+ #[Test]
+ public function language(string $content, string $expected): void
+ {
+ $highlighter = new Highlighter(new TempestTerminalTheme());
+
+ $this->assertSame(
+ $expected,
+ $highlighter->parse($content, new TempestConsoleLanguage())
+ );
+ }
+}