Physics Lab. 2024のロゴ

アドカレ|8日目

Typst 便利パッケージと使用例の紹介

はじめに

Typstは、最近にわかに流行の兆しを見せている組版ソフトウェアです。TypstではLaTeXでamsmathやamssymbなどのパッケージで実現されていた機能の大部分がデフォルトで実装されており、簡単に文書を書くことができます。

さらに、標準にはない機能を補う優れたパッケージが数多く公開されており、容易に使うことができます。この記事では、Typstの便利なパッケージを紹介します。

Typstのインストール方法や基本的な文法については解説しません。他のネット記事や公式ドキュメントを参照してください。

パッケージの導入方法

公式のパッケージリポジトリに登録されているパッケージについては、ファイル中に

#import "@preview/{パッケージ名}:{バージョン}"

と書くことで自動的にダウンロードされ、使えるようになります。上記の書き方ではパッケージ名の名前空間に変数などが展開されますが、

#import "@preview/{パッケージ名}:{バージョン}: *"

と書くとデフォルトの名前空間に展開されます[1]。公式のパッケージリポジトリに登録されているパッケージについては、Typstの公式サイトに簡単な説明つきの一覧があります。

公式のパッケージリポジトリに登録されていないパッケージについては、これほど簡単に導入することはできません。そのようなパッケージの導入方法については個々のパッケージのReadmeを参照してください。以下で紹介するパッケージは全て公式のパッケージリポジトリに登録されています。

Physica

Physicaは物理でよく使われる多種多様なシンボルを追加するパッケージです[2]

#import "@preview/physica:0.9.0": *
- 微分
$
dv(f,x),quad dv(f,x,2),quad dv(f,x,s:\/),quad \
dd(f),quad dd(x,y,z),\
pdv(f, x),quad pdv(f,x,y),quad pdv(,x),quad pdv(,x,y,z,[2,1,3])
$
- ブラケット
$
ket(psi),quad bra(phi),quad braket(psi,phi),quad ketbra(psi,phi),quad mel(psi,A,phi)
$
- テンソル
$
tensor(Gamma,+mu,-nu,-rho),quad tensor(R,+mu,-nu,-rho,-sigma),quad tensor(A,+mu,-nu,-rho,+sigma)
$
- 原子
$
isotope("U",a:238,z:92) --> isotope("Th",a:234,z:90)+isotope("He",a:4,z:2)
$

image.png

Physicaにはこの他にもたくさんの便利な関数があります。

ディラック定数についての注意

ディラック定数を表すものとしてTypst本体にはplanck.reduceがありますが、デフォルトでは横棒が斜めになっています。これはデフォルトの数式フォントでディラック定数を表す文字 ℏ (U+210F) の横棒が斜めになっているからです。

Physicaパッケージのhbarは横棒がまっすぐです。これはプランク定数を表す文字 ℎ (U+210E) に打ち消し線(strike)を加えて実装されているためです。このため打ち消し線の色を変えるとhbar横棒の色が変わってしまいます

これらの問題は、ℏ の横棒がまっすぐであるような代替字形を含むフォントを使うことで解決することができます。例えば次のようにhbarを定義することでまっすぐな横棒を持つディラック定数が得られます。

#let hbar = (sym.wj, text(font: "Stix Two Math", stylistic-set: 3)[#math.planck.reduce], sym.wj).join()

sym.wjを使っているのは、textだけだと前後のスペースがおかしくなるからです。

3種類の方法を比較します。

#import "@preview/physica:0.9.0" as physica

#let hbar = (sym.wj, text(font: "Stix Two Math", stylistic-set: 3)[#math.planck.reduce], sym.wj).join()

$
"planck.reduce: " &planck.reduce,quad E=planck.reduce omega,quad i planck.reduce c\
"physica.hbar: " &physica.hbar,quad E=physica.hbar omega,quad i physica.hbar c\
"hbar: " &hbar,quad E=hbar omega,quad i hbar c
$

image.png

Physicaのhbarと代替字形で定義したhbarでは横棒がまっすぐになっていることが分かります。代替字形で定義したhbarにはstrikeの色などに関する問題がないので、こちらを使った方が良いと思います。

CetZ

CetZはTeXにおけるTikZに相当する図を描画するパッケージです。Typst本体でも基本的な図形の描画を行うことができますが(公式ドキュメント)、CetZを使うとより高度な描画ができます。詳しい使い方はマニュアルを参照していただくとして、描画できる図の例をお見せします。

#import "@preview/cetz:0.1.1"

#let linspace(start, end, n)=range(0,n).map(x => x / n * (end - start) + start)

#cetz.canvas({
    import cetz.draw: *
    line((0,0), (5,0), mark: (end: ">"))
    content((), block(inset: 0.2em)[$abs(bold(p))$], anchor: "left")
    line((0,-5), (0,5), mark: (end: ">"))
    content((), block(inset: 0.2em)[$p^0$], anchor: "right")
    let pa = linspace(0, 4, 100).map(x => (x, calc.sqrt(9+x*x)))
    line(..pa, stroke: red)
    let pb = linspace(0, 4, 100).map(x => (x, -calc.sqrt(9+x*x)))
    line(..pb, stroke: blue)
    line((0,0), (5,5), stroke: red)
    line((0,0), (5,-5), stroke: blue)
    let pe = linspace(-4, 4, 100).map(x => (calc.sqrt(9+x*x), x))
    line(..pe, stroke: olive)
    let draw-point(pos, text, color, anchor) = {
        circle(pos, radius: 0.1, fill: color, stroke: none)
        content((), block(inset: 0.3em)[#text], anchor: anchor)
    }
    draw-point((0, 3),  "(a)", red, "right")
    draw-point((0, -3), "(b)", blue, "right")
    draw-point((1, 1),  "(c)", red, "bottom-right")
    draw-point((1, -1), "(d)", blue, "top-right")
    draw-point((3, 0),  "(e)", olive, "top-right")
    draw-point((0, 0),  "(f)", olive, "right")
})

