TeX Alchemist Online

TeX のこと,フォントのこと,Mac のこと

「たいてき」を読みに含む単語が文書内に存在すれば文書全体を太字にする

読みに〝たいてき〟を含む単語(相対的,大敵など)を文書のどこかに含むと文書全体が太字になるLaTeX文書」という,随分とマニアックなお題を見かけました。

というわけで,このお題の再現を目指して,やってみました。

準備:対象単語をリストアップする

辞書 by 物書堂日本国語大辞典などの国語辞典コンテンツを *たいてき* とワイルドカード検索することで,「読みに〝たいてき〟を含む単語」をリストアップします。

これを

\def\TAITEKI{たいてき,タイテキ,大敵,対敵,具体的,主体的,絶対的,全体的,相対的,肉体的,変態的,立体的,敵対的,実体的,総体的,交代的,後退的,生態的,静態的,有機体的}

と列挙して定義し,「文書内(\begin{document}\end{document})にこれらの単語を含んでいるかどうかを判定して,フォント設定を変更する,という方針で実装してみましょう。

TeX on LaTeX する

%!uplatex
\documentclass[dvipdfmx,autodetect-engine]{jsarticle}
\usepackage{xparse}
\usepackage{xstring}

\makeatletter
\def\TAITEKI{たいてき,タイテキ,大敵,対敵,具体的,主体的,絶対的,全体的,相対的,肉体的,変態的,立体的,敵対的,実体的,総体的,交代的,後退的,生態的,静態的,有機体的}

\NewDocumentEnvironment{checkTAITEKI}{+b}{%
  \edef\BODY{\detokenize{#1}}%
  \@for\@temp:=\TAITEKI\do{%
    \edef\@temp{\expandafter\detokenize\expandafter{\@temp}}%
    \IfSubStr{\BODY}{\@temp}{%
      \def\seriesdefault{bx}%
      \def\kanjiseriesdefault{bx}%
      \normalfont
    }{}%
  }%
  #1%
}{}
\AtBeginDocument{\begin{checkTAITEKI}}
\AtEndDocument{\end{checkTAITEKI}}
\makeatother

\begin{document}

このような\LaTeX 文書は変態的であると言えるでしょう。

Such a \LaTeX{} document can be considered abnormal.

\end{document}

この文書をコンパイルすると,和文・欧文とも太字になります。

もし本文に〝たいてき〟系単語を含まない場合,通常のフォントでの組版となります。

ポイント解説

xparse\NewDocumentEnvironment を使って環境の内容を取得する

LaTeX標準の \newenvironment ではなく,xparse パッケージが提供する \NewDocumentEnvironment を使うことで,「環境の内容全体」を取得することができます。

qiita.com

\NewDocumentEnvironment{body}{+b}{環境開始のコード}{環境終了のコード}

としておくことで,環境開始のコード環境終了のコード の中で #1 として環境の内容を取得できます。+b+ の部分は #1 として複数段落を許容する(\parを含められる)ことを意味します。今回は,これによって checkTAITEKI 環境を定義し,環境の内容を取得して,そこで〝たいてき〟系単語の存在チェックを行います。

\AtBeginDocument, \AtEndDocument\begin{document}, \end{document} をフックする

\AtBeginDocument{\begin{checkTAITEKI}}
\AtEndDocument{\end{checkTAITEKI}}

とすることで,\begin{document}\end{document} が自動的に \begin{document}\begin{checkTAITEKI}\end{checkTAITEKI}\end{document} 相当になるようにフックしておきます。こうすることで,ユーザーサイドとしてはいつも通り \begin{document}\end{document} 内に本文を書けば,自動的に checkTAITEKI 環境による〝たいてき〟系単語存在チェックの対象となります。

\detokenize で文字列化する

一般に,\begin{document}\end{document} の内容は,様々な命令を含み,単純な文字列ではありません。そのままでは部分文字列チェックが難しいので,\detokenize によってただの文字列(ただしカテゴリーコードは全部12(※空白文字は10)の \the-文字列)にしておきます。

xstring\IfSubStr の部分文字列チェックを行う

xstring パッケージが提供する \IfSubStr を使うことで,部分文字列チェックを行えます。ただし,文字列一致判定はカテゴリーコードの一致性も判定されるため,

\edef\@temp{\expandafter\detokenize\expandafter{\@temp}}

によって比較対象も \detokenize\the-文字列化しています。

存在した場合は bx を series のデフォルトにする

〝たいてき〟チェックが真であった場合は,

\def\seriesdefault{bx}% 欧文の series のデフォルト値
\def\kanjiseriesdefault{bx}% 和文の series のデフォルト値

によって series のデフォルトを変更し,\normalfont\selectfont を発動しています。