
# API

shikiphp 提供两个入口：用于常见情况的静态 `Shikiphp` 门面，以及用于其他所有情况的 `Highlighter` 实例（HAST 输出、自定义语法和主题、主题变体及软件包内省）。

## `Shikiphp` 门面

`Shikiphp\Shikiphp` 是一个精简的静态门面，封装了延迟创建并缓存的捆绑版高亮器。

### `Shikiphp::codeToHtml`

```php
public static function codeToHtml(string $code, array $options): string
```

对 `$code` 进行分词并渲染完整的 `<pre class="shiki …">` HTML 代码块。选项数组始终包含一个 `lang`，以及 `theme` 或 `themes` 映射之一，还可以包含任意 [渲染选项](https://shikiphp.inline0.dev/zh/docs/options)。

```php
use Shikiphp\Shikiphp;

echo Shikiphp::codeToHtml($code, ['lang' => 'php', 'theme' => 'github-dark']);
```

### `Shikiphp::codeToTokens`

```php
/** @return list<list<ThemedToken>> */
public static function codeToTokens(string $code, array $options): array
```

返回纯二维令牌网格（每行对应一个内层列表），其中包含 `Shikiphp\Render\ThemedToken` 对象，而非 HTML。

```php
use Shikiphp\Shikiphp;

$lines = Shikiphp::codeToTokens($code, ['lang' => 'js', 'theme' => 'nord']);

foreach ($lines as $line) {
    foreach ($line as $token) {
        // $token->content, $token->color, $token->fontStyle,
        // $token->bgColor, $token->htmlStyle, $token->offset
    }
}
```

### `Shikiphp::codeToTokensBase`

```php
/** @return list<list<ThemedToken>> */
public static function codeToTokensBase(string $code, array $options): array
```

`codeToTokens` 的别名，名称与 Shiki 的 `codeToTokensBase` 名称一致。

### `Shikiphp::codeToTokensResult`

```php
public static function codeToTokensResult(string $code, array $options): TokensResult
```

返回一个丰富结果，与 Shiki 顶层 `codeToTokens` 相对应：令牌网格以及解析后的颜色、主题名称、双主题根样式和最终语法状态。参见下文的 [`TokensResult`](#tokensresult)。

```php
use Shikiphp\Shikiphp;

$result = Shikiphp::codeToTokensResult($code, [
    'lang'  => 'php',
    'theme' => 'github-dark',
]);

$result->tokens;       // list<list<ThemedToken>>
$result->fg;           // "#e1e4e8"
$result->bg;           // "#24292e"
$result->themeName;    // "github-dark"
$result->grammarState; // GrammarState
```

### `Shikiphp::getLastGrammarState`

```php
public static function getLastGrammarState(string $code, array $options): GrammarState
```

对 `$code` 进行分词，并返回最终的语法状态（Shiki 的 `getLastGrammarState`）。通过 [`grammarState`](https://shikiphp.inline0.dev/zh/docs/options) 选项传回该状态，即可从相同状态继续对后续片段进行分词，适用于增量高亮。如果 `lang` 为 `'ansi'`，则会抛出异常（ANSI 没有语法状态）。

```php
use Shikiphp\Shikiphp;

$state = Shikiphp::getLastGrammarState("/* unterminated comment", [
    'lang'  => 'js',
    'theme' => 'nord',
]);

$html = Shikiphp::codeToHtml("still inside the comment */", [
    'lang'         => 'js',
    'theme'        => 'nord',
    'grammarState' => $state,
]);
```

### `Shikiphp::highlighter`

```php
public static function highlighter(): Highlighter
```

返回共享的捆绑版 `Highlighter`，并在首次使用时创建。可通过它访问下方的实例方法。

### `Shikiphp::use` 与 `Shikiphp::reset`

```php
public static function use(Highlighter $highlighter): void
public static function reset(): void
```

`use` 会替换为自定义的 `Highlighter`（例如已加载自定义语法或主题的实例），使门面将调用委托给它。`reset` 会清除缓存的实例，以便下次调用时重新构建默认的捆绑版高亮器。

## `Highlighter`

`Shikiphp\Highlighter` 提供完整接口。通过 `Shikiphp::highlighter()` 获取共享的捆绑版实例，也可以显式构建一个：

```php
use Shikiphp\Highlighter;

$highlighter = Highlighter::createBundled();
```

它实现了 `codeToHtml`、`codeToTokens`、`codeToTokensBase`、`codeToTokensResult` 和 `getLastGrammarState`，签名与门面相同，另外还提供以下内容。

### `Highlighter::codeToHast`

```php
public function codeToHast(string $code, array $options): \Shikiphp\Hast\Element
```

构建 `pre.shiki > code > (span.line > span)*` 所构建的 HAST 树 Shiki，供你自行遍历、修改或序列化。这正是 `codeToHtml` 在内部进行序列化的对象。

```php
use Shikiphp\Shikiphp;

$hast = Shikiphp::highlighter()->codeToHast($code, [
    'lang'  => 'rust',
    'theme' => 'nord',
]);
```

### `Highlighter::codeToTokensWithThemes`

```php
/** @return list<list<ThemedTokenWithVariants>> */
public function codeToTokensWithThemes(string $code, array $options): array
```

每种主题分词一次，并将结果合并为按主题键索引的令牌级 `variants`，与 Shiki 的 `codeToTokensWithThemes` 相对应。需要提供 `themes` 映射。

```php
use Shikiphp\Shikiphp;

$lines = Shikiphp::highlighter()->codeToTokensWithThemes($code, [
    'lang'   => 'ts',
    'themes' => ['light' => 'github-light', 'dark' => 'github-dark'],
]);

$lines[0][0]->content;            // token text
$lines[0][0]->variants['light'];  // ThemedTokenStyle for the light theme
$lines[0][0]->variants['dark'];   // ThemedTokenStyle for the dark theme
```

### `Highlighter::loadGrammar` 与 `Highlighter::loadTheme`

```php
public function loadGrammar(
    array $rawTmLanguage,
    ?string $langId = null,
    array $aliases = [],
    array $embedded = [],
): void

public function loadTheme(array $rawTheme): void
```

从解码后的 JSON 注册自定义的 TextMate 语法或 VS Code 主题。参见[自定义语言和主题](https://shikiphp.inline0.dev/zh/docs/custom-languages-themes)。

### 软件包内省

```php
/** @return list<string> */ public function loadedLanguages(): array
/** @return list<string> */ public function loadedThemes(): array
/** @return list<string> */ public function bundledLanguages(): array
/** @return list<string> */ public function bundledThemes(): array
```

`loadedLanguages`/`loadedThemes` 会报告当前可用的所有 ID（捆绑的以及你注册的自定义 ID）。`bundledLanguages`/`bundledThemes` 只报告随软件包提供的 ID。参见[语言](https://shikiphp.inline0.dev/zh/docs/languages)和[主题](https://shikiphp.inline0.dev/zh/docs/themes)。

## 值对象

### `ThemedToken`

`Shikiphp\Render\ThemedToken` 是一段带样式的文本：

```php
final class ThemedToken
{
    public readonly string $content;
    public readonly ?string $color;
    public readonly int $fontStyle;      // FontStyle bitmask
    public readonly ?string $bgColor;
    public readonly ?string $htmlStyle;  // pre-built inline style (dual themes / ANSI)
    public readonly int $offset;         // UTF-16 code-unit offset into the source
}
```

`fontStyle` 是来自 `Shikiphp\Theme\FontStyle` 的位掩码（`NONE`、`ITALIC`、`BOLD`、`UNDERLINE`、`STRIKETHROUGH`）。

### `TokensResult`

`Shikiphp\TokensResult` 是 `codeToTokensResult` 的返回值：

```php
final class TokensResult
{
    public readonly array $tokens;             // list<list<ThemedToken>>
    public readonly ?string $fg;               // resolved foreground
    public readonly ?string $bg;               // resolved background
    public readonly ?string $themeName;        // single id, or "shiki-themes …"
    public readonly string|false|null $rootStyle; // dual-theme root style (or null)
    public readonly ?GrammarState $grammarState;
}
```

### `GrammarState`

`Shikiphp\GrammarState` 保存分词器的规则栈（按主题名称索引），以便从中间位置继续高亮。

```php
final class GrammarState
{
    public readonly string $lang;

    public function theme(): string;          // first theme name
    public function themes(): array;          // list<string>
    public function getScopes(?string $theme = null): array; // scopes in effect, innermost first
    public function withTheme(string $theme): self;
}
```
