Org modeで埋め込みLaTeXの代わりにtypstを使う
typst、便利ですよね。 L^A T_E X の代わりのPDF生成手段として、とても 使いやすいです。さて、そんなtypstをOrg modeの組込み L^A T_E X の代わ りに使いたいな~と思ったこと、ありませんか?私は大いにあります。
ということで、 手軽に 埋め込み L^A T_E X をtypstに入れ替える方法を 書き記しておこうと思います。
概要
既存の埋め込みLaTeXの文法の一部を用いたまま、LaTeXとして解釈される所を typstとして扱うように実装に手を加えます。
インライン埋め込みでは $y = ax^2 + bx + c$
みたいな書き方を、ブロッ
クとして埋め込むには \begin{...}
で囲んで以下のような書き方をする必
要があります。
\begin{align}
$ y = ax^2 + bx + c $
\end{align}
埋め込みLaTeXでは \( y = x \)
や \[ y = x \]
といった書き方も用意
されていますが、これらはきちんと数式として描画されないので気をつけてく
ださい。(\( $y = x$ \)
とすれば可能ですが、余計な括弧もそのまま描画
されます)
注意事項
ブロックの場合 \begin{...}
で囲む必要があるなど、typstの埋め込みとし
ては適切な実装ではありません。あくまでも最小限の手数で実装するための記
事です。
尚、もし適切に実装をしたい場合はorg-element.elから手を加えるのがよさそ うです(今は時間ないのでやりませんが、いつかやっておきたい。)
実装
1. org-create-formula-imageの置き換え
org-create-formula-image
が、 PROCESSING-TYPE
として typst
シン
ボルを受け取った際はtypstとして処理をするように分岐させます。
(defun org-typst-embed/advice-func (oldfunc &rest args)
"Advice function to enable using typst as LaTeX fragment."
;; 見易さのため、 help:org-create-formula-image の本来の引数に名前を付けているだけ
(let ((string (nth 0 args))
(processing-type (nth 4 args))
(tofile (nth 1 args)))
(if (eq processing-type 'typst)
(progn
;; Block typeであった場合、それを取り除く
(when (string-prefix-p "\\begin{" string)
(setq string (with-temp-buffer
(insert string)
(let ((beg (progn (goto-char (point-min))
(forward-line) (point)))
(end (progn (goto-char (point-max))
(forward-line -2) (end-of-line) (point))))
(buffer-substring beg end)))))
(ob-typst/create-image string tofile))
(apply oldfunc args))))
(advice-add 'org-create-formula-image :around #'org-typst-embed/advice-func)
typstとして処理する部分は、自分の環境では自作の Cj-bc/ob-typstで提供さ
れている ob-typst/create-image を使っています。もし、インストールした
くない場合は以下のように定義して、 ob-typst/create-image
を使用して
いる場所と差し替えてあげるとよいと思います(ob-typstではいくつか
customize variableがあるので、それをハードコードした形になります。)
(defun org-typst-embed/create-image (string tofile)
"Create an image from typst source using external process.
The Typst STRING is saved to a temporary Typst file, then
converted to an image file by 'typst compiler' command.
The generated image file is eventually moved to TOFILE.
Generated file format is determined by TOFILE file
extension. Supported file formats are: .png, .pdf, .svg
"
(if (condition-case nil
(progn (call-process "typst" nil nil nil "--help") t)
(file-missing nil))
(let* ((tmpfile (make-temp-file "ob-typst"))
(ext (file-name-extension tofile))
(log-buf (get-buffer-create "*Org Preview typst Output*")))
(with-temp-file tmpfile
(insert default-rules-str "\n" string))
(copy-file (org-compile-file tmpfile
(list (format "typst compile --format %s --root %%o %%f" ext))
ext "" log-buf)
tofile 'replace))
(display-warning 'org-typst-embed "typst command not found")))
2. org-preview-latex-process-alist
の設定
org-preview-latex-process-alist
に含まれるシンボル以外
は~org-format-latex~ (内部処理で使われている関数)がエラーとして処理し
てしまい、画像の生成が出来ません。又、ここで指定する
:image-output-type
によって最終的な出力のファイル形式が決定します。
これは指定しないと png
となり、透過等が使えません。個人的には背景は
透過させたいので、svgに指定しています(:image-output-type
を指定する
か否かは好みで良いです)
(push '(typst :image-output-type "svg") org-preview-latex-process-alist)
3. org-preview-latex-default-process
の設定
これは 'typst
を指定するだけで良いです。これをすることで、
org--latex-preview-region
が適切に動くようになります。
(setq org-preview-latex-default-process 'typst)
使い方
実装にかかれたコードを全て実行した後、普通にLaTeX fragmentとしてtypst
を書き org-latex-preview
を呼び出せばよいです。
実装メモ
ここからは実際の実装に至るまでのメモを公開しておきます。 より深掘りする際の参考等にしてください
関連する変数
help:org-preview-latex-process-alist
help:org-format-latex が処理してくれるようにするために必要
help:org-preview-latex-default-process
help:org--latex-preview-region が
org-format-latex
に渡すPROCESSING-TYPE
になる
関連する関数
help:org--latex-preview-region
内部でハードコードされたLaTeXプリアンブルを書き込んだりしてくるので、入れ替える必要がある