2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

TypstAdvent Calendar 2024

Day 8

Typstで☃のマフラーの色を指定する方法

Last updated at Posted at 2024-12-08

Typstの重要な目的の一つは「LaTeXのよりよい代替となること」です。そして、皆さんご存知の通り1、LaTeXといえばゆきだるま:snowman:です。となると、Typstでも:snowman:ができることが求められるのは当然の帰結でしょう2

というわけで、本記事では​「好きな色のマフラーを付けたゆきだるま:snowman:を出力する」​ことに関して、とりとめなく話したいと思います:bow:

TeXのConfの話の話

いきなり“Typst以外”の話で恐縮ですが、先月末(2024年11月30日)に富山において「TeXConf 2024」3が開催されました。その最後を飾ったのが鹿野桂一郎氏による「文字の一部に色を塗る」と題した講演です。

この講演では「単一の文字を複数の色に塗り分けて出力する」というタスクについて種々の文書作成ソフトウェア上での実現方法について述べています。具体的には2種類の実装方針を紹介しています。

image-1.png
グリフパスのクリップを利用する方法
(PostScriptでの実装)
image-2.png
TikZ上で実現する方法
(LaTeX+TikZでの実装)

腕に覚えのあるTypstユーザの皆さんは、Typst上で「文字の一部に色を塗る」ことに挑戦してみるのもいいでしょう:information_desk_person:

それに続いて「ゆきだるまの字形☃のマフラーに色を付ける」という発展的な課題について話していたようです4

image-3.png
:snowman:のマフラーに色を塗る

具体的には「任意に与えられた☃の字形について、前処理を許容した上で、マフラー部分の領域を自動的に取得して別の色を塗る」という問題を扱っています。前処理を行えるのでグリフパスの取得が可能ですが、☃の字形中でマフラーの部分が他から独立しているわけでなく、そもそもどの部分がマフラーであるのか事前には判らないため、話は簡単ではありません。講演では機械学習を利用したアプローチを紹介しています。

鹿野氏の講演はとても面白い話なのですが、でも本記事の話題はこの講演の話とは直接は関係ありません。ただ「ゆきだるま:snowman:マフラーに色を付ける」というところだけが関係しています。

:snowman:のConfの話の話

Typstの動向を早くから注視していた人であれば、「:snowman:のマフラーに色を付ける」と聞いてsc1Typstのことを思い出したかもしれません。

昨年(2023年)の11月11日(1が4つ並ぶきりたんぽの日です:smiley:)に某ツイッタァー(現𝕏)において「ナントカConf 2023」5が開催されました。その最後6を飾ったのが某ZR氏による「アレをもっともっと画期的にする話」と題した講演です。

その講演において「:snowman:」と「1」にちなんで紹介されたのが「1を入力して:snowman:のマフラーに色を付ける」ための画期的なTypstモジュールであるsc1Typstです。

sc1Typstを利用したTypst文書では多数の「1」を入力すること文書ソースを作成します。

#import "sc1typst.typ":*; #show:_1
1
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111

この文書ファイルを通常の手順でTypstでコンパイルすると、マフラーに色がついた:snowman:が出力されます。実は、このマフラーの色は先ほどのソース中に書いた「1」の数から決まるようになっています。

image-4.png
出力結果

ところで、この出力中の:snowman:は(鹿野氏のスライドのものと同じ外見であることから判るように)フォントの字形です。つまり、「ゆきだるまの字形☃のマフラーに色を付ける」ネタに関しては、Typstの方がLaTeXよりも1年も先行していたことになります。やっぱり時代はTypstですね:wink:(えっ)

ただし、sc1Typstが使うフォントは固定(原ノ味明朝7)なので「予め抽出したグリフパスのデータを実装コードに直書きする」ことができます。なのでこの辺りについて技術的に面白い点はありません:upside_down:

時代の話は措いておきましょう。世の中には「ゆきだるまの字形☃のマフラーに色を付ける」機能はぜひとも欲しいが一方で「『1』を並べて入力する」方式は全く不要という人もいるでしょう。そういう人にとっては「1」を並べる方式のsc1Typstは向いていないでしょう。

とはいってもsc1Typstの実装コードの中には「マフラーに色を付ける」処理が書かれているはずで、そこだけを抽出して新しいモジュールを作ればよさそうです。何といっても、Typstのスクリプト言語はTeX言語:scream:と違ってとても読みやすいことで有名です。早速sc1Typstの実装コードを眺めてみましょう:smiley:

image-5.png
(某ZR氏のスライドより抜粋)

