
# 自定义语言和主题

捆绑内容涵盖完整的 Shiki 目录，但你也可以从已解码的 JSON 注册自己的
TextMate 语法或 VS Code 主题。两者都保存在 `Highlighter` 实例上。

## 自定义主题

解码一个 VS Code 主题 JSON 文件并传给 `loadTheme`。主题以其 `name` 为键；自定义主题会覆盖同名的捆绑主题。

```php
use Shikiphp\Shikiphp;

$highlighter = Shikiphp::highlighter();

$theme = json_decode(file_get_contents('my-theme.json'), true);
$highlighter->loadTheme($theme);

$code = '<?php echo "hello";';

echo $highlighter->codeToHtml($code, [
    'lang'  => 'php',
    'theme' => $theme['name'], // the theme's own name
]);
```

## 自定义语法

`loadGrammar` 会注册已解码的 `.tmLanguage.json`，这样任何入口点都可以通过语言 id 使用它：

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

- `$langId` — 用于引用它的 id。若省略，则依次使用语法的 `name` 和 `scopeName`。
- `$aliases` — 指向同一语法的额外 id。
- `$embedded` — 此语法嵌入的语言 id，因此也会解析这些语言的语法。

```php
use Shikiphp\Shikiphp;

$highlighter = Shikiphp::highlighter();

$grammar = json_decode(file_get_contents('mylang.tmLanguage.json'), true);
$highlighter->loadGrammar($grammar, 'mylang', aliases: ['ml']);

$code = file_get_contents('example.mylang');

echo $highlighter->codeToHtml($code, [
    'lang'  => 'mylang',
    'theme' => 'github-dark',
]);
```

语法 `include` 引用（`#repo`、`$self`、`$base`、`other.scope`）和嵌入语言会根据高亮器上已注册的语法解析，因此请先注册所有依赖项。

## 通过外观接口使用自定义高亮器

如果你希望静态 `Shikiphp` 外观接口使用自定义高亮器，请通过 `Shikiphp::use` 将其传入：

```php
use Shikiphp\Highlighter;
use Shikiphp\Shikiphp;

$myTheme = json_decode(file_get_contents('my-theme.json'), true);
$myGrammar = json_decode(file_get_contents('mylang.tmLanguage.json'), true);
$code = file_get_contents('example.mylang');

$highlighter = Highlighter::createBundled();
$highlighter->loadTheme($myTheme);
$highlighter->loadGrammar($myGrammar, 'mylang');

Shikiphp::use($highlighter);

// Now the facade delegates to your highlighter.
echo Shikiphp::codeToHtml($code, ['lang' => 'mylang', 'theme' => $myTheme['name']]);
```

调用 `Shikiphp::reset()` 即可恢复使用默认的捆绑高亮器。
