Phiki Documentation

repository·2.x·Indexed 18 days ago

https://github.com/phikiphp/phiki

Phiki is a PHP syntax highlighter inspired by Shiki that uses TextMate grammar files and Visual Studio Code themes to generate highlighted code for web applications. It supports custom grammars and themes, global and snippet-level caching via PSR-16, and integration with league/commonmark. Features include scope-based CSS classes via AddClassesTransformer, line highlighting, focusing, and diff annotations.

Tokens
26.1K
Snippets
50
Records
60
Agent score
63%

What's inside Phiki

  1. Overview of Phiki syntax highlighting

    2.x
    Phiki is a PHP-based syntax highlighter inspired by Shiki. It leverages TextMate grammar files and Visual Studio Code themes to produce high-quality syntax highlighting. Its implementation is inspired by vscode-textmate, allowing it to provide a similar experience to the highlighting found in VS Code and Shiki within the PHP ecosystem.
  2. Phiki Overview

    2.x

    Phiki is a pure PHP package for syntax highlighting code using TextMate grammar files and Visual Studio Code themes. It is designed as a high-performance, zero-dependency alternative to Shiki and Highlight.php.

    Key Advantages:

    • High Quality: Uses the same TextMate/VS Code logic as modern editors.
    • Pure PHP: Unlike Shiki, it does not require spawning a Node.js process, making it suitable for live-rendered PHP applications.
    • Zero Dependencies: Easy to integrate into any PHP project without managing third-party requirements.
  3. How cache invalidation works in Phiki

    2.x
    Phiki does not provide an internal mechanism for cache invalidation. Invalidation only occurs automatically if the cache key changes (e.g., by changing the code, grammar, or theme). To manually invalidate the cache, you must use the specific invalidation methods provided by your Psr\SimpleCache\CacheInterface implementation.
  4. Use Meta Information for highlighting and focusing lines

    2.x

    You can highlight or focus specific lines by adding braces to the Markdown code block info string. The format is {highlight_lines}{focus_lines}.

    • Highlighting: Use {line_numbers} to highlight specific lines.
    • Focusing: Use {}{line_numbers} to focus specific lines. When lines are focused, Phiki adds a focus class to the <pre> element.
    // Highlight lines 2 and 4-8
    ```php {2,4-8}

    // Focus lines 2 and 4-8 (no highlights)

  5. How transformers work in Phiki

    2.x

    Transformers allow you to modify data at various stages of the syntax highlighting process. They can intercept and alter the input code, individual tokens, the HTML AST (Abstract Syntax Tree), or the final HTML output.

    Transformers are applied sequentially: the return value from one transformer is passed as the input to the next.

    Important considerations:

    • Order matters: Transformers are applied in the order they are added.
    • AST Integrity: When modifying the HTML AST (using hooks like root, pre, code, etc.), be cautious when adding or removing elements, as this can break the structure expected by subsequent transformers in the pipeline.
  6. How Phiki works

    2.x

    Phiki provides high-quality syntax highlighting by following a five-step pipeline that mimics the behavior of modern code editors like Visual Studio Code:

    1. Tokenization: Uses TextMate grammar files to break code into pieces, each assigned a scope (a dot-separated string like variable.other.php describing the text type).
    2. Highlighting: Matches token scopes against a Visual Studio Code theme ruleset to determine background color, foreground color, and font styles. This produces HighlightedToken objects.
    3. Structuring: Converts tokens into an AST-like (Abstract Syntax Tree) intermediate structure to represent the desired HTML output.
    4. Transformation: Allows for modification of the AST. This is the primary extension point where features like line highlighting or custom class names are added.
    5. Rendering: "Stringifies" the final AST into HTML for output to browsers, templates, or files.
  7. Apply Line decorations to specific lines

    2.x

    You can target specific lines to add custom CSS classes (e.g., for highlighting or focusing) using LineDecoration::forLine(index)->class('your-class'). Note that line indices are zero-based.

    use Phiki\Transformers\Decorations\LineDecoration;
    
    $output = (new Phiki)
        ->codeToHtml('<?php echo ...', Grammar::Php, Theme::GithubLight)
        ->decoration(
            LineDecoration::forLine(0)->class('focus'),
        );
  8. Apply Gutter decorations to the line number area

    2.x

    To add custom CSS classes to the gutter element (the area containing line numbers), ensure you have enabled the gutter with withGutter() and then use GutterDecoration::make()->class('your-class') via the PendingHtmlOutput::decoration() method.

    use Phiki\Transformers\Decorations\GutterDecoration;
    
    $output = (new Phiki)
        ->codeToHtml('<?php echo ...', Grammar::Php, Theme::GithubLight)
        ->withGutter()
        ->decoration(
            GutterDecoration::make()->class('gutter-class'),
        );
  9. Use Inline Annotations for code highlighting and focusing

    2.x

    Phiki supports inline annotations using special comments within the code. This is useful for avoiding hardcoded line numbers.

    Highlighting

    Add // [code! highlight], // [code! hl], or // [code! ~~] to a line.

    Focusing

    Add // [code! focus], // [code! f], or // [code! **] to a line. This adds a focus class to the <pre> element.

    Diff Annotations

    • Insert: // [code! insert], // [code! ++], or // [code! add]
    • Remove: // [code! remove], // [code! --], or // [code! delete]

    Range Parameters

    Annotations can include a range parameter:

    • // [code! highlight:2] (current line + 2 following)
    • // [code! highlight:-2] (current line + 2 preceding)
    • // [code! highlight:1,3] (next 3 lines)
    • // [code! highlight:start] and // [code! highlight:end] for open-ended ranges.
    echo "Hello, world!"; // [code! highlight]
    echo "Hello, world!"; // [code! f]
    $user = User::find(1); // [code! remove]
    $user = User::findOrFail(1); // [code! insert]
  10. Apply Pre decorations to the code block wrapper

    2.x

    You can add custom CSS classes to the <pre> element that wraps the entire code block by using PreDecoration::make()->class('your-class') within the PendingHtmlOutput::decoration() method.

    use Phiki\Transformers\Decorations\PreDecoration;
    
    $output = (new Phiki)
        ->codeToHtml('<?php echo ...', Grammar::Php, Theme::GithubLight)
        ->decoration(
            PreDecoration::make()->class('pre-class'),
        );
  11. Apply Code decorations to the code element

    2.x

    To add custom CSS classes to the <code> element that wraps the code content, use CodeDecoration::make()->class('your-class') via the PendingHtmlOutput::decoration() method.

    use Phiki\Transformers\Decorations\CodeDecoration;
    
    $output = (new Phiki)
        ->codeToHtml('<?php echo ...', Grammar::Php, Theme::GithubLight)
        ->decoration(
            CodeDecoration::make()->class('code-class'),
        );
  12. Create a custom Phiki extension

    2.x

    To bundle custom grammars and themes for reuse, create a PHP class that implements the Phiki\Contracts\ExtensionInterface.

    Inside the register(Environment $environment): void method, use the $environment object to register your assets. You can use the grammar() method to register a new language grammar and the theme() method to register a new theme, both pointing to the file paths of your JSON definitions.

    use Phiki\Contracts\ExtensionInterface;
    use Phiki\Environment;
    
    class MyExtension implements ExtensionInterface
    {
        public function register(Environment $environment): void
        {
            $environment
                ->grammar('my-language', __DIR__ . '/grammars/my-language.json')
                ->theme('my-theme', __DIR__ . '/themes/my-theme.json');
        }
    }