From 277baedb383669c8c07f5d91c435e4b2ef3b9b3f Mon Sep 17 00:00:00 2001 From: DorZuberi Date: Sat, 4 Apr 2026 16:18:53 +0300 Subject: [PATCH 1/3] Add Apache language support with patterns and tests --- src/Highlighter.php | 4 +- src/Languages/Apache/ApacheLanguage.php | 45 +++++++++++++++ .../Apache/Patterns/ApacheCloseTagPattern.php | 28 ++++++++++ .../Apache/Patterns/ApacheCommentPattern.php | 27 +++++++++ .../Patterns/ApacheDirectivePattern.php | 55 +++++++++++++++++++ .../Apache/Patterns/ApacheFlagPattern.php | 31 +++++++++++ .../Apache/Patterns/ApacheOpenTagPattern.php | 30 ++++++++++ 7 files changed, 219 insertions(+), 1 deletion(-) create mode 100644 src/Languages/Apache/ApacheLanguage.php create mode 100644 src/Languages/Apache/Patterns/ApacheCloseTagPattern.php create mode 100644 src/Languages/Apache/Patterns/ApacheCommentPattern.php create mode 100644 src/Languages/Apache/Patterns/ApacheDirectivePattern.php create mode 100644 src/Languages/Apache/Patterns/ApacheFlagPattern.php create mode 100644 src/Languages/Apache/Patterns/ApacheOpenTagPattern.php diff --git a/src/Highlighter.php b/src/Highlighter.php index 866fe91..a1f01fc 100644 --- a/src/Highlighter.php +++ b/src/Highlighter.php @@ -6,6 +6,7 @@ use ReflectionClass; use Tempest\Highlight\Languages\Base\Injections\GutterInjection; +use Tempest\Highlight\Languages\Apache\ApacheLanguage; use Tempest\Highlight\Languages\Bash\BashLanguage; use Tempest\Highlight\Languages\BBCode\BBCodeLanguage; use Tempest\Highlight\Languages\Blade\BladeLanguage; @@ -55,7 +56,8 @@ final class Highlighter public function __construct(private readonly Theme $theme = new CssTheme()) { - $this->addLanguage(new BashLanguage()) + $this->addLanguage(new ApacheLanguage()) + ->addLanguage(new BashLanguage()) ->addLanguage(new BBCodeLanguage()) ->addLanguage(new BladeLanguage()) ->addLanguage(new CssLanguage()) diff --git a/src/Languages/Apache/ApacheLanguage.php b/src/Languages/Apache/ApacheLanguage.php new file mode 100644 index 0000000..b8dc6e0 --- /dev/null +++ b/src/Languages/Apache/ApacheLanguage.php @@ -0,0 +1,45 @@ +', output: 'VirtualHost')] +#[PatternTest(input: '', output: 'Directory')] +#[PatternTest(input: '', output: 'IfModule')] +final readonly class ApacheCloseTagPattern implements Pattern +{ + use IsPattern; + + public function getPattern(): string + { + return '<\/(?[A-Za-z]\w*)'; + } + + public function getTokenType(): TokenTypeEnum + { + return TokenTypeEnum::KEYWORD; + } +} diff --git a/src/Languages/Apache/Patterns/ApacheCommentPattern.php b/src/Languages/Apache/Patterns/ApacheCommentPattern.php new file mode 100644 index 0000000..2209ccc --- /dev/null +++ b/src/Languages/Apache/Patterns/ApacheCommentPattern.php @@ -0,0 +1,27 @@ +#.*)'; + } + + public function getTokenType(): TokenTypeEnum + { + return TokenTypeEnum::COMMENT; + } +} diff --git a/src/Languages/Apache/Patterns/ApacheDirectivePattern.php b/src/Languages/Apache/Patterns/ApacheDirectivePattern.php new file mode 100644 index 0000000..5b81b3f --- /dev/null +++ b/src/Languages/Apache/Patterns/ApacheDirectivePattern.php @@ -0,0 +1,55 @@ +{$directives})\b/m"; + } + + public function getTokenType(): TokenTypeEnum + { + return TokenTypeEnum::KEYWORD; + } +} diff --git a/src/Languages/Apache/Patterns/ApacheFlagPattern.php b/src/Languages/Apache/Patterns/ApacheFlagPattern.php new file mode 100644 index 0000000..fa240f2 --- /dev/null +++ b/src/Languages/Apache/Patterns/ApacheFlagPattern.php @@ -0,0 +1,31 @@ +on|off|All|None|granted|denied)\b/'; + } + + public function getTokenType(): TokenTypeEnum + { + return TokenTypeEnum::VALUE; + } +} diff --git a/src/Languages/Apache/Patterns/ApacheOpenTagPattern.php b/src/Languages/Apache/Patterns/ApacheOpenTagPattern.php new file mode 100644 index 0000000..22643b9 --- /dev/null +++ b/src/Languages/Apache/Patterns/ApacheOpenTagPattern.php @@ -0,0 +1,30 @@ +', output: 'VirtualHost')] +#[PatternTest(input: '', output: 'Directory')] +#[PatternTest(input: '', output: 'Location')] +#[PatternTest(input: '', output: 'IfModule')] +#[PatternTest(input: '', output: 'FilesMatch')] +final readonly class ApacheOpenTagPattern implements Pattern +{ + use IsPattern; + + public function getPattern(): string + { + return '<(?[A-Za-z]\w*)'; + } + + public function getTokenType(): TokenTypeEnum + { + return TokenTypeEnum::KEYWORD; + } +} From 7f337e89285b327e7e4faca8d7308bc95f728fb2 Mon Sep 17 00:00:00 2001 From: DorZuberi Date: Sat, 4 Apr 2026 16:20:12 +0300 Subject: [PATCH 2/3] Add Apache language tests and fixtures --- tests/Bench/Fixtures/apache.txt | 37 ++++++++ tests/Bench/HighlighterBench.php | 1 + tests/Languages/Apache/ApacheLanguageTest.php | 84 +++++++++++++++++++ 3 files changed, 122 insertions(+) create mode 100644 tests/Bench/Fixtures/apache.txt create mode 100644 tests/Languages/Apache/ApacheLanguageTest.php diff --git a/tests/Bench/Fixtures/apache.txt b/tests/Bench/Fixtures/apache.txt new file mode 100644 index 0000000..d289e05 --- /dev/null +++ b/tests/Bench/Fixtures/apache.txt @@ -0,0 +1,37 @@ +# Apache2 Virtual Host Configuration + + + ServerAdmin webmaster@example.com + ServerName example.com + ServerAlias www.example.com + DocumentRoot /var/www/html + + + Options -Indexes +FollowSymLinks + AllowOverride All + Require all granted + + + ErrorLog ${APACHE_LOG_DIR}/error.log + CustomLog ${APACHE_LOG_DIR}/access.log combined + + RewriteEngine on + RewriteCond %{HTTPS} off + RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] + + + + ServerName example.com + DocumentRoot /var/www/html + + SSLEngine on + SSLCertificateFile "/etc/ssl/certs/server.crt" + SSLCertificateKeyFile "/etc/ssl/private/server.key" + + + Header always set Strict-Transport-Security "max-age=31536000" + + + ProxyPass /api http://localhost:3000 + ProxyPassReverse /api http://localhost:3000 + diff --git a/tests/Bench/HighlighterBench.php b/tests/Bench/HighlighterBench.php index 9c8d83a..d24e4c5 100644 --- a/tests/Bench/HighlighterBench.php +++ b/tests/Bench/HighlighterBench.php @@ -17,6 +17,7 @@ final class HighlighterBench private const string FIXTURES_DIR = __DIR__ . '/Fixtures'; public const array LANGUAGES = [ + 'apache' => 'apache.txt', 'bash' => 'bash.txt', 'bbcode' => 'bbcode.txt', 'blade' => 'blade.txt', diff --git a/tests/Languages/Apache/ApacheLanguageTest.php b/tests/Languages/Apache/ApacheLanguageTest.php new file mode 100644 index 0000000..22623df --- /dev/null +++ b/tests/Languages/Apache/ApacheLanguageTest.php @@ -0,0 +1,84 @@ +assertSame( + $expected, + $highlighter->parse($content, 'apache'), + ); + + $this->assertSame($expected, $highlighter->parse($content, 'apacheconf')); + $this->assertSame($expected, $highlighter->parse($content, 'htaccess')); + } + + public static function provide_highlight_cases(): iterable + { + return [ + 'comments' => [ + <<<'APACHE' + # This is a comment + ServerName example.com + APACHE, + '# This is a comment +ServerName example.com', + ], + 'virtual host block' => [ + <<<'APACHE' + + ServerName example.com + DocumentRoot "/var/www/html" + + APACHE, + '<VirtualHost *:80> + ServerName example.com + DocumentRoot "/var/www/html" +</VirtualHost>', + ], + 'rewrite rules' => [ + <<<'APACHE' + RewriteEngine on + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^(.*)$ index.php [L] + APACHE, + 'RewriteEngine on +RewriteCond %{REQUEST_FILENAME} !-f +RewriteRule ^(.*)$ index.php [L]', + ], + 'ssl configuration' => [ + <<<'APACHE' + SSLEngine on + SSLCertificateFile "/etc/ssl/certs/server.crt" + APACHE, + 'SSLEngine on +SSLCertificateFile "/etc/ssl/certs/server.crt"', + ], + 'directory block with flags' => [ + <<<'APACHE' + + Options All + AllowOverride None + Require all granted + + APACHE, + '<Directory /var/www> + Options All + AllowOverride None + Require all granted +</Directory>', + ], + ]; + } +} From 2feefeb177c0b6037e9ecb4724da68b990f8c89f Mon Sep 17 00:00:00 2001 From: DorZuberi Date: Sat, 4 Apr 2026 16:20:58 +0300 Subject: [PATCH 3/3] Fix namespace order in Highlighter.php imports --- src/Highlighter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Highlighter.php b/src/Highlighter.php index a1f01fc..d8ab5ea 100644 --- a/src/Highlighter.php +++ b/src/Highlighter.php @@ -5,8 +5,8 @@ namespace Tempest\Highlight; use ReflectionClass; -use Tempest\Highlight\Languages\Base\Injections\GutterInjection; use Tempest\Highlight\Languages\Apache\ApacheLanguage; +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;