「読みに〝たいてき〟を含む単語(相対的,大敵など)を文書のどこかに含むと文書全体が太字になるLaTeX文書」という,随分とマニアックなお題を見かけました。
Latexにて「たいてき」読みを含む単語(「相対的」とか「大敵」とか)を任意の場所に書くと、文章全体が太字になるというまじで訳分からん現象に遭遇()
— あくあ@プログラミング (@aqua_prgrmmng) 2023年7月2日
というわけで,このお題の再現を目指して,やってみました。
準備:対象単語をリストアップする
辞書 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
を使うことで,「環境の内容全体」を取得することができます。
\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
を発動しています。