Typst における高校数学テンプレート

目次

Typst は、2023年にパブリックベータ(まだこれから破壊的変更があるかもしれない)が公開されたオープンソースの組版ソフトウェアである。記法の易しさとタイプセットの速さから話題となっている。

ここでは、高等学校数学科教員の立場から、Typst の性格と理念を考えながら、高校数学資料(授業プリント)用の体裁を整えることを試みる。

Typst はまだ若いプロジェクトであり、頓挫することを心配する声もある。書いた原稿が活かせるよう、関数/マクロを置きかえることでほぼ同じ資料が実現できるよう、体裁を似せて設計した。

Typst の紹介そのものは次の記事で行った。

背景

LaTeX と Typst

私はこれまで、高校数学における教材を LaTeX で作ってきた。数学教育界隈ではおそらく Studyaid D.B. が主流だが、プロプライエタリなソフトウェアであり、何らかの事情で Studyaid D.B. が使えない・使いにくい状況になったとき、失うものが大きい。そこで、 オープンソースなソフトウェアであり、OS に依らず、自動化が図れ、仕上がりも美しい LaTeX を選んだ。

LaTeX にはいろいろとあるが、これから先を考えると pLaTeX / upLaTeX よりも LuaLaTeX を使うのがよいと考え、それらのためにテンプレートを用意した。ところが、望む体裁を整えるために処理が多くなり、もとより LuaLaTeX のタイプセットが遅いことも相まって、1枚の資料を作るために待たされる時間が長くなっていた。

Typst は、2023年にパブリックベータが公開されたオープンソースの組版ソフトウェアである。記法の易しさとタイプセットの速さから話題となっている。実際、入力とほぼ同時に処理が進んでゆき、待たされる時間がない。また、記法が易しく、入力そのものが少なくてすむ。また、それらの利点からユーザが増えており、将来も期待ができる。

教材づくりにおいては、ほかの業務との兼ねあいもあり、出版に堪える出力よりも短い時間でそれなりに完成することの価値が高い。Typst は執筆中のタイプセット待ち・エラー対応に優れるので、より向いているかもしれない。

私個人の感覚については、別の記事で述べる

仕上がりの比較

解決

  • ひとまずすべて取り込むのであれば,ダウンロードから .typ ファイルを入手して #import すると楽である。
  • 一部の機能を選んで使うにあたっては,補足からコードをコピーするほうが楽である。

Readme

  • 私家版である。いろいろと難があると思われるが、今はまだ情報が少ないので、広める意味があると考えた。
  • 単位(empt など)を吟味していない。一部を変えると全体が崩れるおそれなどもある。
  • 本来は #for#while で処理すべきところがいくつもあるが、上手く動かないなどしたため、腕力で済ませている。
  • Typst 0.12.0 のもとで作ったものである。これからの維持については未定である。

ダウンロード

上にあるほうが新しい。

テンプレートの登録(スニペット)

テンプレートを別ファイルとして取り出しても、#import やタイトル設定などは書かねばならない。これらは次のように登録しておくと楽になる。

補足

テンプレート全体でなく、一つひとつの機能を使えるよう、役立ちそうなものをここに載せておく。

引用の横に棒を付す

  • par(text(size: 0pt, ""))... は1行めの字下げのためにつけている。適した v の大きさはフォント指定により変わるだろう。

コード

#import "@preview/showybox:2.0.1":*
#let blockquote(body) = showybox(
  frame: (
    thickness: (left: 1pt),
    radius: 0pt
    ),
  par(text(size: 0pt, ""))
  + v(-1em-2.926pt)
  + body
  )

使用例

#blockquote[
	引用文
]

ブロック要素を破線で囲む

  • par(text(size: 0pt, ""))... は1行めの字下げのためにつけている。適した v の大きさはフォント指定により変わるだろう。

コード

#import "@preview/showybox:2.0.1":*
#let blockthink(body) = showybox(
  frame: (
    thickness: (0.4pt),
    dash: "densely-dashed",
    radius: 0pt
    ),
  par(text(size: 0pt, ""))
  + v(-1em-2.926pt)
  + body
  )

使用例

#blockthink[
	点線囲み文
]

インライン要素を破線で囲む

コード

#let boxthink(body) = box(
  height:0.75em,
  text(
    baseline: -3pt,
    box(
      height: 1.3em,
      stroke: (thickness: 0.4pt, dash: "dashed"),
      pad(
        6pt,
        h(-3.375pt)
        + body
        + h(-3.375pt)
      )
    )
  )
)

