以下の内容はhttps://zrbabbler.hatenablog.com/entry/2025/09/10/011340より取得しました。


Typstでの文字のsizeとサイズの話

この​「フォントサイズが実際にどう決まるのか」​という件について、もう少し詳しく説明する。

以下に述べる内容はTypstを実際に使う実験試行から導出したものである。公式の仕様ではないことに注意してほしい。

フォントサイズはどう扱われるか

まずはフォントサイズに関する基本的な事項を確認する。

  • Typstでのテキストのフォントサイズは「textエレメントのsizeパラメタ」(以降ではこれをtext.sizeと書く1ことにする)の値に一致する。
  • このtext.sizeパラメタはlength型の値をとる。
  • text.sizeパラメタの値を変更したい場合はset規則を用いる。
    例:set text(size: 20pt)
  • Typstの各種のエレメント(rawエレメント、math.equationエレメント、……)は種類ごとに異なる独立したtextエレメントのパラメタ」を保持していて、当然その中にはtext.sizeも含まれる。
  • rawエレメントのテキストのフォントサイズは「rawのtext.size」の値に一致する。
  • 「rawのtext.size」の値を変更したい場合はshow-set規則を用いる。
    例:show raw: set text(size: 20pt)
  • エレメント独自の方ではない本来のパラメタのことを本記事では「メインのパラメタ」と呼ぶことにする。

以上の事項を確認するための例を示す。

// Typstの既定のフォント設定だと"フォント自体の見かけの大きさ"が
// 不揃いであり紛らわしいので, 同じ系統のフォントに合わせる.
#set text(font: "Harano Aji Mincho")
#show raw: set text(font: "Harano Aji Gothic")

#set text(size: 14pt) // フォントサイズを設定
#show raw: set text(size: 14pt) // "rawのフォントサイズ"を設定
☃は素敵。// 14pt
`☃は素敵。`// 14pt

// text.sizeと"rawのtest.size"は独立して設定可能.
#set text(size: 10pt)
#show raw: set text(size: 20pt)
☃は素敵。// 10pt
`☃は素敵。`// 20pt

出力結果

em部分はどう扱われるか

Typstのlength型は、絶対的な長さ(abs)とフォントサイズ相対の長さ(em)からなる複合的な値2(例えば4pt+2em)である。length型の値を「実際の長さ」として解釈する場合にはem部分の値は「現在コンテキストのtext.sizeの値」として換算される(text.sizeが11ptであれば4pt+2emは26ptと解釈される)。一方で、set規則やshow-set規則でtext.sizeパラメタの値を設定する際に「現在コンテキスト」を参照するのは望ましくないだろう。

text.sizeの設定の際にはem部分は以下のように扱われる。

  • set規則やshow-set規則でtext.sizeに「Apt+Eem」を設定すると、実際には「『現在のtext.sizeの値』を E 倍して Apt を加算した値」に更新される。
  • 例えば「現在のtext.size」が8pt+2emであるときにset text(size: 5pt+0.5em)を実行すると、text.sizeの値は(8pt+2em)*0.5+5pt、つまり39pt+1emに更新される。
  • em部分が「現在のコンテキスト」に基づいて“解決”されるのではないことに注意。更新後の値も一般的にはem部分を持つ。
  • ただし、前述の規則から導かれる性質として、現在値がem部分を持たない場合は、どんな値を設定しても更新後の値は決してem部分を持たない。例えば現在値が11ptのときにset text(size: 5pt+0.5em)を実行すると10.5ptに更新される。
  • メインのtext.sizeの初期値は11ptである。従って先述の規則により、メインのtext.sizeは決してem部分を持たない。

text.sizeの値から「実際のフォントサイズ」を求める際にはem部分は以下のように扱われる。

  • メインのtext.sizeはem部分を持たないのでその扱いを考える必要はない。メインのtext.sizeは常に絶対的な長さでこれがそのまま「実際のフォントサイズ」となる。
  • rawのtext.sizeはem部分を持つ。これは当該のrawエレメントを含むすぐ外側のコンテキストの「実際のフォントサイズ」に換算される。
  • 例えば、rawのtext.size4pt+0.5emであり現在のフォントサイズが11ptである場合、rawエレメントの「実際のフォントサイズ」は9.5ptとなる。

