
# shikiphp

shikiphp е изцяло-PHP порт на [Shiki](https://shiki.style) — осветител на синтаксиса, който оцветява кода със същите граматики и теми TextMate като VS
Code. Той токенизира кода със същите **граматики TextMate** и го оцветява със
същите **теми VS Code**, използвани от Shiki, като генерира същия HTML като Shiki 3.23.0
— изцяло на PHP.

Без среда за изпълнение на Node. Без разширения PHP извън `json` и `mbstring`. Без нативна
обвързка Oniguruma. Без стартиране на отделен процес JavaScript и без хостван API.

```php
use Shikiphp\Shikiphp;

echo Shikiphp::codeToHtml(<<<'PHP'
<?php
function greet(string $name): string {
    return "Hello, {$name}!";
}
PHP, [
    'lang'  => 'php',
    'theme' => 'github-dark',
]);
```

## Защо shikiphp

Осветяването на синтаксис от страна на сървъра в PHP обикновено изисква един от три
компромиса: стартиране на Node, извикване на хостван API или използване на осветител, базиран на
регулярни изрази, който всъщност не разбира езика. Нито един от тези варианти не се вписва добре в
Laravel, WordPress или стъпка за компилация на статичен сайт.

shikiphp премахва компромиса, като пренася реалния конвейер на Shiki към PHP:

- токенизатор на граматики TextMate (точен порт на
  [`vscode-textmate`](https://github.com/microsoft/vscode-textmate)), включително
  вградени езици, инжекции и вложени хранилища
- разрешаване на теми VS Code със специфичност на селекторите за обхват и
  съпоставяне на родителски обхвати
- Shiki-съвместим HTML: двойни светли/тъмни теми чрез променливи CSS, `codeToHast`,
  трансформатори (всички куки), декорации, `colorReplacements`,
  `structure: 'inline'` и осветяване ANSI (`lang: 'ansi'`)
- **пълният пакет Shiki** — всеки език `tm-grammars` (235, плюс 18
  помощни граматики, които се вграждат) и всяка тема `tm-themes` (65)

## Съпоставка с Shiki 3.23.0

Изходът не е „достатъчно близък“: проверява се спрямо фиксирана версия на Shiki.

| Пакет | Версия | Използва се за |
| --- | --- | --- |
| `shiki` | 3.23.0 | еталонът, стартиран с регулярния му механизъм JavaScript |
| `tm-grammars` | 1.31.15 | вградените граматики |
| `tm-themes` | 1.12.2 | вградените теми |
| `@shikijs/transformers` | 4.2.0 | тестовете за съответствие на трансформаторите |

Самият Shiki е еталонът. Комплектът за регресионни проверки съдържа **214 сценария**,
всеки от които е пример на един език и с една тема и настройки по подразбиране. Всеки
сценарий се осветява от Shiki и shikiphp, а двата низа HTML трябва
да са идентични след премахване на водещите и крайните интервали. Заедно
сценариите обхващат 167 от 253 вградените граматики, `lang: 'ansi'` и всичките 65
теми. Опциите (`structure`, `tabindex`, `colorReplacements`, двойни теми,
`defaultColor` и останалите), `codeToTokensWithThemes` и вградените
трансформатори се проверяват с отделни тестове за съответствие, чиито очаквани изходи
са заснети от същите версии Shiki.

Оттук следват две ограничения. Механизмът по подразбиране на Shiki е Oniguruma, компилиран до
WebAssembly, а еталонът използва вместо това регулярния механизъм JavaScript на Shiki —
механизмът, който използва портът на shikiphp. Освен това по-новите версии на Shiki (серията 4.x) не са
проверявани.

## Как работи

shikiphp е изградена върху вграден енджин за регулярни изрази с чист PHP **JavaScript** от
[`inline0/phasis`](https://github.com/inline0/phasis), захранван от PHP порт на
[`oniguruma-to-es`](https://github.com/slevithan/oniguruma-to-es). Енджинът за регулярни изрази на Shiki
JavaScript преобразува шаблоните на Oniguruma в граматиките на TextMate до
JavaScript `RegExp`, така че енджинът за регулярни изрази на JS е естествената основа — позволява на
shikiphp да съпоставя изхода на този енджин отместване по отместване.

```
code → grammar tokenizer → theme resolver → themed tokens → HTML
              │
              └─ OnigScanner → PatternConverter (oniguruma-to-es) → Shikiphp\Regex (JS RegExp engine)
```

Вижте [Архитектура](https://shikiphp.inline0.dev/bg/docs/architecture) за пълния конвейер.

## Изисквания

- PHP 8.2 или по-нова версия (CI изпълнява тестовия пакет с PHP 8.4)
- `ext-json` и `ext-mbstring` (и двете са включени в почти всяка компилация на PHP)

## Какво следва

- [Първи стъпки](https://shikiphp.inline0.dev/bg/docs/getting-started) — инсталирайте и генерирайте първия си блок.
- [API](https://shikiphp.inline0.dev/bg/docs/api) — пълният набор от методи.
- [Опции](https://shikiphp.inline0.dev/bg/docs/options) — всички опции, които приема `codeToHtml`.
- [Трансформатори](https://shikiphp.inline0.dev/bg/docs/transformers) — конвейерът с куки и вградените трансформатори.
- [CLI](https://shikiphp.inline0.dev/bg/docs/cli) — `bin/shikiphp highlight`, `langs` и `themes`.

## Лиценз

MIT, авторско право на inline0. Вградените граматики и теми TextMate запазват
лицензите си от първоначалните си проекти.
