LaTeXで独自に作図した図形を記号として使う

この記事は[TeX ＆ LaTeX Advent Calendar 2022](https://adventar.org/calendars/7868)の19日目の記事です．（遅くなってすみません．）
18日目は [CareleSmith9](http://circle9tym.blog.fc2.com/blog-entry-417.html) さん，20日目は [MusicDump](https://qiita.com/MusicDump0710/items/0ded9eb9b07d3e2f8130) さんです．
予告にはexpl3でなにかやると書いていましたが，色々あって時間が取れず，やってるうちにクリスマスも過ぎてしまいそうなので，この間使った tikzsymbols の紹介をしたいと思います．

ソースコードと出力のpdfは [GitHub で公開しています](https://github.com/Yukishita26/Misc/tree/main/tikz-new-symbol)．

## ユーザー定義の記号の作成

数学的な文書を書くとき，既存の記号の組み合わせでは表せないような新しい記号を作りたいということ，ありますよね．

`\kern`を使って直接作図したりすると TeX 言語が始まってしまいしんどいので TikZ を使います．
tikzpicture 環境で書いた図形を記号として使うための，パラメータ調整やオプションの引数のやり取りを簡略化できる [tikzsymbolsパッケージ](https://ctan.org/pkg/tikzsymbols) というものがあります．

```tex
\usepackage{tikzsymbols}
%
\tikzsymbolsdefinesymbol{<シンボル名>}{<引数形式>}{
    \begin{tikzpicture}[/tikzsymbolsstyle,<TikZオプション>]
        % 描画
    \end{tikzpicture}
}
```

とすると `\<シンボル名>` のコマンドが作成できます（定義するときの引数には「\」を入れないので注意）．
引数はxparse[^xparse]に似ているが簡略化された形式で，

[^xparse]: 使い勝手の良いコマンドを作るためのシステム．今回のアドベントカレンダーでも解説されています（[\NewDocumentCommand さえあればいい。〜TeX 言語に手を出してしまう前に〜](https://tairahikaru.github.io/texadvent2022/) - thth さん）．

+ `m`：必須引数（`{}`で与える）
+ `B{<default>}`：オプション引数．<default>は引数を与えなかったときのデフォルト値
+ `S`：スケーリング引数（オプション）．記号の拡大縮小のファクター

を0個以上並べて表記します．詳細は[公式マニュアル](https://ftp.yz.yamagata-u.ac.jp/pub/CTAN/graphics/pgf/contrib/tikzsymbols/tikzsymbols.pdf)の5章を参照．

## 四角形記号

例として四角形記号を考えてみます．三角形ABCを ⊿ABC [^triangle]と書くように，四角形ABCDを ◻ABCD のように書きたいですが，四角形は正方形とは限らないので「◻」という正方形の記号を使うのはあまり実情を表した記号とはいえません．
正方形でも平行四辺形でも凧形でもない，一般の四角形を表すためにもっとぐちゃっとした形の四角形記号 <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121120/347fe61e-b630-7276-6b1b-66f6b3f9d6a3.png" alt="square symbol" width=30> を導入してみましょう．
（※なお，このような記号は[「ceo」パッケージに収録されています](http://honyajitsu.cocolog-nifty.com/blog/2022/04/post-af2eac.html#:~:text=%E5%8B%A7%E3%82%81%E3%81%97%E3%81%BE%E3%81%99%E3%80%82-,%E3%80%8Cceo%E3%80%8D%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8,-%E3%80%8Cceo%E3%80%8D%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%81%AF)が，別途定義されたフォントを読み込む方式のため，作るのも使うのも少々面倒なのでおいておくことにします．）

[^triangle]: ここの三角形も正三角形ではなく一般の三角形にしておきたいですね．

```tex
%%% preamble
\tikzsymbolsdefinesymbol{symbunmarkedsquare}{ S }{
    \begin{tikzpicture}[/tikzsymbolsstyle,x=1ex,y=1ex,scale=#1,line width=0.1ex]
        \draw(0,0)--(3,0)--(2.5,2)--(0.5,2.5)--cycle;
    \end{tikzpicture}
}
\newcommand{\unmarkedsquare}{\symbunmarkedsquare[0.65]}

%%% document
\show\triangle
\show\unmarkedsquare
\begin{gather*}
    \triangle{\text{ABC}}\\
    \square{\text{ABCD}}\\
    \unmarkedsquare{\text{ABCD}}
\end{gather*}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121120/6720013b-5fb6-5e24-22bc-4516f5bdf544.png)

図形を描画しているのは TikZ 環境の `\draw(0,0)--(3,0)--(2.5,2)--(0.5,2.5)--cycle;` の部分です．
XY座標の点(0,0)，(3,0)，(2.5,2)，(0.5,2.5)を順に繋いで始点に戻る線を引くという意味になります．
ここをいじれば色々と変えられます．

他の記号と比べてちょっと大きかったので `S` 引数を入れてサイズを変更するといった調整も簡単にできます．

## プレースホルダー記号

プレースホルダー記号を作ってみます．
数学でいうプレースホルダーというのは

> 損失関数は
>
> $$ J(\mathbf{w})=\\|\mathbf{X}\mathbf{w} - \mathbf{y}\\|^2 +\frac{\lambda}{2}\\|\mathbf{w}\\|^2$$
>
> である．ここで $\\|\cdot\\|$ はL2ノルムである．

といったときの「$\cdot$」のように関数の引数が入る場所を空けておく記号です．
具体的な変数を書いてしまうとその変数を入れたときの値と関数そのものの区別がつかないので，明示的に関数そのものを指したいときなどにこのような表記をすることがあります．
一般的に中黒かビュレットあたりが使われますが，積の記号などにも使うので若干紛らわしく，知らない人には伝わりにくかったりします[^place]．

[^place]: ちょくちょく[これはなんですか？という質問](https://jp.quora.com/A-sim-pi-cdot-S-theta-%E3%81%AE-%E3%81%AF%E3%81%A9%E3%81%AE%E3%82%88%E3%81%86%E3%81%AA%E6%84%8F%E5%91%B3%E3%81%A7%E3%81%99%E3%81%8B?no_redirect=1)を見かけます．

もっとここに何か入るんだよ感を出すために，PowerPoint の数式入力 UI を参考にしてみます．PowerPoint では数式の入力中，括弧のように中に記号を入れる際に下図のように点線のプレースホルダーが作られます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121120/ac47fdbc-55ba-5d71-53a3-3acabbd81c1a.png)

TikZ では簡単に点線を書けるのでこれで作図してみます．

```tex
% 点線□
\tikzsymbolsdefinesymbol{dotsquare}{
    S % scale
    B{1} % line width factor
    B{0ex} % descend depth
}{%
    \begin{tikzpicture}[/tikzsymbolsstyle,x=1ex,y=1ex,scale=#1,baseline=#3,line width=0.12ex*#2,transform shape,densely dotted]
        \draw(0,0)--(0,1)--(1,1)--(1,0)--cycle;
    \end{tikzpicture}%
}
% 点線◯
\tikzsymbolsdefinesymbol{dotcircle}{
    S % scale
    B{1} % line width factor
    B{0ex} % descend depth
}{%
    \begin{tikzpicture}[/tikzsymbolsstyle,x=1ex,y=1ex,scale=#1,baseline=#3,line width=0.12ex*#2,transform shape,densely dotted]
        \draw(0,0.5)circle(0.5);
    \end{tikzpicture}%
}
\newcommand{\placeholder}{\mathbin{\dotsquare[1.5][][0.15ex]}}
\newcommand{\dottedSquare}{\mathbin{\dotsquare[1.5][][-0.1ex]}}
\newcommand{\dottedCirc}{\mathbin{\dotcircle[0.8][][-0.2ex]}}
\newcommand{\dottedBigCirc}{\mathbin{\dotcircle[2][][0.45ex]}}

%%% domcument
{\tiny $ \norm{\placeholder} $ }
{\footnotesize $ \norm{\placeholder} $ }
{\normalsize $ \norm{\placeholder} $ }
{\Large $ \norm{\placeholder} $ }
{\huge $ \norm{\placeholder} $ }

\begin{gather*}
    \norm{A \circ B}\\
    \norm{A \dottedCirc B}\\
    \norm{A \bigcirc B}\\
    \norm{A \dottedBigCirc B}\\
    \norm{A \mathbin{\square}B}\\
    \norm{A \dottedSquare B}
\end{gather*}
```

フォントサイズ変更に追従します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121120/60d603bf-b5b8-1b9c-6556-44940e3b8022.png)
`\circ`, `\bigcirc`, `\square` に合わせた点線図形も作ってみました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121120/40d3401f-8f87-a371-0df2-950a16683328.png)

記号の位置を上下にずらす場合は`baseline`オプションを指定します（下向きが正）[^sq][^hoge]．

[^sq]: 括弧の中心あたりと`square`の上下位置って結構違うんですね．

[^hoge]: ところで`baseline`による高さ変更やフォントサイズ変更への対応は TikZ 側の機能です．xparseの機能も標準に入りましたし，オプション等々を自分で指定するなら tikzsymbols パッケージなしで TikZ だけ使っても同じことはできます．

なお，現状では数式中で添字になったときなどのサイズ変更に対応していないので $\int$ の方に乗せたりしても大きいままです．
`\mathchoice`などで別途処理する必要があります．