tempest/highlight
Fast, extensible server-side syntax highlighting for PHP. Tempest Highlight parses code with a simple Highlighter API and supports multiple languages for rendering highlighted output in apps, docs, and tooling—install via Composer and start highlighting in minutes.
Installation:
composer require tempest/highlight
Add to composer.json if using Laravel's autoloader:
"autoload": {
"psr-4": {
"App\\": "app/",
"Tempest\\Highlight\\": "vendor/tempest/highlight/src/"
}
}
Run composer dump-autoload.
First Usage:
use Tempest\Highlight\Highlighter;
$highlighter = new Highlighter();
$highlighted = $highlighter->parse('<?php echo "Hello"; ?>', 'php');
echo $highlighted;
Key Classes:
Highlighter: Core class for parsing and rendering.Renderer\HtmlRenderer: Default HTML renderer (extend for custom output).Language\LanguageManager: Registers and manages language definitions.Add a Blade directive to highlight code snippets:
// app/Providers/AppServiceProvider.php
use Tempest\Highlight\Highlighter;
public function boot()
{
Blade::directive('highlight', function ($expression) {
$highlighter = new Highlighter();
$language = $expression ?? 'text';
return "<?php echo (new \\Tempest\\Highlight\\Highlighter())->parse(" . $expression . ", '{$language}'); ?>";
});
}
Usage in Blade:
@highlight('return $this->parse($code, $language);', 'php')
$highlighter->registerLanguage(new \Tempest\Highlight\Language\CustomLanguage('custom', $rules));
Extend Renderer\AbstractRenderer for custom output (e.g., JSON, ANSI for CLI):
use Tempest\Highlight\Renderer\AbstractRenderer;
class JsonRenderer extends AbstractRenderer {
public function renderToken(Token $token): string {
return json_encode([
'text' => $token->getText(),
'type' => $token->getType(),
]);
}
}
Register it:
$highlighter->setRenderer(new JsonRenderer());
default, github, monokai, catppuccin, etc.$highlighter->setTheme('custom', [
'keyword' => '#ff0000',
'string' => '#00ff00',
]);
$cache = new \Symfony\Component\Cache\Adapter\FilesystemAdapter();
$highlighter->setCache($cache);
$highlighter->setGutter(false);
return response()->json([
'code' => $highlighter->parse($request->code, $request->language),
]);
spatie/laravel-markdown):
$markdown = Markdown::parse("# Code Example\n```php\n<?php echo 'Hello'; ?>\n```");
$highlighted = $highlighter->parse($markdown->getContent(), 'php');
Highlight code in Artisan commands or terminal output:
use Symfony\Component\Console\Style\SymfonyStyle;
$io = new SymfonyStyle($input, $output);
$io->text($highlighter->parse($code, 'bash', 'terminal'));
Language Auto-Detection:
'php', 'javascript').$highlighter->setFallbackLanguage('text');
Whitespace Sensitivity:
$highlighter->setTrimCode(false);
Blade Template Conflicts:
@highlight(e('<?php echo $dynamic_code; ?>'), 'php')
Terminal Output:
$highlighter->setRenderer(new \Tempest\Highlight\Renderer\HtmlRenderer());
Inspect Tokens: Enable debug mode to see tokenized output:
$highlighter->setDebug(true);
$tokens = $highlighter->tokenize('<?php echo 1; ?>', 'php');
dd($tokens);
Language-Specific Issues:
use Tempest\Highlight\Language\PhpLanguage;
class CustomPhpLanguage extends PhpLanguage {
protected function getRules(): array {
return array_merge(parent::getRules(), [
// Add custom rules here
]);
}
}
$highlighter->registerLanguage(new CustomPhpLanguage());
Performance Bottlenecks:
phpbench (included in the package). Common optimizations:
Theme Variables:
$background). Use setThemeVariables to override:
$highlighter->setThemeVariables('catppuccin', [
'background' => '#1e1e2e',
]);
Line Numbers:
$highlighter->setGutter(false);
$highlighter->setThemeVariables('default', [
'gutter' => [
'background' => '#f0f0f0',
'color' => '#333',
],
]);
Fallback Behavior:
text. Set a custom fallback:
$highlighter->setFallbackLanguage('markdown');
Add a New Language:
Tempest\Highlight\Language\AbstractLanguage.getRules().$highlighter->registerLanguage(new CustomLanguage());
Custom Renderers:
AbstractRenderer and implement renderToken(). Example for ANSI output:
class AnsiRenderer extends AbstractRenderer {
public function renderToken(Token $token): string {
$styles = $this->getStyle($token->getType());
return "\033[{$styles}m{$token->getText()}\033[0m";
}
}
Hooks for Post-Processing:
postProcess method to modify output:
$highlighter->setPostProcess(function ($html) {
return str_replace('<span class="keyword">', '<strong>', $html);
});
Service Provider Binding: Bind the highlighter to the container for dependency injection:
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->singleton(Highlighter::class, function ($app) {
return new Highlighter();
});
}
Usage in controllers:
use Tempest\Highlight\Highlighter;
public function showCode(Highlighter $highlighter) {
return $highlighter->parse($request->code, $request->language);
}
Caching Highlighted Code: Use Laravel’s cache to store highlighted snippets:
$cacheKey = "highlighted_{$language}_{md5($code)}";
$highlighted = cache()->remember($cacheKey, now
How can I help you explore Laravel packages today?