spatie/code-outliner
CLI tool to visualize your code structure by generating outline images of files or directories. Overlay multiple files to spot dense or repetitive areas and improve readability. Requires Puppeteer via spatie/browsershot; install globally via Composer.
Installation:
composer require spatie/code-outliner
Add the service provider to config/app.php:
Spatie\CodeOutliner\CodeOutlinerServiceProvider::class,
First Use Case: Generate an outline for a single file:
use Spatie\CodeOutliner\Facades\CodeOutliner;
$outline = CodeOutliner::generate('path/to/YourController.php');
$outline->save('path/to/output.png');
Where to Look First:
On-Demand Generation: Use the facade in controllers or commands to generate outlines dynamically (e.g., for documentation or PR reviews):
$outline = CodeOutliner::generate('app/Http/Controllers/UserController.php');
return response()->file($outline->getPath());
Batch Processing: Process multiple files via CLI (e.g., for a code review session):
php artisan code-outliner:generate app/Http/Controllers --output=docs/outlines
Integration with Laravel Events: Trigger outline generation post-commit or pre-deploy:
// In a service provider or event listener
event(new RepositoryPushed($repository));
CodeOutliner::generate('app/Service/'.class_basename($repository->getPath()))
->save(storage_path('app/outlines/'.basename($repository->getPath()).'.png'));
Customizing Output:
Override defaults in config/code-outliner.php:
'colors' => [
'background' => '#f5f5f5',
'keyword' => '#0000ff',
'string' => '#a31515',
],
'line-height' => 1.5,
Webhook-Driven Workflows: Use the package in a webhook endpoint to generate outlines for pull requests:
public function handle(PullRequestEvent $event) {
$outline = CodeOutliner::generate($event->filePath)
->save(storage_path("temp/pr_{$event->id}.png"));
// Attach to PR comment or Slack notification
}
storage/app/outlines).Cache::remember).GenerateOutlineJob::dispatch('app/Service/HeavyClass.php');
$this->partialMock(Spatie\CodeOutliner\Facades\CodeOutliner::class, function ($mock) {
$mock->shouldReceive('generate')->andReturn(new MockOutline());
});
Performance:
--limit in CLI.Syntax Highlighting:
Path Handling:
generate() are resolved from the root directory, not the working directory.realpath():
CodeOutliner::generate(realpath('app/Http/Controllers/UserController.php'));
Output Overwriting:
save() overwrites files by default. Use unique filenames for batch processing:
$outline->save("outlines/{$fileName}-".time().'.png');
Deprecated Methods:
if (!file_exists($path)) {
throw new \InvalidArgumentException("File not found: {$path}");
}
imagick or gd for image generation. Install via:
sudo apt-get install php-imagick # Ubuntu/Debian
try {
$outline = CodeOutliner::generate($path);
} catch (\Exception $e) {
Log::error("Outline generation failed for {$path}: {$e->getMessage()}");
}
config/code-outliner.php:
'font' => resource_path('fonts/consolas.ttf'), // Custom font
'dpi' => 96, // Adjust resolution
#hex, rgb(0,0,0), or named colors like red).Custom Tokenizers:
Extend Spatie\CodeOutliner\Tokenizers\TokenizerInterface to support new languages or syntax:
class CustomTokenizer implements TokenizerInterface {
public function tokenize(string $code): array {
// Implement custom logic
}
}
Register it in the service provider:
$this->app->bind(
TokenizerInterface::class,
CustomTokenizer::class
);
Post-Processing:
Hook into the outline-generated event to modify the output:
// In a service provider
event(new OutlineGenerated($outline));
Listen to it in another provider:
event(new OutlineGenerated($outline));
$outline->addWatermark('Confidential');
CLI Customization:
Extend the GenerateCommand to add flags or logic:
class CustomGenerateCommand extends GenerateCommand {
protected function getOptions() {
return [
['recursive', 'r', InputOption::VALUE_NONE, 'Generate outlines recursively'],
// ...
];
}
}
Bind it in the service provider:
$this->app->bind(
'command.code-outliner.generate',
CustomGenerateCommand::class
);
Output Formats:
The package outputs PNGs by default. Extend to support other formats (e.g., SVG) by modifying the Renderer class.
How can I help you explore Laravel packages today?