Prism.js 使ってみた

今までソースコードをシンタックスハイライト表示させるのに [Ex Code Prettify](https://www.cyokodog.net/blog/ex-code-prettify-doc/) を利用していたのですが、

* 更新が止まっている
* 利用するには jQuery が必要

というわけで、新しいものを探すことに。
検索してみると [Prism.js](https://prismjs.com/) の評判が良いみたいだったので使ってみました！

[npm](https://www.npmjs.com/package/prismjs) にもアップされていますが、テーマやプラグインの設定が簡単なダウンロード版を利用します。

## Prism.js のダウンロード

[ダウンロードページ](https://prismjs.com/download.html)より必要な項目を選んでダウンロードします。

### 開発バージョンまたは軽量バージョンを選択

* Development version ： 開発バージョン
* Minified version ： 軽量バージョン

### テーマを選択

テーマは全8種類。
[Dracula](https://draculatheme.com/) テーマが欲しい…

#### Default

![prismjs_theme_default.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492675/d4b64448-88c4-a5b8-69a2-bd501fd6026c.png)

#### Dark

![prismjs_theme_dark.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492675/d3caaa59-8e50-8ee4-02d1-2069cb4b5fd9.png)

#### Funky

![prismjs_theme_funky.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492675/8335d235-030d-a591-7eda-c01918bc4251.png)

#### Okaidia

![prismjs_theme_okaidia.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492675/a76ea094-2f01-c3a7-2aac-c213156316a9.png)

#### Twilight

![prismjs_theme_twilight.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492675/2720be2e-527d-bf6a-c874-9f525d32f90f.png)

#### Coy

![prismjs_theme_coy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492675/71da2123-1ec2-f1ae-f4c6-ab93f014fa10.png)

#### Solarized Light

![prismjs_theme_solarized-light.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492675/4641142e-f824-78bc-77e5-e1da0ebcc868.png)

#### Tomorrow Night

![prismjs_theme_tommorrow-night.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492675/7fdba84d-c7e1-13d2-7ce5-d8457dd7878d.png)

### 利用言語を選択

言語の量がスゴイ！！

![prismjs_languages.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492675/86af0d43-edc7-9a28-0aa6-cfaa6c90039a.png)

### プラグインを選択

自分の必要な機能を選べるので軽量なんですね！

![prismjs_plugins.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492675/7621e820-bbc4-02f1-ed86-1f784ceca00f.png)

| プラグイン名 | 機能|
|----------------|--------------|
| Line Highlight|指定した行を目立たせる。|
| Line Numbers|行番号を表示する。|
| Show Invisibles|タブ、スペース、改行などの不可視文字を表示する。|
| Autolinker|コード内の URL やメールアドレスをクリック可能なリンクにする。|
| WebPlatform Docs|コードを WebPlattform Docs にリンクさせる。|
| Custom Class|Prism のクラスを編集して、Prism をカスタムする。|
| File Highlight|外部ファイルを取得し、その内容をハイライトさせる。|
| Show Language|指定した言語名を表示する。|
| JSONP Highlight|JSONP を使ってコンテンツを取得し、その内容をハイライトさせる。|
| Highlight Keywords|コード中の特定のキーワードに独自 CSS を設定する。|
| Remove initial line feed|コードブロック内のはじめに改行があれば削除する。|
| Inlin color|コード中にカラーコードがあれば、その色を表示させる。|
| Previewers|コードの結果がホバーでプレビューできる。|
| Autoloader|指定した言語が自分の prism.js にないとき、自動的にロードする。|
| Keep Markup|コード中のマークアップ（HTML）が保持される。|
| Command Line|コマンドラインをプロンプトとともに表示し、オプションでコマンドからの出力を表示する。|
| Unescaped Markup|マークアップ（HTML）をエスケープせずに、コードとして表示させる。|
| Normalize Whitespace|コードブロック内の不要な空白を削除する。|
| Data-URI Highlight|データURIを強調表示する。|
| Toolbar | コードブロック上部にボタンを設置する。|
| Copy to Clipboard Button | クリップボードにコピーするボタンを追加する。|
| Download Button | コードファイルをダウンロードするボタンを追加する。|
| Match braces | 一致する括弧を色分けする。|
| Diff Highlight | diffブロック（GitHub）内のコードを強調表示する。|
| Filter highlight | 独自の条件を設定し、独自の表示をさせる。|
| Treeview | ファイルシステムのツリー構造を見やすく表示させる。|

### JavaScript と CSS をダウンロード

以下のボタンから JavaScript と CSS をダウンロードします。

![prismjs_download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492675/4e29a598-b72c-f0e0-fb26-1c45af401f1b.png)

## Prism.js の使い方

### JavaScript と CSS を読み込む

シンタックスハイライトを利用したいページで Prism.js の JavaScript と CSS を読み込みます。

```html:html
<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="prism.css">
  <script src="prism.js" defer></script>
</head>
```

### コードを記述する

シンタックスハイライトさせたいコードを `<pre><code class="language-言語名"> ... </code></pre>` で囲みます。
言語名はダウンロード時に選択した言語名を設定します。

```html:html
<pre>
  <code class="language-言語名">
    ...
  </code>
</pre>
```

HTML のタグに使われる `<` や `>` はエスケープ処理をしないと HTML として認識されてしまい正しく表示されません。
`<` は `&lt;`、`>` は `&gt;` に変換が必要です。

```html:html
<pre>
  <code class="language-html">
    &lt;p&gt;エスケープします&lt;/p&gt;
  </code>
</pre>
```

## ハマリポイント

### ファイル名を表示したいんじゃぁぁぁ～

Show Language プラグインを利用することで言語名の自動表示が可能になりますが、言語名の他にファイル名を表示したかったので調べてみると…
`<pre>` に `data-label` 属性を設定することで任意の文字列が表示できました！

```html:html
<pre data-label="index.html">
  <code class="language-html">
    ...
  </code>
</pre>
```

### Pug で利用したいんじゃぁぁぁ～

Pug で利用するためにはパイプライン `|` を利用します。

```pug:pug
div
  p Pug で Prism.js を利用する
  pre
    code.language-html
      | ...
      | ...
      | ...
      | ...
```

### コードを折り返したいんじゃぁぁぁ～

Prism.js はデフォルトでは行を折り返さない設定となっています。
行を折り返すためには `prism.css` の設定を上書きします。
`code[class*='language-']` と `pre[class*='language-']` に対して設定しないと行番号がズレます。

```css:css
code[class*='language-'],
pre[class*='language-'] {
  white-space: pre-wrap !important;
}
```

### 設定項目忘れてしもたぁぁぁ～

ダウンロード版を利用していると、後で言語・プラグインを追加したくなった時に、
「あ、やべ…今まで利用していた言語・プラグイン忘れてしもたぁぁぁ～」
ということになります。

ダウンロードページのチェック項目を選択するたびに URL にパラメータが付与されるので、全てチェックした状態の URL を保存しておけば大丈夫！

こんな感じ↓

```
https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript+bash+css-extras+json+markup-templating+php+pug+scss&plugins=line-highlight+line-numbers+inline-color+toolbar+copy-to-clipboard
```

`prism.css` の設定を上書きする CSS ファイルにコメントとして残しておくといいかもです～。