Ink

Contents related to tech, hobby, etc

Org modeで埋め込みLaTeXの代わりにtypstを使う

|

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 を呼び出せばよいです。

実装メモ

ここからは実際の実装に至るまでのメモを公開しておきます。 より深掘りする際の参考等にしてください

関連する変数

関連する関数

LaTeXフラグメント識別用