Skip to content

Commit 6f457af

Browse files
authored
feat(console): add support for printing hyperlinks (#850)
1 parent 4099b40 commit 6f457af

File tree

4 files changed

+69
-0
lines changed

4 files changed

+69
-0
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Console\Highlight\TempestConsoleLanguage\Injections;
6+
7+
use Tempest\Highlight\Highlighter;
8+
use Tempest\Highlight\Injection;
9+
use Tempest\Highlight\ParsedInjection;
10+
use function Tempest\Support\str;
11+
12+
final readonly class LinkInjection implements Injection
13+
{
14+
public function parse(string $content, Highlighter $highlighter): ParsedInjection
15+
{
16+
return new ParsedInjection(preg_replace_callback(
17+
subject: $content,
18+
pattern: '/(?<match>\<href=\"(?<href>.+)\"\>(?:(?!\<href).)*?\<\/href\>)/',
19+
callback: function (array $matches) {
20+
$match = $matches['match'];
21+
$href = $matches['href'];
22+
23+
return str($match)
24+
->replaceFirst("<href=\"{$href}\">", "\x1b]8;;{$href}\x1b\\")
25+
->replaceLast('</href>', "\x1b]8;;\x1b\\")
26+
->toString();
27+
},
28+
));
29+
}
30+
}

src/Tempest/Console/src/Highlight/TempestConsoleLanguage/TempestConsoleLanguage.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Tempest\Console\Highlight\TempestConsoleLanguage\Injections\EmphasizeInjection;
99
use Tempest\Console\Highlight\TempestConsoleLanguage\Injections\H1Injection;
1010
use Tempest\Console\Highlight\TempestConsoleLanguage\Injections\H2Injection;
11+
use Tempest\Console\Highlight\TempestConsoleLanguage\Injections\LinkInjection;
1112
use Tempest\Console\Highlight\TempestConsoleLanguage\Injections\StrongInjection;
1213
use Tempest\Console\Highlight\TempestConsoleLanguage\Injections\UnderlineInjection;
1314
use Tempest\Highlight\Language;
@@ -27,6 +28,7 @@ public function getAliases(): array
2728
public function getInjections(): array
2829
{
2930
return [
31+
new LinkInjection(),
3032
new EmphasizeInjection(),
3133
new StrongInjection(),
3234
new UnderlineInjection(),
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Console\Tests\TempestConsoleLanguage\Injections;
6+
7+
use PHPUnit\Framework\Attributes\Test;
8+
use PHPUnit\Framework\Attributes\TestWith;
9+
use PHPUnit\Framework\TestCase;
10+
use Tempest\Console\Highlight\TempestConsoleLanguage\Injections\LinkInjection;
11+
use Tempest\Console\Highlight\TempestTerminalTheme;
12+
use Tempest\Highlight\Highlighter;
13+
14+
/**
15+
* @internal
16+
*/
17+
final class LinkInjectionTest extends TestCase
18+
{
19+
#[Test]
20+
#[TestWith(['<href="https://tempestphp.com">Tempest</href>', "\e]8;;https://tempestphp.com\e\Tempest\e]8;;\e\\"])]
21+
#[TestWith(['<href="http://example.com/path?param=value!@#$%^&*()_+-={}:<>?,./">My link</href>', "\e]8;;http://example.com/path?param=value!@#$%^&*()_+-={}:<>?,./\e\My link\e]8;;\e\\"])]
22+
#[TestWith(['<href="tel:+1234567890">My link</href>', "\e]8;;tel:+1234567890\e\My link\e]8;;\e\\"])]
23+
#[TestWith(['<href="mailto:[email protected]">My link</href>', "\e]8;;mailto:[email protected]\e\My link\e]8;;\e\\"])]
24+
public function language(string $content, string $expected): void
25+
{
26+
$highlighter = new Highlighter(new TempestTerminalTheme());
27+
28+
$this->assertSame(
29+
$expected,
30+
(new LinkInjection())->parse($content, $highlighter)->content,
31+
);
32+
}
33+
}

tests/Integration/Console/Highlight/TempestConsoleLanguage/TempestConsoleLanguageTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ final class TempestConsoleLanguageTest extends TestCase
2929
#[TestWith(['<style="dim"><style="bg-dark-red fg-white">foo</style></style>', "\e[2m\e[41m\e[97mfoo\e[49m\e[39m\e[22m"])]
3030
#[TestWith(['<style="fg-cyan">cyan</style>unstyled<style="bg-dark-red">dark red</style>', "\e[96mcyan\e[39munstyled\e[41mdark red\e[49m"])]
3131
#[TestWith(['<style="dim"><style="fg-gray">dim-gray</style> just-gray</style>', "\e[2m\e[90mdim-gray\e[39m just-gray\e[22m"])]
32+
#[TestWith(['<em>Tempest</em>', "\e[1m\e[4mTempest\e[22m\e[24m"])]
33+
#[TestWith(['<href="https://tempestphp.com">Tempest</href>', "\e]8;;https://tempestphp.com\e\Tempest\e]8;;\e\\"])]
34+
#[TestWith(['<em><href="https://tempestphp.com">Tempest</href></em>', "\e[1m\e[4m\e]8;;https://tempestphp.com\e\Tempest\e]8;;\e\\\e[22m\e[24m"])]
35+
#[TestWith(['<style="fg-cyan"><href="https://tempestphp.com">Tempest</href></style>', "\e[96m\e]8;;https://tempestphp.com\e\Tempest\e]8;;\e\\\e[39m"])]
3236
public function language(string $content, string $expected): void
3337
{
3438
$highlighter = new Highlighter(new TempestTerminalTheme());

0 commit comments

Comments
 (0)