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

Pygments Laravel Package

kzykhys/pygments

Thin PHP wrapper around the Python Pygments syntax highlighter. Highlight code to HTML/ANSI, generate CSS for styles (e.g., monokai), guess lexer by filename, and list available lexers/formatters/styles. Supports custom pygmentize path.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install Dependencies:
    sudo easy_install Pygments  # Install Python Pygments
    composer require kzykhys/pygments
    
  2. Basic Usage:
    use KzykHys\Pygments\Pygments;
    
    $pygments = new Pygments();
    $highlighted = $pygments->highlight('<?php echo "Hello"; ?>', 'php', 'html');
    
  3. First Use Case:
    • Render syntax-highlighted code snippets in a Laravel Blade template:
      <pre>{{ app(Pygments::class)->highlight($code, 'php') }}</pre>
      

Where to Look First

  • Class Reference: Focus on these core methods:
    • highlight(string $code, string $lexer, string $formatter = 'html')
    • getLexers(), getFormatters(), getStyles()
    • guessLexer(string $filename)
  • Configuration: Check if pygmentize is in your PATH or specify a custom path:
    $pygments = new Pygments('/usr/local/bin/pygmentize');
    

Implementation Patterns

Core Workflows

1. Dynamic Code Snippet Highlighting

  • Pattern: Use in API documentation or blog posts.
  • Example:
    // In a Laravel controller
    public function showCodeExample(Request $request) {
        $code = file_get_contents(storage_path('app/code/example.js'));
        $highlighted = app(Pygments::class)->highlight($code, 'javascript');
        return view('docs.example', ['code' => $highlighted]);
    }
    
  • Blade Integration:
    @component('components.code-block', ['code' => $code, 'language' => 'php'])
    @endcomponent
    

2. Lexer Auto-Detection

  • Pattern: Guess language from filename for user uploads.
  • Example:
    $lexer = app(Pygments::class)->guessLexer('app/Http/Controllers/UserController.php');
    // Outputs: 'php'
    

3. CSS Generation for Theming

  • Pattern: Customize syntax highlighting themes.
  • Example:
    $css = app(Pygments::class)->getCss('monokai', '.code-block');
    file_put_contents(public_path('css/syntax.css'), $css);
    

4. ANSI Output for CLI Tools

  • Pattern: Use in Laravel Artisan commands or terminal output.
  • Example:
    $ansiCode = app(Pygments::class)->highlight('print("Hello")', 'python', 'ansi');
    echo $ansiCode; // Renders colored output in terminal
    

Integration Tips

Laravel Service Container

Register the wrapper as a singleton in AppServiceProvider:

public function register()
{
    $this->app->singleton(Pygments::class, function ($app) {
        return new \KzykHys\Pygments\Pygments('/usr/bin/pygmentize');
    });
}

Caching Highlighted Code

Avoid repeated Python process spawning:

$cacheKey = "pygments:{$lexer}:".md5($code);
$highlighted = cache()->remember($cacheKey, now()->addHours(1), function () use ($code, $lexer) {
    return app(Pygments::class)->highlight($code, $lexer);
});

Blade Directives

Create reusable syntax:

Blade::directive('highlight', function ($expression) {
    return "<?php echo app('Pygments')->highlight({$expression[0]}, '{$expression[1]}'); ?>";
});

Usage:

@highlight($code, 'php')

Formatter Flexibility

Support multiple output formats (HTML, ANSI, LaTeX):

$html = app(Pygments::class)->highlight($code, 'python', 'html');
$latex = app(Pygments::class)->highlight($code, 'python', 'latex');

Gotchas and Tips

