
# shikiphp

shikiphp는 [Shiki](https://shiki.style)의 순수 PHP 포트입니다. VS Code와 같은 TextMate 문법 및 테마로 코드에 색상을 입히는 구문 하이라이터입니다. Shiki에서 사용하는 것과 같은 **TextMate 문법**으로 코드를 토큰화하고 **VS Code 테마**로 표시하여, PHP만으로도 Shiki 3.23.0와 같은 HTML를 생성합니다.

Node 런타임이 필요 없습니다. `json` 및 `mbstring` 외의 PHP 확장도 필요하지 않습니다. 네이티브 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 문자열이 동일해야 합니다. 시나리오 전체는 번들 문법 253개 중 167개, `lang: 'ansi'` 및 테마 65개를 다룹니다. 옵션(`structure`, `tabindex`, `colorReplacements`, 이중 테마, `defaultColor` 등), `codeToTokensWithThemes` 및 내장 변환기는 별도의 패리티 테스트로 확인하며, 기대 출력은 동일한 Shiki 버전에서 캡처했습니다.

여기에는 두 가지 제한이 있습니다. Shiki의 기본 엔진은 Oniguruma를 WebAssembly로 컴파일한 것이지만, 기준 구현은 Shiki의 JavaScript 정규식 엔진을 사용합니다. 이는 shikiphp가 포팅한 엔진입니다. 이후 Shiki 릴리스(4.x 계열)는 검증하지 않았습니다.

## 작동 방식

shikiphp는 [`inline0/phasis`](https://github.com/inline0/phasis)의 PHP [`oniguruma-to-es`](https://github.com/slevithan/oniguruma-to-es)을 기반으로 한 벤더링된 순수-PHP **JavaScript 정규식 엔진**을 사용합니다. Shiki의 JavaScript 정규식 엔진은 TextMate 문법의 Oniguruma 패턴을 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/ko/docs/architecture)를 참조하세요.

## 요구 사항

- PHP 8.2 이상 (CI는 PHP 8.4에서 테스트 스위트를 실행합니다)
- `ext-json` 및 `ext-mbstring` (거의 모든 PHP 빌드에 기본 포함됩니다)

## 다음 단계

- [시작하기](https://shikiphp.inline0.dev/ko/docs/getting-started) — 첫 블록을 설치하고 렌더링합니다.
- [API](https://shikiphp.inline0.dev/ko/docs/api) — 전체 메서드 목록입니다.
- [옵션](https://shikiphp.inline0.dev/ko/docs/options) — `codeToHtml`이 허용하는 모든 옵션입니다.
- [트랜스포머](https://shikiphp.inline0.dev/ko/docs/transformers) — 훅 파이프라인과 기본 제공 항목입니다.
- [CLI](https://shikiphp.inline0.dev/ko/docs/cli) — `bin/shikiphp highlight`, `langs`, `themes`입니다.

## 라이선스

MIT, 저작권 inline0. 번들에 포함된 TextMate 문법과 테마에는 각각 원래 라이선스가 적용됩니다.
