xfakebold.styの紹介

本稿は [TeX ＆ LaTeX Advent Calendar 2019](https://adventar.org/calendars/4087) の2日目の記事です.
1日目は @kakinaguru_zo さんによる「[LuaTeXでカラーフォント・絵文字✌(SVG/COLR/CBDT)](https://qiita.com/kakinaguru_zo/items/8a085484c7a0530e032b)」でした.
3日目はp_typoさんによる [TeXConf 2020](https://texconf2020.tumblr.com/post/189449023930/pre-announcement) です.

# xfakebold.sty とは?

xfakebold.sty ([CTAN](https://www.ctan.org/pkg/xfakebold)) とは, **pdfファイル上で擬似的に太字を実現する**コマンド `\setBold` を提供するパッケージで, **LuaLaTeX または pdfLaTeXのみで利用可能**です[^1].

[^1]: XeLaTeXでは fontspec.sty の FakeBold オプションを使えば良い, らしい.

`\setBold` コマンドを使うと, 以下のようになります[^2]:

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111178/8975f929-cf31-d6c4-69ee-024cd5197669.png" width="256px">　　<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111178/edb669b3-3bab-e70d-c9af-17ecf7ebc581.png" width="256px">




[^2]: フォントはメイリオと Segoe UI を用いています.

普通の文書での使い道はよくわかりませんが, bemaerで Computer Modern (などのセリフ系フォント) を使う場合に有効です.


実際, 自分がbeamerを使うときは `\usefonttheme{professionalfonts}` として数式だけ Computer Modern を使うので, xfakebold を重宝しています.
本稿では, beamer (またはスライド作成用クラスファイル) 上での利用を前提とした解説をします.

なお, 擬似的な太字はpdfのフォントのレンダリング方法を利用して実現しています. 詳しくはCTANにあるマニュアルを参照してください.


**追記**: @doraTeX さんが (u)pLaTeX への対応を考えてくださいました:
[xfakebold.sty を (u)pLaTeX + dvipdfmx に対応させてみた](https://doratex.hatenablog.jp/entry/20191206/1575571353)


# 使い方

## 個人的にオススメの使い方

とりあえず, プリアンブルに以下を書くと, 数式だけが自動的に太くなり, スライド上で数式が見やすくなります[^0].

[^0]: 個人の感想です.

```latex 
\usepackage[bold=0.2]{xfakebold} % bold の値はお好み. デフォルトは0.4
\everymath{\setBold\aftergroup\unsetBold}
\renewenvironment{equation}{\align}{\endalign}
\def\[#1\]{\begin{align*}#1\end{align*}}
\let\origtext\text
\renewcommand{\text}[1]{\origtext{\unsetBold\relax#1\setBold}}
```

4行目にヤバそうなものが見えますが, ともあれ, 以下で細かい部分を説明していきます.


## パッケージの読み込み

```latex
\usepackage{xfakebold}
```

とすればよいです. 

読み込み時のオプションとして, `bold` というパラメータを指定することができます (デフォルトは0.4).
このオプションは, 文字を何pt太くするか, を指定します.
例えば, 

```latex
\usepackage[bold=0.5]{xfakebold}
```

とすると, 通常より0.5pt太くなります.

boldの値を変えた際の違いは以下のようになります.

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111178/25d1de78-4932-463f-957c-9b472a4c6974.png" width="512px">


個人的には, 0.2か0.3あたりがちょうどよいかなあと思います.

## コマンド

`\setBold` と `\unsetBold` というコマンドが用意されています.

`\setBold` を使うと, それ以降のテキストが (数式だろうが何だろうが全て) 太くなります. `\unsetBold` を用いれば, それ以降のテキストが普通の太さで表示されます.

```latex
あいうえお \setBold あいうえお \unsetBold あいうえお
```

出力: 

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111178/56bb5625-f3fe-8141-605e-9b442d73b03d.png" width="512px">


用意されているコマンドはこの2つだけです[^3].

[^3]: 実は `\fake@bold` というコマンドもあり, オプション `bold` の値はこのコマンドに取り込まれます. したがって, `\fake@bold` を途中で `\renewcommand` すると, 途中で太さを変えることができます. 


パッケージの使い方自体はこれだけですが, 以下, 個人的な好みで色々と変更する, という話が続きます.

# 数式だけに \setBold する

上の使い方を見ればわかるように, `\setBold` の後ろは全てが太くなってしまいます.
そのため, フォント次第ではかえって読みにくくなってしまいます. 
個人的には, beamerでの利用を考えると, 数式だけ太くしてくれればいいのに, と思います. 
そこで, 数式のときだけ自動的に `\setBold` する方法を考えます.

## インライン数式の場合

インライン数式で自動的に `\setBold` するには, プリアンブルに以下のように記述すると良いです.

```latex
\everymath{\setBold\aftergroup\unsetBold}
```

## 別行立て数式の場合

別行立て数式でも自動的に `\setBold` する場合, `\everydisplay` というコマンドの利用が考えられますが, これを用いると, amsmath.sty の `align` 環境などと衝突します.

実は, amsmath.sty を読み込んでいる場合は, 上の `\everymath` による記述によって, `align` 環境なども自動的に `\setBold` されます. 

ということは, `\[ ... \]` による記述と `equation`・`equaiton*` 環境の3つだけ対処すれば良いのですが, うまい方法が思いつかなかったので, 思い切って, **これらの環境を align 環境に置き換える**ことで対応することにします[^a].

[^a]: 紹介する方法が良い方法とは思っていませんが, とりあえず動くので... より良い方法があれば教えて下さい.

まず, `equation` 環境は, 以下のようにすると書き換えられます[^eq]. 

[^eq]: 自分はスライドで相互参照を使わないので, 自分のスライドにはこの記述はしないのですが.

```latex
\renewenvironment{equation}{\align}{\endalign}
```

cf. [newenvironment: error with \\begin{align} and \\end{align}](https://tex.stackexchange.com/questions/236664/newenvironment-error-with-beginalign-and-endalign)


`equation*` 環境は使われることはないと思うので放置します. 
`\[ ... \]` は以下のように書き換えます.

```latex
\def\[#1\]{\begin{align*}#1\end{align*}}
```

cf. [Redefining \\\[ to \\begin{align*}](https://latex.org/forum/viewtopic.php?t=2918#)

本当にこんなことしていいのか? って感じがしますが, 動くので, これで良いということにします.


## `\text` コマンド内の文字列

上のように対処すると, `\text` コマンドの中でも `\setBold` が有効になってしまうため, このコマンドを使う場合は, 少し見栄えがよくありません.

```latex
% プリアンブル
\everymath{\setBold\aftergroup\unsetBold}
\renewenvironment{equation}{\align}{\endalign}
\def\[#1\]{\begin{align*}#1\end{align*}}

% 本文
Poisson方程式
\[
    \begin{cases}
        -\Delta u = f & \text{in } \Omega, \\
        u = 0         & \text{on } \partial\Omega
    \end{cases}
\]
を考える.
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111178/c2bf1228-991e-795c-f9cb-d452699e6af6.png" width="256px">

上の出力を見ると, `\text` コマンド内の in と on が太くなってしまっています.
これを回避するためには, `\text{\unsetBold ... \setBold}` という感じで `\unsetBold` と `\setBold` を入れてあげればよいですが, 毎回入れるのは面倒です.
そこで, 以下のように `\text` コマンドを再定義しちゃいましょう[^5].

[^5]: 実は, この状態で `\text` コマンド内に数式を書くと, なぜか数式が太くなりません. この問題を回避するためには, `\renewcommand` の部分は `\renewcommand{\text}[1]{\origtext{\everymath{\setBold\aftergroup\unsetBold}\unsetBold\relax#1\setBold}}` としないといけません. が, `\text` コマンド内で数式を使うことはあまりないと思うので, 適宜 `\setbold` を書くというのでも良いと思います. と言いつつ自分はこの長い `\renewcommand` を使っています. これ, どうにかならないのでしょうか.


```latex 
% プリアンブル
\everymath{\setBold\aftergroup\unsetBold}
\renewenvironment{equation}{\align}{\endalign}
\def\[#1\]{\begin{align*}#1\end{align*}}
% \text コマンドを再定義
\let\origtext\text
\renewcommand{\text}[1]{\origtext{\unsetBold\relax#1\setBold}}

% 本文
Poisson方程式
\[
    \begin{cases}
        -\Delta u = f & \text{in } \Omega, \\
        u = 0         & \text{on } \partial\Omega
    \end{cases}
\]
を考える.
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111178/8bdbe58b-3f72-a3e3-7fc8-1e3b751c2920.png" width="256px">


並べてみるとだいぶ違います.

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111178/c2bf1228-991e-795c-f9cb-d452699e6af6.png" width="256px">　　<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111178/8bdbe58b-3f72-a3e3-7fc8-1e3b751c2920.png" width="256px">


まとめると, 以下のように使うのが個人的なオススメです[^4].

[^4]: もちろん (?), amsmath パッケージは読み込まれているものとします.


```latex:再掲
\usepackage[bold=0.2]{xfakebold} % bold の値はお好み. デフォルトは0.4
\everymath{\setBold\aftergroup\unsetBold}
\renewenvironment{equation}{\align}{\endalign}
\def\[#1\]{\begin{align*}#1\end{align*}}
\let\origtext\text
\renewcommand{\text}[1]{\origtext{\unsetBold\relax#1\setBold}}
```


# フォントサイズに応じて相対的に太さを変える

xfakebold.sty は, ポイントでどれだけ太くするかを指定します. 
したがって, 文字サイズが変更されると, 太くなる割合も変化してしまいます.
そこで, LuaLaTeX 限定ですが, xfakebold を読み込む代わりに, 以下のようにすれば, 相対的に余分な太さを指定することができます.


```latex:プリアンブル
\usepackage{ifthen}

\makeatletter
\newcommand{\r@tio}{2}
\newcommand{\setBold}{%
    \ifthenelse{\equal{\f@series}{bx}}{%
        \renewcommand{\r@tio}{5}%
    }{%
        \renewcommand{\r@tio}{2}%
    }%
    \pdfextension literal direct { 2 Tr \directlua{tex.print(0.01*\r@tio*\f@size)} w }\relax
}
\newcommand{\unsetBold}{\pdfextension literal direct { 2 Tr 0 w }\relax}
\makeatother
```

`\r@tio` はフォントサイズに対する太くなる割合 (パーセント) を意味しています.
`\f@series` は現在のフォントシリーズ (太字とか) を, `\f@size` は現在のフォントサイズを返します.
なお, ifthen パッケージを使わなくても同じことができると思いますが, 使った方が楽だと思います.


他にも, `\pdfextension literal direct { 2 Tr 数字 w }` という表現を駆使すれば, 自分だけの fakebold を作ることができます[^fb].

[^fb]: 実は, xfakebold.sty の中身は, 本質的にはこれだけです.


# 終わりに

LuaLaTeX または pdfLaTeX で擬似的な太字を実現する xfakebold というパッケージを紹介しました.
主な用途はbeamerで文字を太して読みやすくすることだと思います.
他に有効な使い道があったら教えてください.


## 宣伝

- [amsmathの数式環境まとめ](https://qiita.com/t_kemmochi/items/a4c390b4967b13f3afb7)
- [FreeFem++の紹介](https://qiita.com/t_kemmochi/items/418bdc55e4937381711e)


# 付録: \varepsilon が汚い 

汚い[^eps]. 

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111178/7fd7721b-9b55-4338-681a-9633c2a40b00.png" width="512px">

お分かり頂けただろうか.

[^eps]: モニターやソフトウェアに依存する現象かも?