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

Commonmark Highlighter Laravel Package

spatie/commonmark-highlighter

Server-side syntax highlighting for league/commonmark code blocks using scrivo/highlight.php. Generates HTML compatible with highlight.js themes, reducing JavaScript and avoiding flashes of unstyled code. Supports 185+ languages for fast, clean markdown rendering.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/commonmark-highlighter
    

    Requires league/commonmark (≥2.0) and scrivo/highlight.php (≥v9.18).

  2. Basic Usage:

    use League\CommonMark\CommonMarkConverter;
    use Spatie\CommonMarkHighlighter\CommonMarkHighlighter;
    
    $converter = new CommonMarkConverter();
    $converter->addRenderer(new CommonMarkHighlighter());
    
    $markdown = <<<MD
    ```php
    <?php
    echo "Hello, world!";
    

    MD;

    echo $converter->convert($markdown);

    Outputs HTML with syntax-highlighted PHP code.
    
    
  3. First Use Case:

    • Replace raw Markdown code blocks in your Laravel app (e.g., blog posts, docs) with visually appealing, syntax-highlighted versions.
    • Integrate with existing league/commonmark pipelines (e.g., in a MarkdownRenderer service).

Implementation Patterns

Core Workflow

  1. Integration with Laravel:

    • Service Provider: Register the highlighter globally in AppServiceProvider:
      public function boot()
      {
          $converter = new CommonMarkConverter();
          $converter->addRenderer(new CommonMarkHighlighter());
          app()->singleton('markdown.converter', fn() => $converter);
      }
      
    • Usage in Controllers/Blades:
      $html = app('markdown.converter')->convert($markdownContent);
      return view('post.show', compact('html'));
      
  2. Dynamic Configuration:

    • Override default settings (e.g., theme, line numbers) via the highlighter’s constructor:
      new CommonMarkHighlighter(
          theme: 'atom-one-dark',
          lineNumbers: true,
          tabSize: 4
      )
      
  3. Theming:

    • Use highlight.js themes by passing the theme name (e.g., 'monokai') to the constructor.
    • Custom themes: Extend Spatie\CommonMarkHighlighter\Highlight\Theme and pass an instance.
  4. Language Detection:

    • Explicitly set language via Markdown fence (e.g., php` `code` ).
    • Fallback to auto-detection (requires scrivo/highlight.php’s language mappings).
  5. Caching:

    • Cache converted Markdown in Laravel’s cache (e.g., Cache::remember()) to avoid reprocessing identical content.

Advanced Patterns

  • Custom Highlighting Rules: Extend Spatie\CommonMarkHighlighter\Highlight\Highlighter to add language-specific rules or preprocess code blocks.

  • Blade Directives: Create a Blade directive for concise syntax:

    Blade::directive('markdown', function ($expression) {
        return "<?php echo app('markdown.converter')->convert({$expression}); ?>";
    });
    

    Usage:

    @markdown($post->content)
    
  • API Responses: Use the highlighter in API responses for rich Markdown rendering:

    return response()->json(['content' => app('markdown.converter')->convert($markdown)]);
    

Gotchas and Tips

Pitfalls

  1. Language Mismatch:

    • If the language isn’t explicitly set (e.g., php` `code` ), auto-detection may fail for obscure languages.
    • Fix: Always specify the language or ensure scrivo/highlight.php supports it.
  2. Performance:

    • Highlighting large code blocks (e.g., 10K+ lines) can be slow.
    • Fix: Cache results aggressively or lazy-load the highlighter.
  3. Theme Incompatibility:

    • Not all highlight.js themes work perfectly with scrivo/highlight.php.
    • Fix: Test themes in a staging environment before production use.
  4. Markdown Parsing Conflicts:

    • Nested code blocks (e.g., Markdown inside code) may break highlighting.
    • Fix: Pre-process Markdown or use league/commonmark’s Environment to configure parsers.
  5. Dependency Conflicts:

    • scrivo/highlight.php may conflict with other packages using highlight.php (e.g., vlucas/phpdotenv).
    • Fix: Use composer why-not to diagnose and pin versions.

Debugging Tips

  • Log Highlighting Errors: Wrap the highlighter in a try-catch to log unsupported languages:

    try {
        $html = $highlighter->renderBlock($block);
    } catch (\Exception $e) {
        \Log::error("Highlighting failed for {$block->getLanguage()}: " . $e->getMessage());
        $html = "<pre>{$block->getContent()}</pre>"; // Fallback
    }
    
  • Inspect Raw Output: Use dd($block->getContent()) to verify input before highlighting.

  • Theme Debugging: Test themes in isolation:

    $highlighter = new CommonMarkHighlighter(theme: 'your-theme');
    echo $highlighter->highlight('return "test";', 'php');
    

Extension Points

  1. Custom Highlighter: Override Spatie\CommonMarkHighlighter\Highlight\Highlighter to add:

    • Language-specific syntax tweaks.
    • Pre/post-processing (e.g., minification, linting).
  2. Event Hooks: Use league/commonmark’s EventDispatcher to hook into parsing:

    $environment = Environment::create();
    $environment->addEventListener(
        new CodeBlockRenderedEventListener($highlighter)
    );
    
  3. Fallback Renderer: Implement a fallback for unsupported languages:

    $converter->addRenderer(new FallbackCodeBlockRenderer());
    

Configuration Quirks

  • Tab Size: Default is 4. Adjust via constructor or environment config:

    config(['commonmark-highlighter.tab_size' => 2]);
    
  • Line Numbers: Enable globally via config:

    config(['commonmark-highlighter.line_numbers' => true]);
    
  • CSS Inlining: The highlighter outputs <style> tags by default. Disable with:

    new CommonMarkHighlighter(includeStyle: false);
    
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