元バイオ系

元バイオウェット系がデータサイエンスやらを勉強していくブログ。 基本自分用のまとめ。

LaTeX数式からはてなブログ数式へ一発で変換する

勉強するときはlatexまたはmarkdownでまとめているのですが、これをはてなブログへ転記しようと思うと相当に面倒くさい(特に数式周りが)。

数式の記述方法については以下のブログ記事でとてもよくまとめてくれている。

はてなブログで数式を書く - 七誌の開発日記

数式に関して少し発見があったのでメモ。

上記まとめブログの「裏技」にて、

【注意】2020年2月4日現在、この方法は使えなくなったようです。 どこか一箇所で [ tex: ~ ] を使用すれば、独立した数式に $$ ~ $$ や [ ~ ] を使用できるようです。

とあるのですが、2020年2月29日現在は [ tex: ~ ] を書いておけば一応$$~$$でも数式は表示されました。ただ、$$が残ってしまうという問題がありました。

そこで、$$を削除したところ普通に数式表示されました。推奨される方法ではないとは思いますが、便利なので使っていこうかと思います。

自動化した

Markdown→はてなブログ記事へのドキュメント変換スクリプトをPythonで書きました。 使い方は

python <path_to_script> <path_to_markdown>

です。とりあえず自分が使う用に書いた(今書いている別の記事の為)ので汚い&必要最低限の変換しか考慮していないですが、数式変換には便利かと思います。

import argparse
import os
import re

parser = argparse.ArgumentParser()
parser.add_argument("path", help="text file including latex equations.")

args = parser.parse_args()
path = args.path

def convert(text):
    link_indices = [m.span() for m in re.finditer("\[[あ-んぁ-んァ-ン一-龥a-zA-Z0-9!-/:-@[-`{-~]*\]([a-zA-Z0-9!-/:-@[-`{-~]*)", text)][::-1]
    links = []
    for i,idx in enumerate(link_indices):   # 逆順になっていることに注意
        links.append(text[idx[0]:idx[1]])
        text = text[:idx[0]] + "@@@" + text[idx[1]:]

    text = text.replace("\\\\", "\\\\\\")
    text = text.replace("_", "\\_")
    text = text.replace("^", "\\^")
    text = text.replace("[", "\\[")
    text = text.replace("]", "\\]")
    text = text.replace("\\{", "\\\\{")
    text = text.replace("\\}", "\\\\}")
    text = text.replace("*", "\\*")

    # equations
    text = text.replace(r"$$", r"")
    N = len([m.span() for m in re.finditer("$$", text)][::-1])
    if N > 0:
        text = """[tex: \displaystyle]
""" + text
    
    indices = [m.span() for m in re.finditer("\$", text)][::-1]
    for i,idx in enumerate(indices):   # 逆順になっていることに注意
        if i % 2 == 0:
            # $ -> ]
            text = text[:idx[0]] + "]" + text[idx[1]:]
        elif i % 2 == 1:
            text = text[:idx[0]] + "[tex: \\displaystyle " + text[idx[1]:]


    link_indices = [m.span() for m in re.finditer("@@@", text)][::-1]
    for i,idx in enumerate(link_indices):   # 逆順になっていることに注意
        text = text[:idx[0]] + links[i] + text[idx[1]:]

    return text


with open(path) as f:
    text = f.read()

newtext = convert(text)

with open("hatena.txt", "w") as f:
    f.write(newtext)

数式表示には上記の方法を利用しています。