使用例

#boxthink[点線囲み文]

式番号を右端ではなくやや内側にする

  • きわめてアドホックな処理である。全角スペースを使って左へ寄せている。

コード

#set math.equation(numbering: "……①  ", number-align: right + bottom)

一部のみに式番号を振る

  • 全体には式番号を付けずにおき、式番号を振りたいものにのみ新たな命令を使う。

コード

#let eqno(body) = math.equation(block: true, numbering: "……①  ", number-align: right + bottom)[$#body$]

使用例

#eqno[$
a
$]

インライン数式に式番号を振る(手動・引用不可)

  • 教材なので、式番号は高々数個であることを前提にした。

コード

#let inlinenumbering(body) = text(font: "New Computer Modern Math","……") + body

使用例

$a$ #inlinenumbering[①]

AA でローマン体、AAA で黒板太字に書き換える

  • もとは AA で黒板太字になるが、高校数学の教材であれば点などでローマン体を使うことが多いだろう。

コード

// # Roman
#let AA = $upright(A)$
#let BB = $upright(B)$
#let CC = $upright(C)$
#let DD = $upright(D)$
#let EE = $upright(E)$
#let FF = $upright(F)$
#let GG = $upright(G)$
#let HH = $upright(H)$
#let II = $upright(I)$
#let JJ = $upright(J)$
#let KK = $upright(K)$
#let LL = $upright(L)$
#let MM = $upright(M)$
#let NN = $upright(N)$
#let OO = $upright(O)$
#let PP = $upright(P)$
#let QQ = $upright(Q)$
#let RR = $upright(R)$
#let SS = $upright(S)$
#let TT = $upright(T)$
#let UU = $upright(U)$
#let VV = $upright(V)$
#let WW = $upright(W)$
#let XX = $upright(X)$
#let YY = $upright(Y)$
#let ZZ = $upright(Z)$
// # Blackboard
#let AAA = $bb(A)$
#let BBB = $bb(B)$
#let CCC = $bb(C)$
#let DDD = $bb(D)$
#let EEE = $bb(E)$
#let FFF = $bb(F)$
#let GGG = $bb(G)$
#let HHH = $bb(H)$
#let III = $bb(I)$
#let JJJ = $bb(J)$
#let KKK = $bb(K)$
#let LLL = $bb(L)$
#let MMM = $bb(M)$
#let NNN = $bb(N)$
#let OOO = $bb(O)$
#let PPP = $bb(P)$
#let QQQ = $bb(Q)$
#let RRR = $bb(R)$
#let SSS = $bb(S)$
#let TTT = $bb(T)$
#let UUU = $bb(U)$
#let VVV = $bb(V)$
#let WWW = $bb(W)$
#let XXX = $bb(X)$
#let YYY = $bb(Y)$
#let ZZZ = $bb(Z)$

使用例

$a in AA, b in RRR$

よく使う記号を名づけておく

コード

#let cdots = $dots.h.c$
#let tand = $"and"$
#let tor = $"or"$
#let GCD = math.op(math.upright("GCD"))
#let LCM = math.op(math.upright("LCM"))
#let pair(a,b) = $(#a,thick #b)$
#let triplet(a,b,c) = $(#a,thick #b,thick #c)$
#let quadruplet(a,b,c,d) = $(#a,thick #b,thick #c,thick #d)$
#let overarc(body) = $accent(
  body,
  paren.t
)$
#let parallel = $slash.double$
#let parallelnot = $slash.double #h(-6pt) backslash #h(3pt)$
#let similar = math.op(text(baseline: 0.75pt, font: "Yu Mincho","∽"))
#let triangle = "△" + h(0pt)
#let permutation(n,r) = $attach(upright("P")#h(-1pt), bl: #n, br: #r)$
#let combination(n,r) = $attach(#h(-0.25pt)upright("C"), bl: #n, br: #r)$
#let repeatedpermunation(n,r) = $attach(upright(Pi), bl: #n, br: #r)$
#let repeatedcombination(n,r) = $attach(upright("H"), bl: #n, br: #r)$
#let homogeneous(n,r) = $attach(upright("H"), bl: #n, br: #r)$
#let expected = $upright(bold(E))$

使用例

