スポンサーリンク

Enlighterプラグインで表示させたコードがMathJax-LaTeXプラグインのLaTeXコマンドとして処理されてしまう問題

2023年3月17日

 こんにちは、その日暮らしです。

 Enlighter - Customizable Syntax Highlighterプラグインでコードを表示したところその一部がMathJax-LaTeXプラグインのLaTeXコマンドとして認識され、Enlighterのブロック内で数式としてレンダリングされてしまいました

 これは、記事にコードを貼ったときに誤ったコードが表示されてしまうことがあるということです。

 この非常に困った事態になんとかしようと思いなんとかしてみました。

 当記事では、そんな小ネタをシェアします。


発端

 以下のようにLaTeXコマンドを記事中のEnlighterブロックに入力すると・・・

Enlighterブロックに入力したLaTeXコマンド

・・・、MathJax-LaTeXプラグインのLaTeXコマンドとして認識され、レンダリングの結果以下のように数式が表示されてしまいます。

Enlighterブロック内でレンダリングされたLaTeXコマンド

 なんでわざわざLaTeXのコマンドなんてコードに入れるのって思われるかもしれませんが、事の発端は、以下の記事でHTML中にあるLaTeXコマンドを正規表現「'/\\\\\\((.+?)\\\\\\)/'」を使って検索するコードをEnlighterブロックに貼ったことからでした。このときは、正規表現の文字列が「'/\\\\(.+?)/'」と表示され「(.+?)」の部分が数式としてレンダリングされてしまいました。

 こんなんじゃカッコ悪い以前に誤ったコードが表示されてしまうので大問題ですよね。

 なんとかします。

対策

 MathJax-LaTeXプラグインで実際に数式のレンダリングを行っているのはMathJaxで、これは、<pre></pre>や<code></code>で囲まれたところにあるLaTeXコマンドをレンダリングの対象外として扱います。MathJaxもEnlighterも実装はJavaScriptなので、Enlighterが実行された後とMathJaxが実行される前のタイミングでEnlighterのノードを丸ごと<code></code>で囲む処理をJavaScriptで実装すればよさそうです。

 実装するコードとしては、新たに作成するJavaScriptをWordPressに登録するコードと、そのJavaScript本体になります。

 以下が、JavaScriptのコードをWordPressに登録するコードです。このコードを、使っているテーマのfunctions.phpに貼ります。6行目のwp_enqueue_script関数を呼び出すときの第3引数「array( 'enlighterjs' )」では、Enlighterの実行後にここで登録するJavaScriptが実行されるように指定しています。また、MathJaxのJavaScriptは、なにもしなくても今回登録するJavaScriptより前に実行されることはなかったのでMathJaxの実行順は気にしないことにします(本当にそれでいいのか不明)。

// Myスクリプトを追加する。
function add_my_scripts() {
    // 投稿かつAMP以外の場合に・・・。
    if ( is_singular( 'post' ) && substr( get_pagenum_link( get_query_var( 'paged' ) ), -5 ) !== '/amp/' )
        // enlighterを丸ごと<code>で囲むスクリプトを追加する。
        wp_enqueue_script( 'wrap_enlighter', get_stylesheet_directory_uri() . '/js/wrap-enlighter.js', array( 'enlighterjs' ), '1.0', true );
}
add_action( 'wp_enqueue_scripts', 'add_my_scripts' );

 以下が、JavaScriptのコードです。これを「wrap-enlighter.js」というファイル名でテーマ直下の「js」フォルダに格納します。コードの中身を簡単に解説すると、DOMを使って記事のHTML内にある「enlighter-default」というクラス名を持つEnlighterのノードを列挙し、それらのノードすべてについてそのノードの直前に新しく作成した<code></code>を挿入し、その<code></code>の中にEnlighterのノードを移動する、という処理を行っています。

// enlighterを丸ごと<code>で囲む。
document.addEventListener('DOMContentLoaded', function() {
    // ページ内のenlighterを列挙する。
    let enlighters = document.getElementsByClassName('enlighter-default');
    // すべてのenlighterについて・・・。
    for (let enlighter of enlighters) {
        // <code>を作る。
        let code = document.createElement('code');
        // <code>をenlighterの直前に挿入する。
        enlighter.parentNode.insertBefore(code, enlighter);
        // enlighterを<code>の下に移動する。
        code.appendChild(enlighter);
    }
});

 これで、Enlighterブロック内のコードがLaTeXコマンドとしてレンダリングされることはなくなるはずです。

 試してみます。

 本文中に「\(E=mc^2\)」と書くとMathJaxでレンダリングされて「\(E=mc^2\)」(AMPでは正しく表示されない)と表示されますが、Enlighterのブロック内ではレンダリングされず「\(E=mc^2\)」のままです。

print(r'\(E=mc^2\)')

 うまくいきました。


 以上、「Enlighterプラグインで表示させたコードがMathJax-LaTeXプラグインのLaTeXコマンドとして処理されてしまう問題」でした。


この記事を書いた人

プロフィール

 その日暮らし

 こんにちは、その日暮らしです/地方国立大理系院卒→大手大企業就職→ソフト開発二十年超→メンタル壊して退職→ちょっと回復→資格取得頑張る(簿記3級と応用情報は合格でデスペはギブアップ)→コロナ禍で再就職無理→離婚orz→実家へ出戻ってこどおじ化(笑)→WordPressの勉強のためブログに挑戦/そんな訳でブログは始めたばかりですが日々いろんなことを試して得た知識を投稿していこうと思ってます/以上