Cloudflare PagesのHUGOで数式をきれいに表示

目次

VSCodeでMarkdownをフォーマットするとき、prettierは括弧を使った数式のインライン表記をサポートしていない。変わりにmarkdownlintを使用する。

Cloudflare PagesHUGOは、標準では括弧を使った数式のインライン表記をサポートしない。ビルドシステムをV3に変更する必要がある。


問題点

VSCodeでMarkdownを編集していますが、数式をインライン表記するためには$数式$を使っていました。しかし、Cloudflare PagesでWebページにすると、数式がレンダリングされたり・されなかったりという現象に出いました。そこで、別の表記方法である\(数式\)を使うことにしたのですが、次の2つの問題に出会いました。

  • VSCodeでMarkdownフォーマッタにPrettierをつかてました。しかし\(A_i\)を数式と認識せず、アンダーバーを\(A\_i\)にエスケープされてしまう。
  • Cloudflare PagesのHugoでレンダリングすると、\(数式\)のエスケープが消えて(数式)になってしまう。そのため数式としてレンダリングされない。。

解決方法

インライン数式の括弧表記に対応したMarkdownフォーマッタ

\(数式\)をインラインの数式として正しく認識できるMarkdown専用のフォーマッタであるmarkdownlintを使うようにしました。

設定方法は次のとおりです。

  1. VSCodeの拡張機能でmarkdownlintを検索して、markdownlintをインストールします。
  2. コマンドパレットCtrl + Shift + pからPreferences: Open User Settings (JSON)を選んでユーザ設定(JSON)を開きます。
  3. markdownlintがmarkdownファイルのフォーマットをするよう次の設定を加えます。ここでは、同時に保存するときに自動的にフォーマットする設定を加えています。
"[markdown]": {
  "editor.defaultFormatter": "DavidAnson.vscode-markdownlint",
  "editor.formatOnSave": true
},

Cloudflare PagesのHugoで数式のレンダリング

Cloudflare Pagesの初期設定は、ビルドシステムがv2になっていました。その結果使用されるHugoのバージョンが古いため\(数式\)のエスケープが消えて(数式)になってしまうようです。

そのためこの問題は、Cloudflare Pagesの設定を開いてビルドシステムの設定をv3に修正すれば問題が解消します1

ビルドシステムv3が使用するHugoのバージョンは、Build image · Cloudflare Pages docsで確認できます。

全てのMarkdownファイルからインライン数式を括弧表記に書き換え (Optional)

これまで$数式$で書いてきたインラインの数式は、次のスクリプトで変換しました。一括での変換も可能ですが、コマンドの実行例があったりするので確認しながら置換しています。また、

import re
from pathlib import Path

def convert_line_interactive(line, file_path, line_num):
    pattern = re.compile(r'(?<!\$)\$(?!\$)(.+?)(?<!\$)\$(?!\$)')

    def replacer(match):
        content = match.group(1)
        return f"\\({content}\\)"

    matches = list(pattern.finditer(line))
    if not matches:
        return line, False

    print(f"\nFile: {file_path}")
    print(f"Line {line_num}:")
    print(f"  BEFORE: {line.rstrip()}")

    new_line = pattern.sub(replacer, line)
    print(f"  AFTER : {new_line.rstrip()}")

    choice = input("Replace this line? [y/N/q] ").strip().lower()
    if choice == 'y':
        return new_line, True
    elif choice == 'q':
        print("Aborted by user.")
        exit(0)
    else:
        return line, False

# 処理対象の .md ファイル(./contents ディレクトリに限定)
for file_path in Path('./contents').rglob("*.md"):
    lines = file_path.read_text(encoding='utf-8').splitlines(keepends=True)
    changed = False
    new_lines = []

    for i, line in enumerate(lines, start=1):
        new_line, was_changed = convert_line_interactive(line, file_path, i)
        new_lines.append(new_line)
        if was_changed:
            changed = True

    if changed:
        file_path.write_text(''.join(new_lines), encoding='utf-8')
        print(f">>> Updated: {file_path}")

参考サイト


  1. 使用するHugoのバージョンは、設定の変数にHUGO_VERSIONを作成してバージョン番号を書くと、特定のバージョンのHugoを使ってWebページをビルドすることが出来ます。 ↩︎