Weave 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

Geshi Laravel Package

easybook/geshi

GeSHi is a PHP syntax highlighter that converts source code into HTML with language-aware formatting. This EasyBook-maintained fork supports numerous languages and is useful for rendering code in documentation, blogs, and PHP applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Install with Composer:

composer require easybook/geshi

There is no service provider and no namespaced façade. The package exposes a single global class, GeSHi, autoloaded from geshi.php via a classmap. The smallest usable call is:

$geshi = new \GeSHi($source, 'php');
echo $geshi->parse_code();

Where to look first:

  • vendor/easybook/geshi/geshi.php — the entire public API lives in this one class. Search for function set_, function enable_, and function get_ to see your knobs.
  • vendor/easybook/geshi/geshi/ — one PHP file per supported language (php.php, javascript.php, blade.php if present, etc.). The filenames are the language identifiers you pass to the constructor.

The first real use case is rendering a user-facing code block — a blog post snippet, a README viewer, an admin panel showing config files. Create a thin wrapper immediately rather than sprinkling new \GeSHi(...) through controllers:

namespace App\Support;

class Highlighter
{
    public function render(string $code, string $language = 'text'): string
    {
        $geshi = new \GeSHi($code, $language);

        if ($geshi->error()) {
            return '<pre>' . e($code) . '</pre>';
        }

        $geshi->enable_classes();
        $geshi->set_header_type(GESHI_HEADER_PRE_VALID);
        $geshi->set_tab_width(4);

        return $geshi->parse_code();
    }
}

Check error() before trusting the output — the constructor does not throw when the language file is missing.

Implementation Patterns

Use classes, not inline styles. Out of the box GeSHi emits inline style="" attributes, which bloats HTML and makes theming impossible. Call enable_classes() early, then ship one stylesheet with rules for the standard token classes: .kw1–.kw4 (keywords), .co1–.co4 (comments), .st0–.st_h (strings), .br0, .sy0, .nu0, .me1, .re1, .sc0, .es0, .de1. The specific numbers depend on the language file, so generate or audit CSS against the languages you actually support.

Wrap it in a Blade component. Keep markup concerns in the view layer:

{{-- resources/views/components/code.blade.php --}}
@props(['code', 'language' => 'text'])
<div class="code-block">
    {!! app(\App\Support\Highlighter::class)->render($code, $language) !!}
</div>

Cache the rendered HTML. GeSHi re-parses the language file for every instance and has no result cache. For content that does not change often, cache by a hash of (code, language, options):

$key = 'geshi:' . md5($language . '|' . $code);

return Cache::remember($key, now()->addDay(), fn () =>
    app(\App\Support\Highlighter::class)->render($code, $language)
);

Add line numbers and highlighted lines when reading code reviews:

$geshi->enable_line_numbers(GESHI_FANCY_LINE_NUMBERS, 5); // number every 5th
$geshi->highlight_lines_extra([2, 7]);
$geshi->set_highlight_lines_extra_style('background: #fff3cd;');

Register custom languages or keyword groups. Drop a language file into resources/geshi/ and call set_language_path(resource_path('geshi')) before parse_code(). For small additions use add_keyword_group($language, GESHI_KEYWORDS_CASESENSITIVE, $keywords).

Integrate with Markdown rendering. If you render Markdown through league/commonmark, register a custom fenced-code block renderer (or post-process the HTML) that delegates to your wrapper. Do not try to run GeSHi over already-rendered HTML — it expects raw source and will double-escape it.

Reuse instances when rendering many blocks. set_source() and set_language() let you reset an instance between calls, which avoids repeated constructor overhead in a loop, though the language file is still re-read.

Gotchas and Tips

  • error() is the only error channel. A typo in the language name silently produces an error comment or unstyled output depending on configuration. Always branch on $geshi->error() and fall back to e($source) in a <pre>.
  • Never pre-escape the source. GeSHi internally applies htmlspecialchars; passing e($code) produces visible HTML entities.
  • Language paths are resolved relative to geshi.php. Copying or relocating the class file without the geshi/ directory breaks every language except the built-ins. set_language_path() is the fix, and is mandatory if you ship your own language files.
  • The default header type matters. GESHI_HEADER_PRE_TABLE (used for line numbers) emits a <table> that fights flex/grid layouts and can break horizontal scrolling. Prefer GESHI_HEADER_PRE_VALID unless you need per-line markup, and style .linenumbers yourself.
  • The package is from 2018 and upstream GeSHi is effectively unmaintained. Test carefully on your PHP version; some language files and older code paths can trip deprecations or removals in PHP 8.x. Pin the version and add a smoke test that parses every supported language once.
  • Class names are not a stable API. .kw1 in PHP does not mean the same token as .kw1 in JavaScript. If you publish a shared stylesheet, scope it per language (.language-php .kw1 { … }) rather than assuming global consistency.
  • Style and URL setters are an injection surface. set_overall_style(), set_line_style(), and keyword-URL mappings are written verbatim into the output. Never pass user-controlled strings to them.
  • Performance is proportional to code size and token count. For large files, cache aggressively, cap rendered size, and consider lazy-rendering blocks below the fold.
  • License is GPL-2.0. Confirm that is acceptable for your distribution before shipping it in a non-GPL project; for commercial or permissively licensed products, a maintained MIT/BSD highlighter is usually the safer long-term choice.
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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo