アレForumのアレな話
dvipdfmxがアレらしい。
Each
\color
command executes\special {color push \current@color }\aftergroup \reset@color
but the
push
is never followed by apop
(except at the end of the job).The color stack apparently has a limitation of 127 or 128 positions (you get red, I get blue, so it can be off by one depending on the version of the software).
ただし、このTeX Forumの問題のように「トップレベルで\color
を大量に使うと失敗する」ことについては割と簡単に対処できそうである。
トップレベルではそもそも\aftergroup
で挿入したトークンは実行されないので、\reset@color
は元々一度も実行されていないはずである。だから色スタックに関するトップレベルでの整合性は元々要求されていないことになる。となると、次の動作をすればよい。
- まず最初に初期色をスタックに積んでおく。*1
- トップレベルで
\set@color
が実行された場合は本来の動作の代わりに「色スタックをpop →\current@color
をpush」をする(トップレベルなので\aftergroup
はそもそも無意味)。これでスタックの深さは変わらなくなる。
イマドキのTeXエンジンであればe-TeX拡張の\currentgrouplevel
が使えるので「いまトップレベルにいるか」が判定できる。
やってみた
というわけで、なんとかしてみた。
- LaTeX: Hack for top-level color changes with dvipdfmx(Gist/zr-tex8r)
あとは適当な例で試すだけだが、折角なんとかしたのだからナントカすることにする。
% upLaTeX + dvipdfmx (essential) \documentclass[dvipdfmx]{jsarticle} \usepackage{xcolor} \colorlet{R}{red}\colorlet{B}{blue}\colorlet{G}{green!50!black} \usepackage{bxdpx-tchack} \newcommand*\cS[1]{\color{#1}☃\color{black}} \newcommand*\cNice[7]{% \cS{#1}っ\cS{#2}\cS{#3}\cS{#4}っ\cS{#5}っ \cS{#6}っっ♪\cS{#7}っっ♪} \newcommand*\cNicePar{% \cNice{R}{B}{R}{G}{B}{R}{R} \cNice{B}{B}{G}{R}{G}{B}{B}\par \cNice{G}{R}{R}{R}{B}{G}{G} \cNice{R}{G}{R}{B}{G}{R}{R}\par} \begin{document} \cNicePar \cNicePar \cNicePar \cNicePar \cNicePar \end{document}
まとめ
色とりどりのナントカはトッテモ素敵😊😊😊