image.png

Typstではletを使って簡単に関数を定義することができるので、描画中の共通する操作を関数にまとめることができ簡潔にコードが書けます。この例でもdraw-pointというラベル付きの点を描画する関数を定義して使っています。

Tablex

Typstは標準でtableという表を描画する関数(公式ドキュメント)があります。しかし1つ1つのセルごとに罫線をカスタマイズしたり、セルを結合したりすることはできません。このような機能は将来的に標準で実装される予定があるそうですが、現在でもTablexというパッケージを使えば非常に複雑な表を書くことができます。

#import "@preview/tablex:0.0.6": *
// この関数は https://github.com/typst/typst/issues/528#issuecomment-1494318510 から引用。
#let rotatex(angle,body) = style(styles => {
  let size = measure(body,styles)
  box(inset:(x: -size.width/2+(size.width*calc.abs(calc.cos(angle))+size.height*calc.abs(calc.sin(angle)))/2,
             y: -size.height/2+(size.height*calc.abs(calc.cos(angle))+size.width*calc.abs(calc.sin(angle)))/2),
             rotate(body,angle))
})
#let colorA = red.lighten(50%)
#let colorB = blue.lighten(50%)
#let colorC = orange.lighten(50%)
#let colorD = green

#gridx(
  columns: 5,
  align: center + horizon,
  row-gutter: 0pt,
  hlinex(start: 2),
  vlinex(start: 2), [], vlinex(start: 2), [], vlinex(), colspanx(3)[期末試験の点数],
  hlinex(start: 2),
  [], [], [0\~49], vlinex(start: 1), [50\~79],
  vlinex(start: 1, end: 4), vlinex(start: 4, expand: -1pt, stroke: colorA),
  [80\~100], vlinex(),
  hlinex(),
  rowspanx(3, rotatex(-90deg)[中間試験の点数]),
  cellx(rotatex(-90deg)[0\~49]),cellx(fill: colorD)[D],
  rowspanx(2, fill: colorB)[B],rowspanx(3, fill: colorA)[A],
  hlinex(),
  cellx(rotatex(-90deg)[50\~79]),cellx(fill: colorC)[C],
  hlinex(),
  cellx(rotatex(-90deg)[80\~100]),cellx(fill: colorB)[B], cellx(fill: colorA)[],
  hlinex()
)

image.png

次のような関数があります。

関数 機能
tablex
gridx デフォルトで罫線がないtablex
cellx カスタマイズできるセル
colspanx 横に結合したセル
rowspanx 縦に結合したセル
hlinex 水平線
vlinex 鉛直線

詳しい使い方はTablexのReadmeを参照してください。

Metro

Metroは単位を扱うことができるパッケージです。TeXにおけるsiunitxに相当します。

#import "@preview/metro:0.1.0": *

- 数値: #num(1.23, e:8), #num(1.23, e:8, minimum-decimal-digits: 3)
- 単位: #unit("keV"), #unit("m/s"), #unit("J/(K m^3)")
- 単位の別表記: #unit("m/s", per-mode: "symbol"), #unit("J/(K m^3)", per-mode: "symbol")
- 単位付きの数値: #qty(511, "keV"), #qty(1.23, e: 8, "m/s")
- 誤差付き: #qty(511, pm: 3, "keV"), #qty(1.23, pm: 0.01, e: 8, "m/s")

image.png

次のような関数があります。

関数 機能
num 数値
unit 単位
qty 単位付きの数値

詳しい使い方はマニュアルを参照してください。

また1つ1つの関数にオプションをつけていると面倒なので、metro-setupという関数でまとめてオプションの値を設定することも可能です。

その他

これまで紹介したパッケージの他にもTypstには数多くのパッケージが存在します。いくつかのパッケージをまとめて紹介します。

  • Algo: 擬似コードが書ける。
  • codelst: ソースコードが書ける。
  • Commute: 可換図式が書ける。
  • Pinit: 矢印を使った説明が書ける。
  • Polylux: スライドが作れる。
  • Prooftrees: 証明図が書ける。

おわりに

Typstは積極的に開発が行われており、パッケージの作成といったユーザーの活動も活発です。ぜひTypstを使って文書を作りましょう。

追記

2023-12-9: @Yarakashi_Kikohshi 様のコメントを基にPhysicaパッケージの解説に「ディラック定数についての注意」という節を加えました。


  1. importの詳細については公式ドキュメントの記載を参照してください: https://typst.app/docs/reference/scripting/#modules ↩︎

  2. LaTeXでいうphysicsパッケージに相当するものですが、physicsパッケージが抱える数多くの問題はPhysicaにはないと思います。 ↩︎