Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/Highlighter.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use ReflectionClass;
use Tempest\Highlight\Languages\Base\Injections\GutterInjection;
use Tempest\Highlight\Languages\Bash\BashLanguage;
use Tempest\Highlight\Languages\BBCode\BBCodeLanguage;
use Tempest\Highlight\Languages\Blade\BladeLanguage;
use Tempest\Highlight\Languages\Css\CssLanguage;
use Tempest\Highlight\Languages\Diff\DiffLanguage;
Expand Down Expand Up @@ -54,6 +55,7 @@ final class Highlighter
public function __construct(private readonly Theme $theme = new CssTheme())
{
$this->addLanguage(new BashLanguage())
->addLanguage(new BBCodeLanguage())
->addLanguage(new BladeLanguage())
->addLanguage(new CssLanguage())
->addLanguage(new DiffLanguage())
Expand Down
30 changes: 30 additions & 0 deletions src/Languages/BBCode/BBCodeLanguage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\BBCode;

use Override;
use Tempest\Highlight\Languages\Base\BaseLanguage;
use Tempest\Highlight\Languages\BBCode\Patterns\BBCodeAttributePattern;
use Tempest\Highlight\Languages\BBCode\Patterns\BBCodeCloseTagPattern;
use Tempest\Highlight\Languages\BBCode\Patterns\BBCodeTagPattern;

class BBCodeLanguage extends BaseLanguage
{
public function getName(): string
{
return 'bbcode';
}

#[Override]
public function getPatterns(): array
{
return [
...parent::getPatterns(),
new BBCodeAttributePattern(),
new BBCodeTagPattern(),
new BBCodeCloseTagPattern(),
];
}
}
30 changes: 30 additions & 0 deletions src/Languages/BBCode/Patterns/BBCodeAttributePattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\BBCode\Patterns;

use Tempest\Highlight\IsPattern;
use Tempest\Highlight\Pattern;
use Tempest\Highlight\PatternTest;
use Tempest\Highlight\Tokens\TokenTypeEnum;

#[PatternTest(input: '[url=http://example.com]link[/url]', output: 'http://example.com')]
#[PatternTest(input: '[color=#ff0000]red[/color]', output: '#ff0000')]
#[PatternTest(input: '[size=14]text[/size]', output: '14')]
#[PatternTest(input: '[quote=John]hello[/quote]', output: 'John')]
#[PatternTest(input: '[b]no attribute[/b]', output: null)]
final readonly class BBCodeAttributePattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return '\[\w+=(?<match>[^\]]+)\]';
}

public function getTokenType(): TokenTypeEnum
{
return TokenTypeEnum::ATTRIBUTE;
}
}
29 changes: 29 additions & 0 deletions src/Languages/BBCode/Patterns/BBCodeCloseTagPattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\BBCode\Patterns;

use Tempest\Highlight\IsPattern;
use Tempest\Highlight\Pattern;
use Tempest\Highlight\PatternTest;
use Tempest\Highlight\Tokens\TokenTypeEnum;

#[PatternTest(input: '[/b]', output: 'b')]
#[PatternTest(input: '[/url]', output: 'url')]
#[PatternTest(input: '[/code]', output: 'code')]
#[PatternTest(input: '[/quote]', output: 'quote')]
final readonly class BBCodeCloseTagPattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return '\[\/(?<match>[a-zA-Z]+)\]';
}

public function getTokenType(): TokenTypeEnum
{
return TokenTypeEnum::KEYWORD;
}
}
31 changes: 31 additions & 0 deletions src/Languages/BBCode/Patterns/BBCodeTagPattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\BBCode\Patterns;

use Tempest\Highlight\IsPattern;
use Tempest\Highlight\Pattern;
use Tempest\Highlight\PatternTest;
use Tempest\Highlight\Tokens\TokenTypeEnum;

#[PatternTest(input: '[b]bold text[/b]', output: 'b')]
#[PatternTest(input: '[url=http://example.com]link[/url]', output: 'url')]
#[PatternTest(input: '[img]image.png[/img]', output: 'img')]
#[PatternTest(input: '[*]list item', output: '*')]
#[PatternTest(input: '[color=#ff0000]red[/color]', output: 'color')]
#[PatternTest(input: '[list]', output: 'list')]
final readonly class BBCodeTagPattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return '\[(?<match>[a-zA-Z\*]+)[\]=]';
}

