こんにちは、その日暮らしです。
Enlighter - Customizable Syntax Highlighterプラグインでコードを表示したところその一部がMathJax-LaTeXプラグインのLaTeXコマンドとして認識され、Enlighterのブロック内で数式としてレンダリングされてしまいました。
これは、記事にコードを貼ったときに誤ったコードが表示されてしまうことがあるということです。
この非常に困った事態になんとかしようと思いなんとかしてみました。
当記事では、そんな小ネタをシェアします。
発端
以下のようにLaTeXコマンドを記事中のEnlighterブロックに入力すると・・・
・・・、MathJax-LaTeXプラグインの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コマンドとして処理されてしまう問題」でした。
コメント