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 @@ -21,6 +21,7 @@
use Tempest\Highlight\Languages\JavaScript\JavaScriptLanguage;
use Tempest\Highlight\Languages\Json\JsonLanguage;
use Tempest\Highlight\Languages\Markdown\MarkdownLanguage;
use Tempest\Highlight\Languages\Nginx\NginxLanguage;
use Tempest\Highlight\Languages\Php\PhpLanguage;
use Tempest\Highlight\Languages\Python\PythonLanguage;
use Tempest\Highlight\Languages\Scss\ScssLanguage;
Expand Down Expand Up @@ -69,6 +70,7 @@ public function __construct(private readonly Theme $theme = new CssTheme())
->addLanguage(new JavaScriptLanguage())
->addLanguage(new JsonLanguage())
->addLanguage(new MarkdownLanguage())
->addLanguage(new NginxLanguage())
->addLanguage(new PhpLanguage())
->addLanguage(new PythonLanguage())
->addLanguage(new ScssLanguage())
Expand Down
68 changes: 68 additions & 0 deletions src/Languages/Nginx/NginxLanguage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Nginx;

use Override;
use Tempest\Highlight\Languages\Base\BaseLanguage;
use Tempest\Highlight\Languages\Bash\Patterns\BashCommentPattern;
use Tempest\Highlight\Languages\Bash\Patterns\BashNumberPattern;
use Tempest\Highlight\Languages\Nginx\Patterns\NginxBooleanPattern;
use Tempest\Highlight\Languages\Nginx\Patterns\NginxDirectivePattern;
use Tempest\Highlight\Languages\Nginx\Patterns\NginxOperatorPattern;
use Tempest\Highlight\Languages\Nginx\Patterns\NginxVariablePattern;
use Tempest\Highlight\Languages\Php\Patterns\DoubleQuoteValuePattern;
use Tempest\Highlight\Languages\Php\Patterns\SingleQuoteValuePattern;

class NginxLanguage extends BaseLanguage
{
public function getName(): string
{
return 'nginx';
}

#[Override]
public function getAliases(): array
{
return ['nginxconf'];
}

#[Override]
public function getInjections(): array
{
return [
...parent::getInjections(),
];
}

#[Override]
public function getPatterns(): array
{
return [
...parent::getPatterns(),

// COMMENTS
new BashCommentPattern(),

// VALUES
new SingleQuoteValuePattern(),
new DoubleQuoteValuePattern(),

// DIRECTIVES
new NginxDirectivePattern(),

// BOOLEANS
new NginxBooleanPattern(),

// VARIABLES
new NginxVariablePattern(),

// OPERATORS
new NginxOperatorPattern(),

// NUMBERS
new BashNumberPattern(),
];
}
}
27 changes: 27 additions & 0 deletions src/Languages/Nginx/Patterns/NginxBooleanPattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Nginx\Patterns;

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

#[PatternTest(input: 'gzip on;', output: 'on')]
#[PatternTest(input: 'autoindex off;', output: 'off')]
final readonly class NginxBooleanPattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return '\b(?<match>on|off)\b';
}

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

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Nginx\Patterns;

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

#[PatternTest(input: 'server {', output: 'server')]
#[PatternTest(input: 'listen 80;', output: 'listen')]
#[PatternTest(input: ' proxy_pass http://backend;', output: 'proxy_pass')]
final readonly class NginxDirectivePattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
$directives = implode('|', [
'server', 'location', 'listen', 'root', 'index', 'proxy_pass',
'upstream', 'http', 'events', 'worker_processes', 'worker_connections',
'error_log', 'access_log', 'ssl_certificate', 'ssl_certificate_key',
'try_files', 'return', 'rewrite', 'if', 'set', 'map', 'include',
'server_name', 'client_max_body_size', 'keepalive_timeout',
'gzip', 'gzip_types', 'add_header', 'deny', 'allow',
'fastcgi_pass', 'fastcgi_param', 'proxy_set_header',
'proxy_http_version', 'proxy_cache', 'proxy_cache_valid',
'sendfile', 'tcp_nopush', 'tcp_nodelay', 'types', 'default_type',
'log_format', 'expires', 'autoindex', 'charset', 'resolver',
'ssl', 'ssl_protocols', 'ssl_ciphers', 'ssl_prefer_server_ciphers',
'ssl_session_cache', 'ssl_session_timeout',
'limit_req', 'limit_req_zone', 'limit_conn', 'limit_conn_zone',
'geo', 'stub_status',
]);

return "\b(?<match>(?:{$directives}))\b";
}

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

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Nginx\Patterns;

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

#[PatternTest(input: 'listen 80;', output: ';')]
#[PatternTest(input: 'location = /health {', output: '=')]
final readonly class NginxOperatorPattern implements Pattern
{
use IsPattern;

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

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

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Nginx\Patterns;

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

#[PatternTest(input: 'proxy_set_header Host $host;', output: '$host')]
#[PatternTest(input: 'return 301 $scheme://example.com;', output: '$scheme')]
final readonly class NginxVariablePattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return '(?<match>\$[a-zA-Z_]\w*)';
}

public function getTokenType(): TokenTypeEnum
{
return TokenTypeEnum::VARIABLE;
}
}
74 changes: 74 additions & 0 deletions tests/Bench/Fixtures/nginx.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Main Nginx configuration
worker_processes auto;
error_log /var/log/nginx/error.log;

events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
gzip on;
gzip_types text/plain application/json;

log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent';

upstream backend {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}

server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}

server {
listen 443 ssl;
server_name example.com;

ssl_certificate /etc/ssl/certs/example.pem;
ssl_certificate_key /etc/ssl/private/example.key;
ssl_protocols TLSv1.2 TLSv1.3;

root /var/www/html;
index index.html index.htm;

add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";

location / {
try_files $uri $uri/ =404;
}

location /api {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
}

location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
access_log off;
}

location = /health {
stub_status;
allow 127.0.0.1;
deny all;
}

if ($request_uri ~* "^/old-path") {
rewrite ^/old-path(.*)$ /new-path$1 permanent;
}
}
}
1 change: 1 addition & 0 deletions tests/Bench/HighlighterBench.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ final class HighlighterBench
'javascript' => 'javascript.txt',
'json' => 'json.txt',
'markdown' => 'markdown.txt',
'nginx' => 'nginx.txt',
'php' => 'php.txt',
'python' => 'python.txt',
'scss' => 'scss.txt',
Expand Down
Loading
Loading