public function getTokenType(): TokenTypeEnum
{
return TokenTypeEnum::KEYWORD;
}
}
29 changes: 29 additions & 0 deletions tests/Bench/Fixtures/bbcode.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[b]Bold text[/b]
[i]Italic text[/i]
[u]Underlined text[/u]
[s]Strikethrough[/s]

[url=http://example.com]Click here[/url]
[img]http://example.com/image.png[/img]

[color=#ff0000]Red text[/color]
[size=18]Big text[/size]

[quote=John]
This is a quoted message.
[/quote]

[code]
echo "Hello World";
[/code]

[list]
[*]First item
[*]Second item
[*]Third item
[/list]

[table]
[tr][th]Header[/th][th]Header 2[/th][/tr]
[tr][td]Cell 1[/td][td]Cell 2[/td][/tr]
[/table]
1 change: 1 addition & 0 deletions tests/Bench/HighlighterBench.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ final class HighlighterBench

public const array LANGUAGES = [
'bash' => 'bash.txt',
'bbcode' => 'bbcode.txt',
'blade' => 'blade.txt',
'css' => 'css.txt',
'diff' => 'diff.txt',
Expand Down
78 changes: 78 additions & 0 deletions tests/Languages/BBCode/BBCodeLanguageTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Tests\Languages\BBCode;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Tempest\Highlight\Highlighter;

class BBCodeLanguageTest extends TestCase
{
#[DataProvider('provide_highlight_cases')]
public function test_highlight(string $content, string $expected): void
{
$highlighter = new Highlighter();

$this->assertSame(
$expected,
$highlighter->parse($content, 'bbcode'),
);
}

public static function provide_highlight_cases(): iterable
{
return [
[<<<'TXT'
[b]Hello World[/b]
[i]italic text[/i]
[u]underlined[/u]
[s]strikethrough[/s]
TXT,
<<<'TXT'
[<span class="hl-keyword">b</span>]Hello World[/<span class="hl-keyword">b</span>]
[<span class="hl-keyword">i</span>]italic text[/<span class="hl-keyword">i</span>]
[<span class="hl-keyword">u</span>]underlined[/<span class="hl-keyword">u</span>]
[<span class="hl-keyword">s</span>]strikethrough[/<span class="hl-keyword">s</span>]
TXT],

[<<<'TXT'
[url=http://example.com]Click here[/url]
[color=#ff0000]Red text[/color]
[size=18]Big text[/size]
[quote=John]Hello there[/quote]
TXT,
<<<'TXT'
[<span class="hl-keyword">url</span>=<span class="hl-attribute">http://example.com</span>]Click here[/<span class="hl-keyword">url</span>]
[<span class="hl-keyword">color</span>=<span class="hl-attribute">#ff0000</span>]Red text[/<span class="hl-keyword">color</span>]
[<span class="hl-keyword">size</span>=<span class="hl-attribute">18</span>]Big text[/<span class="hl-keyword">size</span>]
[<span class="hl-keyword">quote</span>=<span class="hl-attribute">John</span>]Hello there[/<span class="hl-keyword">quote</span>]
TXT],

[<<<'TXT'
[list]
[*]First item
[*]Second item
[*]Third item
[/list]
TXT,
<<<'TXT'
[<span class="hl-keyword">list</span>]
[<span class="hl-keyword">*</span>]First item
[<span class="hl-keyword">*</span>]Second item
[<span class="hl-keyword">*</span>]Third item
[/<span class="hl-keyword">list</span>]
TXT],

[<<<'TXT'
[img]http://example.com/image.png[/img]
[code]echo "hello";[/code]
TXT,
<<<'TXT'
[<span class="hl-keyword">img</span>]http://example.com/image.png[/<span class="hl-keyword">img</span>]
[<span class="hl-keyword">code</span>]echo &quot;hello&quot;;[/<span class="hl-keyword">code</span>]
TXT],
];
}
}
Loading