Pitfalls

  1. Python Dependency:

    • Issue: Servers may lack Python/Pygments (e.g., Heroku, Lambda).
    • Fix: Use a Docker container with Python preinstalled or document setup steps for deployments.
  2. Shell Injection Vulnerabilities:

    • Issue: Unsanitized input in highlight() can execute arbitrary shell commands.
    • Fix: Validate $lexer and $formatter against allowed lists:
      $allowedLexers = ['php', 'javascript', 'python', 'sql'];
      if (!in_array($lexer, $allowedLexers)) {
          throw new \InvalidArgumentException("Invalid lexer: {$lexer}");
      }
      
  3. Performance Overhead:

    • Issue: Spawning Python processes adds ~100–200ms latency per request.
    • Fix: Cache aggressively or use client-side JS alternatives (e.g., Prism.js) for non-critical content.
  4. PHP Version Conflicts:

    • Issue: Package uses deprecated PHP 5.3+ features (e.g., create_function).
    • Fix: Fork the package for PHP 8.x compatibility or use a polyfill.
  5. Lexer/Formatter Limitations:

    • Issue: Not all Pygments lexers/formatters are exposed via the wrapper.
    • Fix: Check getLexers() and getFormatters() for supported options.

Debugging Tips

  1. Verify pygmentize Path:

    which pygmentize  # Should return /usr/bin/pygmentize or similar
    

    If missing, install Pygments:

    pip install Pygments
    
  2. Check Python Version:

    • Ensure Python 2.4+ is installed (Pygments.php may not support Python 3.x).
  3. Log Errors: Wrap calls in try-catch to log failures:

    try {
        $highlighted = app(Pygments::class)->highlight($code, $lexer);
    } catch (\Exception $e) {
        Log::error("Pygments error: {$e->getMessage()}");
        $highlighted = "<pre><code>{$code}</code></pre>"; // Fallback
    }
    
  4. Test Lexer Guessing:

    $lexer = app(Pygments::class)->guessLexer('example.go');
    // Debug: var_dump($lexer); // Should output 'go'
    

Extension Points

  1. Custom Lexers/Formatters:

    • Extend the wrapper to support additional Pygments options by modifying the highlight() method to pass extra arguments to pygmentize.
  2. Fallback Mechanisms:

    • Implement a fallback to a simpler highlighter (e.g., highlight_string in PHP) if Pygments fails:
      public function highlight($code, $lexer, $formatter = 'html') {
          try {
              return parent::highlight($code, $lexer, $formatter);
          } catch (\Exception $e) {
              return highlight_string($code, true);
          }
      }
      
  3. Docker Integration:

    • Use a multi-stage Docker build to include Python/Pygments only during build:
      # Build stage
      FROM python:2.7 as builder
      RUN pip install Pygments
      
      # Runtime stage
      FROM php:8.1-apache
      COPY --from=builder /usr/local/bin/pygmentize /usr/local/bin/
      
  4. Configuration Management:

    • Store the pygmentize path in .env:
      PYGMENTIZE_PATH=/usr/bin/pygmentize
      
    • Load it dynamically:
      $pygments = new Pygments(config('pygments.path'));
      

Pro Tips

  1. Batch Processing:

    • For bulk highlighting (e.g., migrating old docs), use batch processing:
      $files = glob(storage_path('app/code/*.php'));
      foreach ($files as $file) {
          $code = file_get_contents($file);
          $highlighted = app(Pygments::class)->highlight($code, 'php');
          file_put_contents($file, $highlighted);
      }
      
  2. ANSI to HTML Conversion:

    • Convert ANSI output to HTML for web use:
      $ansi = app(Pygments::class)->highlight($code, 'python', 'ansi');
      $html = preg_replace('/\x1b\[([0-9;]+)?m/', '', $ansi); // Strip ANSI codes
      
  3. Lexer Prioritization:

    • Override auto-detected lexers for edge cases:
      $lexer = app(Pygments::class)->guessLexer('config.yaml');
      if ($lexer === 'yaml')
      
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.
codraw/entity-migrator
codraw/doctrine-extra
codraw/aws-tool-kit
codraw/validator
codraw/workflow
codraw/open-api
codraw/cron-job
codraw/process
codraw/log
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony