
# カスタム言語とテーマ

同梱セットには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()`を呼び出します。