11月11日のネタ用のコードであるためか、チョット読みにくい:christmas_tree:ですね……(ざんねん:upside_down:

(以上で長い長い長い前フリ終わり:upside_down:

フツーのTypstモジュールの話

というわけで、「ゆきだるまの字形☃のマフラーに色を付ける」ための読みにくくないTypstモジュールをつくりました:smiley:

一応パッケージ(package)の形にしてあるので、ローカルでインストールすればパッケージとして読み込めます。

// ローカルインストールしてパッケージとして読み込む場合
#import "@local/scmuffler:0.2.0": *

ですが、単純にscmuffler.typのファイルをカレントディレクトリに配置してモジュールとして読み込むのでもいいでしょう。

// カレントに置いてモジュールとして読み込む場合
#import "scmuffler.typ": *

sc1Typstと同様に「原ノ味明朝」フォントをTypstで利用可能な状態にしておく必要があります。(一番手っ取り早い方法はフォントをOSにインストールすることです。)

おやくそく

この節に挙げる例では和文用の最低限のレイアウト設定として次のモジュールを使用します。

layout.typ
// 和文用の最低限のレイアウト設定
#set paper(page: "a5")
#set text(
  lang: "ja",
  font: "Harano Aji Mincho", // 全面的に"原ノ味明朝"を使う
  top-edge: 0.88em,
)

キホン的な使い方

scmufflerパッケージは次の関数を提供します。

  • scmuffler(«色»)[content値]: マフラーの部分を«色»(color値)で指定した色に変えて(原ノ味明朝の)“☃”の文字(U+2603)を出力する。

例えば次のような文書ソースを用意します。

example-1.typ
#import "layout.typ": *
#show: doc // おやくそく
// モジュール読込
#import "scmuffler.typ": *

// "scmuffler(olive)"でolive色のマフラーの☃を出力
私は#scmuffler(olive)よりも#scmuffler(red)の方が好きです。

これをコンパイルすると、以下の出力が得られます。

image-6.png
出力結果

素敵:blush:

マフラーの色を少しずつ変えていく

これ以降はプログラミングを利用します :bow:

Typstのcolor.mapモジュールで提供される​“turbo”のカラーマップの配色を利用してマフラーの色をグラデーションにしましょう。

sample-2.typ
#import "layout.typ": *
#show: doc
#import "scmuffler.typ": *

// カラーマップからgradient値を作る
#let turbo = gradient.linear(..color.map.turbo)
// "sample()"で色を抽出できる
#for k in range(21) {
  scmuffler(turbo.sample(k / 20.0 * 100%).darken(25%))
}
image-7.png
出力結果

素敵:blush::blush:

箇条書きの番号を色付きマフラーの☃にする

  • muffler-numbering(«色»,…)[function値]: 色付きマフラーの☃を利用したカウンタ書式関数を生成する。マフラーの色は引数に指定したcolor値が順番に使われる。
example-3.typ
#import "layout.typ": *
#show: doc
#import "scmuffler.typ": *

// muffler-numbering(<色>,...)
// 色付きマフラーの☃を利用したカウンタ書式関数を生成する.
// マフラーの色は引数に指定したものが順番に使われる.
#let muffler-numbering(..args) = {
  let colors = args.pos()
  (value) => {
    scmuffler(colors.at(calc.rem-euclid(value - 1, colors.len())))
  }
}

#set enum( // 赤・青・緑のマフラーを反復する
  numbering: muffler-numbering(red, blue, olive),
)
// Universeにあるパッケージの名前🙃
+ 粗体(cuti)
+ 口胡(kouhu)
+ 随機(suiji)
+ 条碼(tiaoma)
+ 投影(touying)
image-8.png
出力結果

素敵:blush::blush::blush:

まとめ

TypstでもLaTeXでも何でもいいので、イロイロな色のマフラーを着けたゆきだるま:snowman:が入った文書をドンドンつくりましょう!:blush:

  1. えっ、ご存知でしょ?:snowman:

  2. アッ、某“Typst以外”の記事の書き出しの使い回しだ!:astonished:

  3. TeXConfはTeX・組版・出版とその周辺に関する知見を共有することを目的とした会議です。

  4. あるいは、時間切れのため話していないのかもしれません。(TeXConf 2024に参加していない人並感 :upside_down:

  5. ナントカConfは:snowman::snowman2:とその周辺に関する知見を共有することを目的とした会議です。

  6. なお「ナントカConf 2023」の講演数は全部で1件でした。

  7. Typst Appで使用可能な日本語用フォントの一つです。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?