|
| 1 | +<?php |
| 2 | + |
| 3 | +namespace Laravelsu\Highlight\Themes; |
| 4 | + |
| 5 | +use Exception; |
| 6 | +use Tempest\Highlight\Highlighter; |
| 7 | +use Tempest\Highlight\Theme; |
| 8 | +use Tempest\Highlight\Themes\EscapesWebTheme; |
| 9 | +use Tempest\Highlight\Tokens\TokenType; |
| 10 | +use Tempest\Highlight\Tokens\TokenTypeEnum; |
| 11 | +use Tempest\Highlight\WebTheme; |
| 12 | + |
| 13 | +final class InlineTheme implements Theme, WebTheme |
| 14 | +{ |
| 15 | + use EscapesWebTheme; |
| 16 | + |
| 17 | + private array $map = []; |
| 18 | + |
| 19 | + public function __construct(string $themePath) |
| 20 | + { |
| 21 | + $contents = @file_get_contents($themePath); |
| 22 | + |
| 23 | + if ($contents === false) { |
| 24 | + throw new Exception("No valid CSS file found at path {$themePath}"); |
| 25 | + } |
| 26 | + |
| 27 | + preg_match_all('/(?<selector>[\w,\.\s\-]+){(?<style>(.|\n)*?)}/', $contents, $matches); |
| 28 | + |
| 29 | + foreach ($matches[0] as $key => $match) { |
| 30 | + $selector = trim($matches['selector'][$key]); |
| 31 | + $style = str_replace([PHP_EOL, ' ', "\t"], [' ', '', ''], trim($matches['style'][$key])); |
| 32 | + |
| 33 | + $this->map[$selector] = $style; |
| 34 | + } |
| 35 | + } |
| 36 | + |
| 37 | + public function before(TokenType $tokenType): string |
| 38 | + { |
| 39 | + if ($tokenType === TokenTypeEnum::HIDDEN) { |
| 40 | + return '<span style="display: none">'; |
| 41 | + } |
| 42 | + |
| 43 | + $class = match ($tokenType) { |
| 44 | + TokenTypeEnum::KEYWORD => 'hl-keyword', |
| 45 | + TokenTypeEnum::OPERATOR => 'hl-operator', |
| 46 | + TokenTypeEnum::TYPE => 'hl-type', |
| 47 | + TokenTypeEnum::VALUE => 'hl-value', |
| 48 | + TokenTypeEnum::VARIABLE => 'hl-variable', |
| 49 | + TokenTypeEnum::PROPERTY => 'hl-property', |
| 50 | + TokenTypeEnum::ATTRIBUTE => 'hl-attribute', |
| 51 | + TokenTypeEnum::GENERIC => 'hl-generic', |
| 52 | + TokenTypeEnum::NUMBER => 'hl-number', |
| 53 | + TokenTypeEnum::LITERAL => 'hl-literal', |
| 54 | + TokenTypeEnum::COMMENT => 'hl-comment', |
| 55 | + TokenTypeEnum::INJECTION => 'hl-injection', |
| 56 | + default => $tokenType->getValue(), |
| 57 | + }; |
| 58 | + |
| 59 | + $style = $this->map[".{$class}"] ?? null; |
| 60 | + |
| 61 | + if (! $style) { |
| 62 | + return "<span class=\"{$class}\">"; |
| 63 | + } |
| 64 | + |
| 65 | + return "<span style=\"{$style}\">"; |
| 66 | + } |
| 67 | + |
| 68 | + public function after(TokenType $tokenType): string |
| 69 | + { |
| 70 | + return '</span>'; |
| 71 | + } |
| 72 | + |
| 73 | + public function preBefore(Highlighter $highlighter): string |
| 74 | + { |
| 75 | + $preStyle = $this->map['pre'] ?? $this->map['pre, code'] ?? ''; |
| 76 | + |
| 77 | + return "<pre><code data-lang=\"{$highlighter->getCurrentLanguage()->getName()}\" class=\"notranslate\" style=\"{$preStyle}\">"; |
| 78 | + } |
| 79 | + |
| 80 | + public function preAfter(Highlighter $highlighter): string |
| 81 | + { |
| 82 | + return '</code></pre>'; |
| 83 | + } |
| 84 | +} |
0 commit comments