🍣

Typst の擬似コード用モジュールを作成した

2023/06/21に公開

Typst とは

Rust 製の組版システムで、

  • Latex よりもシンプルに記述できる
  • コンパイルがめちゃくちゃ速い
  • 最近 Pandoc に対応した

という特徴がある。

数式だけ見比べてみてもこんな感じ。

Latex

\[
  \begin{aligned}
    \sum_{k = 0}^{n}k
      & = 1 + \ldots + n \\
      & = \frac{n(n + 1)}{2}
  \end{aligned}
\]

Typst

$ sum_(k=0)^n k
  &= 1 + ... + n \
  &= (n(n+1)) / 2 $

擬似コードを書くためのモジュールがない

Latex では有志が公開している algorithmicx などがあるが、 Typst ではこれに近いものはまだないようだった(あってもちょっと使いづらかった)。

作った

ファイルをインポートすればサクッと扱え、その上でテンプレートのカスタムが容易にでき、比較的自由にアルゴリズムの表現ができるものを目指した。

#import "../algomod.typ": algomod, algomodLink
#import "../algomod_statements.typ": *

#let algorithm = algomod()

#algorithm(
  title: [algorithm_title],
  label: <label>,
  lines: (
    Function("func_name", $a, b$),
      Let($"array" <- {1, 2, 3}$),
      While($"array.length" < 10$),
        $"array.push"("array.last" + 1)$,
      End(),
      ForAll("val", "array"),
        If($"val" > b$),
          $a <- a + "val"$,
        Else(),
          Return($a + b$),
        End(),
      End(),
      Return($a + b$),
    End(),
  )
)

You can place link to #algomodLink(<label>)

#let customedAlgorithm = algomod(
  // Change indent size
  indentSize: 1.2em,
  // Change format
  format: (title, lines) => [
    #block(
      fill: rgb("#EBEEF5"),
      radius: 8pt,
      pad(
        x: 2em,
        y: 1em,
      )[
        #title
        #v(.4em)
        #enum(..lines)
      ]
    )
  ]
)

// Customize statement
// preIndent: make indent in the current line
// postIndent: make indent in the next line
#let Comment(comment) = {
  return createStatement(
    preIndent: 0.5,
    postIndent: -0.5,
    [`//` #raw(comment)],
  )
}

// Override default statement
// You can (de)indent w/o displaying any lines like this
#let End() = {
  return createStatement(
    preIndent: -1,
    none,
  )
}

#customedAlgorithm(title: [algorithm_title], lines: (
  Comment("comment"),
  Function($"func_name"$, $a, b$),
    Let($"array" <- {1, 2, 3}$),
    ForAll($"val"$, $"array"$),
      If($"val" > b$),
        $a <- a + "val"$,
      End(),
    End(),
    Repeat(),
      $a <- a + b$,
    Until($a + b < 10$),
    Return($a + b$),
  End(),
))

image

あんまりカスタマイズしてないけど、例では End 句を全てインデントを1つ下げつつ、行には反映させないというものに変更し、背景色も変更した。
やろうと思えばフォントも変えられるし、命令の全てについて色を変更したり、行番号をいろはにほへとに変更したりもできる。

参考

GitHubで編集を提案

Discussion