text.sizeの初期値は以下の通りである。

  • メインのtext.size11pt
  • rawのtext.size0.8em

ここまで述べた規則を考慮すれば、メインとrawのフォントサイズを完全に把握することができるはずである。

実際にフォントサイズはどう扱われるか

さて今まで散々「規則」を述べてきたわけであるが、Typstの動作がそれと一致していなければ意味がない。そこで実際のTypstの動作を確認したいわけであるが、それには「現在のフォントサイズ」を調べる手段が必要である。

Typstの「現在のフォントサイズ」を調べる

Typstのコードモードにおいてtext.sizeという式を書くと現在のコンテキストにおけるtext.sizeの値が取得できるはずである。ただし実際の動作としてはこれで取得できる値はem部分を解決した後の「現在のフォントサイズ」のようである。ともかく、以下のマークアップで「現在のフォントサイズ」を知ることができる。

#context [#repr(text.size)]

ただしrawエレメントについてはその特質上「rawの中でコードモードに移行する」ことができないので、「現在のフォントサイズ」を知るには少しトリックが必要である。以下のようなコードを利用する。

#show raw: _ => repr(text.size)

すなわちshow規則を利用して「rawの中でコードモードに移行する」ことを無理やり実現するわけ4である。このshow規則が有効な状態で​`x`​と書くと、“x”の代わりに「rawでの現在のフォントサイズ」が出力される。

合わせると、以下のようにcurrentを定義5すると#currentでメイン・raw内の「現在のフォントサイズ」が出力されることになる。

#let current = context {
  show raw: it => repr(text.size)
  [#repr(text.size) / `x`]
}

Typstの「フォントサイズの規則」を調べる

動作確認用に以下の文書コードを用意した。

// 現在フォントサイズを表示するやつ
#let current = context {
  show raw: it => repr(text.size)
  [#repr(text.size) / `x`]
}

//// 実験用コード

// raw/text.size = 0.8em
#show raw: set text(size: 8pt+2.5em)
// raw/text.size = 8pt+2em
#show raw: set text(size: 5pt+0.5em)
// raw/text.size = 9pt+1em
#show raw: set text(size: 2em-13pt)
// raw/text.size = 5pt+2em

// text.size = 11pt
#current // "11pt / 27pt"となるはず

#set text(size: 20pt)
// text.size = 20pt
#current // "20pt / 45pt"となるはず

このコードの要点は以下の通りである。

  • rawのtext.sizeへの設定を何度か繰り返すことで、設定の規則が自分の想定通りになっていることを確認する。
  • メインのtext.sizeの2通りの設定の下でメイン・rawの現在フォントサイズを調べることで、rawのtext.sizeが内部的にはem部分を持っている(そこはメインのフォントサイズに換算される)ことを確認する。

実際にTypstでコンパイルすると以下の出力が得られた。

出力結果

このコードの範囲では、全て想定通りに動作していることが判った😊

まとめ

Typstはナニカより簡単😍(簡単😭)


  1. 実際にTypstのコードモードでtext.sizeと書くことでこのパラメタの現在コンテキストでの値を取得することができる。もちろん「現在コンテキスト」が確立している(例えばcontext式の中にいる)必要がある。
  2. TeXCSSにおいては「長さの値」は絶対的な部分しか持たず、“em単位”は常にその場で解釈される。例えばTeXにおいてem値が12ptのときに\dimen0=1emの代入を行ったとすると、\dimen0がもつ値は単に12ptとなる。これに対してTypstでlet len=1emの代入を行ったとするとlenがもつ値は“1em”そのものとなり、これの実際の長さは「現在のコンテキスト」に応じて変化する。
  3. 実際にTypstでコードモードで(8pt+2em)*0.5+5ptという式の値は9pt+1emとなる。
  4. なお、rawに対するshow規則のコードは「raw独自のtext関連パラメタ」が適用された状態で実行される。show規則の仕様で、この状態のコンテキストが暗黙的に確立されている。
  5. このcurrentが関数ではなく「単一のcontent値」であることにも注意してほしい。currentは「コンテキストに依存するcontent値」であるため、書いた場所によって全く異なる出力になることが可能である。



以上の内容はhttps://zrbabbler.hatenablog.com/entry/2025/09/10/011340より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14