Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Highlight Laravel Package

tempest/highlight

Fast, extensible server-side code highlighting for PHP and more. Tempest Highlight parses source code into highlighted output with a simple API: instantiate the Highlighter and call parse($code, 'php'). Ideal for docs, blogs, and code previews.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require tempest/highlight
    

    Add the service provider to config/app.php under providers:

    Tempest\Highlight\HighlightServiceProvider::class,
    
  2. Basic Usage:

    use Tempest\Highlight\Highlight;
    
    $highlight = app(Highlight::class);
    $code = '<?php echo "Hello, World!"; ?>';
    $html = $highlight->highlight($code, 'php');
    
  3. First Use Case: Display syntax-highlighted code snippets in a Laravel Blade template:

    // In a controller
    return view('snippets.show', ['highlightedCode' => $highlight->highlight($code, 'php')]);
    
    // In Blade
    {!! $highlightedCode !!}
    

Key Files to Explore

  • config/highlight.php: Default configuration (languages, themes, etc.).
  • vendor/tempest/highlight/src/Highlight.php: Core class documentation.
  • vendor/tempest/highlight/src/Languages/: Predefined language lexers.

Implementation Patterns

Common Workflows

1. Dynamic Language Detection

Use detectLanguage() to auto-detect code language (e.g., for user-uploaded files):

$language = $highlight->detectLanguage($code);
$html = $highlight->highlight($code, $language);

2. Theming

Override the default theme (e.g., solarized-dark) via config or runtime:

$highlight->setTheme('monokai');
$html = $highlight->highlight($code, 'javascript');

3. Line Numbers

Enable line numbers globally in config/highlight.php:

'line_numbers' => true,

Or per-call:

$html = $highlight->highlight($code, 'python', ['line_numbers' => true]);

4. Custom Lexers

Extend existing lexers or create new ones by implementing Tempest\Highlight\Lexer\LexerInterface:

class CustomLexer implements LexerInterface {
    public function tokenize(string $code): array { ... }
}

Register it via the service provider’s extend method.

5. Caching Highlighted Output

Cache results for static code snippets (e.g., documentation):

$cacheKey = 'code_snippet_' . md5($code);
$html = Cache::remember($cacheKey, now()->addHours(1), function () use ($highlight, $code) {
    return $highlight->highlight($code, 'php');
});

6. Integration with Laravel Filesystem

Highlight files directly from storage:

$code = Storage::disk('public')->get('scripts/app.js');
$html = $highlight->highlight($code, 'javascript');

7. API Responses

Return highlighted code in JSON API responses:

return response()->json([
    'code' => $code,
    'highlighted' => $highlight->highlight($code, 'go'),
]);

8. Queueing Heavy Highlighting

Offload highlighting for large files to a queue job:

HighlightJob::dispatch($filePath, 'rust')->delay(now()->addMinute());

Integration Tips

Laravel Mix/Webpack

Use the package to generate static highlighted snippets during build:

// webpack.mix.js
mix.webpackConfig({
    plugins: [
        new LaravelHighlightPlugin({
            files: ['resources/js/snippets/*.js'],
            output: 'public/highlighted-snippets.js',
        }),
    ],
});

Livewire/Alpine.js

Dynamically update highlighted code in real-time:

// Livewire component
public function highlightCode(string $code): string {
    return app(Highlight::class)->highlight($code, 'vue');
}

Markdown Parsing

Integrate with packages like spatie/laravel-markdown:

$markdown = Markdown::parse($content);
$highlighted = preg_replace_callback(
    '/```([\w-]+)\n(.*?)```/s',
    fn($matches) => $highlight->highlight($matches[2], $matches[1]),
    $markdown
);

Testing

Mock the Highlight class in tests:

$this->mock(Highlight::class, function ($mock) {
    $mock->shouldReceive('highlight')
         ->with('<?php ...', 'php')
         ->andReturn('<div class="highlight"><span>...</span></div>');
});

Gotchas and Tips

Pitfalls

  1. Language Mismatch:

    • Issue: Incorrect language specified (e.g., php for HTML) leads to poor highlighting.
    • Fix: Use detectLanguage() or validate against supported languages:
      $supported = $highlight->getSupportedLanguages();
      if (!in_array($language, $supported)) {
          $language = 'text'; // Fallback
      }
      
  2. Performance with Large Files:

    • Issue: Highlighting 10KB+ files can slow responses.
    • Fix: Cache results or use queue jobs. Avoid highlighting in loops.
  3. XSS Risks:

    • Issue: Directly outputting $highlight->highlight() in Blade can expose raw HTML.
    • Fix: Escape output or use {!! !!} only in trusted contexts.
  4. Theme/Style Conflicts:

    • Issue: Custom themes may break with existing CSS.
    • Fix: Inspect generated HTML for classes (e.g., .hljs) and scope styles:
      .highlight { contain: content; } /* Prevent style leaks */
      
  5. Case-Sensitive Language Names:

    • Issue: 'PHP' fails; must use 'php'.
    • Fix: Normalize input:
      $language = strtolower(trim($language));
      
  6. Lexer Overrides Not Loading:

    • Issue: Custom lexers registered in AppServiceProvider are ignored.
    • Fix: Ensure the provider is listed after HighlightServiceProvider:
      $this->app->register(Tempest\Highlight\HighlightServiceProvider::class);
      $this->app->register(CustomHighlightProvider::class);
      

Debugging Tips

  1. Inspect Tokens: Dump lexer tokens to debug highlighting issues:

    $tokens = $highlight->getLexer('php')->tokenize($code);
    dd($tokens); // Check for missing/incorrect token types
    
  2. Enable Debug Mode: Temporarily enable verbose output:

    $highlight->setDebug(true);
    $html = $highlight->highlight($code, 'ruby');
    // Check logs for lexer/parser errors
    
  3. Check for Deprecated Methods: Monitor deprecation notices in Laravel logs if upgrading from older versions.

  4. Validate Config: Ensure config/highlight.php paths (e.g., lexers_path) are correct. Default:

    'lexers_path' => realpath(__DIR__ . '/../../vendor/tempest/highlight/src/Languages'),
    

Extension Points

  1. Custom Themes: Extend the default theme by copying vendor/tempest/highlight/src/Themes/default.css to resources/css/ and overriding classes.

  2. Language Plugins: Dynamically load lexers from a database or API:

    $highlight->addLexer('custom-lang', new CustomLexer());
    
  3. Event Hooks: Listen for highlighting events (e.g., highlighting):

    event(new HighlightingEvent($code, 'python'));
    
  4. Fallback Lexers: Implement a fallback lexer for unsupported languages:

    $highlight->setFallbackLexer(function ($code) {
        return new TextLexer(); // Basic text highlighting
    });
    
  5. Line Number Formatting: Customize line number output via the line_numbers option:

    $html = $highlight->highlight($code, 'css', [
        'line_numbers' => true,
        'line_number_format' => '<span class="line-number">%s</span>',
    ]);
    
  6. Highlighting Directories: Recursively highlight all files in a directory (e.g., for docs):

    $files = Storage::disk('public')->files('snippets');
    foreach ($files as $file) {
        $code = Storage::disk('public')->get($file);
        $html = $highlight->highlight($code, pathinfo($file, PATHINFO_EXTENSION));
        Storage::disk('public')->put("highlighted/{
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport