GravプラグインのMathjaxでv3.0.0を適用

2019-11-01 12:242019-11-29 10:53

はじめに: 改行が効かないがそのうち直る

Upgrading from v2 to v3

をみると現状3.0.0では式中のlinebreakingがv2と同じようにはまだ効かないようです。これはやってから気づきました。v2から削除したけど今後実装するつもりはない、といっている特徴と違ってこれは今後のバージョンで修正されるようです。なので改行についてはそのうち治ると一旦放置して移行しました。

Step1: build-in JSをオフにする

Grav側のMathjaxプラグインのbuild-in Javascriptのオプションをオフにします。v2とはconfigの書き方が異なるので、これらは正しく機能しません。conversion toolに通して再配置するのもありますがプラグインのファイルをいじりたくないのでその方法は無しです。幸い、今のmathjaxプラグインでは追加のデリミタを自前でデフォルトのものに置き換えて出力してくれるので特に設定不要です。

build-in CSSの方はどっちでも良いですが自分でレイアウト調整する場合にはオフで良いでしょう。あとから.mathjaxクラスにあてれば調整できます。

Step2: CDNのアドレスを以下に変更

https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js

これもプラグインのconfigに書き込めばよいです。Adminから変更してもよいしサーバにいるなら/user/config/plugins/mathjax.yamlを編集します。これで一応改行以外はv3.0.0のものが使えて、かつマイナーバージョンのアップデートがあれば勝手に最新のものを使ってくれるようです。

Step3: テーマのphpからasyncをつける

mathjaxのページのscriptタグのサンプルにもあるように、パフォーマンスの観点からasync指定が必須です。ところが、編集現在のmathjaxプラグインではCDNの読み込みにasyncが指定されませんし、そのようなオプションも設けられていません。よって、ここでは以下のコードをテーマのphpに仕込んでasyncを付加しました。仮にテーマの名前をMyThemeとします。

//MyTheme.php
class MyTheme extends Theme
{
  public static function getSubscribedEvents()
  {
    return [
      'onThemeInitialized' => ['onThemeInitialized', 0],
    ];
  }

  public function onThemeInitialized()
  {
    if ($this->isAdmin()) {
      $this->active = false;
      return;
    }

    $this->enable([
      'onTwigSiteVariables' => ['onTwigSiteVariables', -1],
    ]);
  }

  public function onTwigSiteVariables()
  {
    $assets = $this->grav['assets'];

    /* Search mathjax CDN and add async loading */
    foreach($assets->getJs() as $asset) {
      if(stripos($asset['asset'], 'mathjax') != false) {
        $asset['attributes'] = [ 'loading' => 'async' ];
      }
    }
  }
}

関係無い所はもろもろ中略の疑似コードです。これで次のようにリファレンス通りにasync付きでjsが読み込まれます。

<script async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>;

サンプルと違ってtypeとidはついてませんがまあいいでしょう。scriptタグでtype指定無しはデフォルトでtext/javascriptになるので不要。idもまあいらん。そもそもphpいじらなくてもヘッダのtwigテンプレートに直接書き込んでもよい。

Step4: TeXブロックが無ければCDN読み込まない

これはまだやっていない。mathjaxプラグインでは全てのTeX要素をプリプロセスで処理して、タグ<p class="mathjax">を付与した上でデリミタをデフォルトに置き換える。つまりコンテンツを検索して.mathjaxが1度も現れなければmathjaxのCDNをクライアントに読ませることは不要ということになる。なのでそういう機能をテーマのphpで追加したかったという話。おそらく可能。

Gravのテーマphpから必要な時だけヘッダのMathjaxコードを挿入

できた。