$
a_1+a_2+a_3+cdots+a_n\
(A tand B) tor C\
GCD(a,b) + LCM(a,b)\
pair(a,b)\
overarc(upright(A B))\
l parallel m\
triangle upright(A B C) similar triangle upright(D E F)\
permutation(n,r)\
expected(A)
$

ベクトル・複素共役で ab の高さを揃える

  • arrow はアクセント文字のため長さの調整が離散的で、avec(a_i) などに難がある。

コード

#let invisibleheight = h(0pt) + box(height:0.7em, width:0em) + h(0pt)
#let avec(body) = $arrow(body invisibleheight)$
#let complement(body) = $overline(body invisibleheight)$
#let conjugate(body) = $overline(body invisibleheight)$

使用例

$
  avec(a)+avec(b)\
  conjugate(a)+conjugate(b)
$

ヘッダにページ・タイトル・メモを載せ下線を引く

コード

#let doctemplate(Title,Note,Document) = {
set page(
  paper: "a4",
  header:
    par(spacing: 5pt)[
    #context{counter(page).display("1/1", both: true)}
    #h(1em)
    #text(font: "Yu Gothic", weight: 500, Title)
    #h(1fr)
    #Note
    #line(
      length: 100%,
      start: (0% + 0pt, 0% + 0pt),
      stroke: 0.4pt
      )
    #v(5pt)],
    header-ascent: 1em,
)
Document
}

使用例

  • 本文のはじめに書く。
  • 「1/1 タイトル (空白)メモ」のようなヘッダに下線が引かれる。
#show: Document => doctemplate(
  "タイトル",
  "メモ",
  Document
)

日本語に合わせて強調を設定する

  • 本文は明朝と仮定し、strong はゴシックに変え、emph は下線を付すものとした。
  • LaTeX では苦労するところだが、Typst は日本語下線も自動的に折り返してくれる。

コード

#show strong: set text(font: "Yu Gothic")
#show emph: it => {
  underline[#it]
}

使用例

_あ_ *あ*

数式中の日本語フォントを変更する

コード

#show math.equation: set text(font: ("New Computer Modern Math","Yu Mincho"), size: 12pt)

使用例

$A あ$

数式を左寄せのうえ字下げする

コード

#show math.equation.where(block: true): set align(left)
#show math.equation.where(block: true): eq => pad(left: 2em, eq)

使用例

A
$
1+2=3
$

分数・極限・積分は常に大きく表示する

  • 本文は明朝と仮定し、strong はゴシックに変え、emph は下線を付すものとした。

コード

#show math.frac: math.display
#show math.integral: math.display
#let lim = $limits(#math.op("lim"))$

使用例

inline $1/2 + lim_(x -> oo) integral_1^x f(x) d x$  inline

± の短縮入力

  • 同じパッケージにより自由に決められる。

コード

#import "@preview/quick-maths:0.1.0": shorthands
#show: shorthands.with(
  ($+-$, $plus.minus$),
  ($-+$, $minus.plus$),
)

使用例

$1 +- sqrt(2) -+ a$

不等号のイコールを二重に変える

コード

#import "@preview/quick-maths:0.1.0": shorthands
#show: shorthands.with(
  ($<=$, $lt.equiv$),
  ($>=$, $gt.equiv$),
)

使用例

$1 >= 1 <= 2$

実部・虚部をラテン立体にする

コード

#show math.Re: math.upright("Re") + h(2pt)
#show math.Im: math.upright("Im") + h(2pt)

使用例

$Re z + i Im z$

できていないこと

LaTeX 版のテンプレートで実現できている機能・体裁を順に・すべて実装するのではなく、ひとまず講義資料として最低限の役目を果たせるように作り、少しずつ高みを目指す。

Typst そのものが若く、破壊的な変更もあることを織り込み、凝りすぎない。

  • 句読点のぶら下げに対応していない。
  • !や?の直後に」が来るときに文字を詰めてしまう。
  • explannomination における英字のフォントサイズが小さなままである(#show regex … を使うとほかのフォントサイズ指定が効かなくなるので見送っている)。
  • 数式内の日本語でカンマのフォントが Yu Mincho にならない(全角幅でない)。
  • avec の矢印の長さが離散的にしか伸びない。
  • 増減表や置換積分の対応表などが作れていない。
  • スイッチングにより表示を切り替える関数が作れていない。

参考

アイディア

テンプレートを作るにあたっての戒め

次の記事は (La)TeX 向けのものであるが、よい戒めとして残しておく。

改訂