フォントサイズ変更時の記号類と句読点の間の空白について

フォントサイズ変更時の記号類と句読点の間の空白について

- M. Imura の投稿
返信数: 11
初めまして。

LaTeX文書を作成する際に、本文中に小さくカッコ書きをすることがあります。この場合に、閉括弧の直後に句読点が入ると、その間が詰められずに空白ができてしまいます。

サンプルのように\inhibitglueを入れれば見た目は対処可能ですが、もう少しスマートな解法はないものかと思い、質問する次第です。

\documentclass[uplatex]{jsarticle}
\begin{document}
これはテストです(閉括弧と句読点の空き)。

これはテストです{\small (閉括弧と句読点の空き)}。

これはテストです{\small (閉括弧と句読点の空き)\inhibitglue}。

\end{document}

よろしくお願いします。
M. Imura への返信

Re: フォントサイズ変更時の記号類と句読点の間の空白について

- 本田 知亮 の投稿
クイックハックですが,
こんな感じでしょうか.

\futurelet が本質的です.

\documentclass{jsarticle}
\begin{document}

\makeatletter

\def\mysmall#1{%
\def\temp@arg{#1}%
\futurelet\@next\@mysmall
}

\def\@mysmall{%
\let\inhibitglue@or@empty\@empty
\if\@next。\let\inhibitglue@or@empty\inhibitglue\fi
\if\@next.\let\inhibitglue@or@empty\inhibitglue\fi
\if\@next,\let\inhibitglue@or@empty\inhibitglue\fi
\if\@next、\let\inhibitglue@or@empty\inhibitglue\fi
{\small\temp@arg\inhibitglue@or@empty}%
}

\makeatother

あああ(いいい)。

あああ{\small(いいい)}。


あああ\mysmall{(いいい)}。


\end{document}


===
なんかこの手の話題が以前にあったような記憶があるのですが,
\lastnodecharの話だったかな~
それなら,後ろじゃなくて前の話だから違うけど.
c.f. https://ja.osdn.net/projects/eptex/wiki/lastnodechar

M. Imura への返信

Re: フォントサイズ変更時の記号類と句読点の間の空白について

- 帯田 木偶太 の投稿
本田知亮さんのと多分、同工異曲だと思いますが、
対象にする句読点類をカスタマイズしやすいようにしてみました。


\documentclass{jarticle}\relax

\makeatletter
\def\smallnote#1{%
    \def\smallnote@content{#1}%
    \futurelet\smallnote@next\smallnote@
}
\def\smallnote@{%
    \smallnote@switch
    \if@tempswa
        \let\smallnote@after=\inhibitglue
    \else
        \let\smallnote@after=\@empty
    \fi
    {\small (\smallnote@content)%
        \smallnote@after
    }%
}
\def\smallnote@punct{。、.,([「}% <-- 対象とする句読点類を書き並べる
\def\smallnote@switch{%
    \@tempswafalse
    \expandafter\@tfor\expandafter\reserved@a\expandafter:\expandafter=\smallnote@punct\do{%
        \if \reserved@a \smallnote@next
            \@tempswatrue
        \fi
    }%
}
\makeatother

\begin{document}

あいう\smallnote{注}えお

あいう\smallnote{注}。

\end{document}

帯田 木偶太 への返信

Re: フォントサイズ変更時の記号類と句読点の間の空白について

- M. Imura の投稿
早速のお返事ありがとうございました。

お二方のマクロをそれぞれ試してみました。

本田知亮さんのマクロを試したところ、figure環境や
table環境などを使用していると以下のエラーが
出るようです。

! Undefined control sequence.
\@xfloat ...oatpenalty \z@ \else \@next \@currbox
                                                  \@freelist {\@tempcnta \si...

また、これは使い方が悪いのだと思いますが、
\textsf{ほげほげ\mysmall{(カッコ)}}。のような
使い方をすると、添付の画像1のようになってしまい
ます。ただ、\textbfだと問題ないようです。

それから、リスト環境で最後のアイテムに句読点なしで使うと
以下のエラーが出ます。また、リストの途中で句読点なしで使うと
添付の画像2のようになってしまいます。

\begin{itemize}
  \item ほげほげ\mysmall{(カッコ1)}
  \item ホゲホゲ\mysmall{(カッコ2)}
\end{itemize}

! Use of \@item doesn't match its definition.
\@checkend #1->\def \reserved@a {
                                #1}\ifx \reserved@a \@currenvir \else \@bad...


また、帯田木偶太さんのマクロは、やはりリスト環境の
最後のアイテムのに句読点なしで使うとエラーが出ています。
ただ、こちらの方ではリストの途中では句読点なしでも
問題ないようです。

\begin{itemize}
  \item ほげほげ\smallnote{(カッコ1)}
  \item ほげほげ\smallnote{(カッコ2)}
\end{itemize}

! Missing \endcsname inserted.
<to be read again>
                  \let

せっかく作っていただいたのに文句ばかりで恐縮ですが、よろしくお願いします。

添付 sample.png
M. Imura への返信

Re: フォントサイズ変更時の記号類と句読点の間の空白について

- 帯田 木偶太 の投稿
》 また、帯田木偶太さんのマクロは、やはりリスト環境の
》 最後のアイテムのに句読点なしで使うとエラーが出ています。

たしかにエラーになりますね。でも、なぜエラーになるのか、理解できない… orz

ただ、\smallnote@ の定義を
    \def\smallnote@{%
        \ifx \smallnote@next \end
            {\small (\smallnote@content)}%
        \else
            \smallnote@switch
            \if@tempswa
                \let\smallnote@after=\inhibitglue
            \else
                \let\smallnote@after=\@empty
            \fi
            {\small (\smallnote@content)%
                \smallnote@after\relax
            }%
        \fi
    }

に変えると、とりあえず回避できるようです。でも、なぜ回避できちゃうのか
理解できない… orz

ちなみに、私のマクロでは、中を囲む丸括弧は、マクロ自身で出力しますので、
通常であれば(閉じ丸括弧を二重にするのでなければ)、
\smallnote{(カッコ1)} ではなく \smallnote{カッコ1} のように使います。
そして、そのようにすれば、ご指摘のエラーは出ないようです。
でも、なぜ出なくなるのか理解できない… orz

Please tell me why.  PLEASE!
帯田 木偶太 への返信

Re: フォントサイズ変更時の記号類と句読点の間の空白について

- tat tsan の投稿
帯田木偶太さんの最初のマクロで、\smallnote@switch の定義の if テストを
\if \reserved@a \smallnote@next
から
\if \reserved@a \noexpand \smallnote@next
にするとエラーはなくなりました。
tat tsan への返信

Re: フォントサイズ変更時の記号類と句読点の間の空白について

- 帯田 木偶太 の投稿
ご指摘ありがとうございます。

\if は、展開不可能なものが 2 個得られるまで、後続のトークンを
展開するんでしたね。すっかり忘れてました。何ともお恥ずかしい限り。

ということで、次のようになりますね。

\documentclass{jarticle}\relax

\makeatletter
\def\smallnote#1{%
    \def\smallnote@content{#1}%
    \futurelet\smallnote@next\smallnote@
}
\def\smallnote@{%
        \smallnote@switch
        \if@tempswa
            \let\smallnote@after=\inhibitglue
        \else
            \let\smallnote@after=\@empty
        \fi
        {\small (\smallnote@content)%
            \smallnote@after\relax
        }%
}
\def\smallnote@punct{。、.,([「}% <-- 対象とする句読点類を書き並べる
\def\smallnote@switch{%
    \@tempswafalse
    \expandafter\@tfor\expandafter\reserved@a\expandafter:\expandafter=\smallnote@punct\do{%
        \if \reserved@a \noexpand\smallnote@next
            \@tempswatrue
        \fi
    }%
}
\makeatother

\begin{document}

あいう\smallnote{注}えお

あいう\smallnote{注}。


\begin{itemize}
  \item ほげほげ\smallnote{カッコ1}
  \item ほげほげ\smallnote{(カッコ2)}
\end{itemize}

\end{document}
M. Imura への返信

Re: フォントサイズ変更時の記号類と句読点の間の空白について

- tat tsan の投稿
本多さんのマクロを改変してみました。
(1) 本体を robust にする。(← figure 環境対策)
(2) if テストに \noexpand をつける。

\makeatletter
\DeclareRobustCommand\mysmall[1]{%
\def\temp@arg{#1}%
\futurelet\@next\@mysmall
}
\def\@mysmall{%
\let\inhibitglue@or@empty\@empty
\if\noexpand\@next。\let\inhibitglue@or@empty\inhibitglue\fi
\if\noexpand\@next.\let\inhibitglue@or@empty\inhibitglue\fi
\if\noexpand\@next,\let\inhibitglue@or@empty\inhibitglue\fi
\if\noexpand\@next、\let\inhibitglue@or@empty\inhibitglue\fi
{\small\temp@arg\inhibitglue@or@empty}%
}
\makeatother

tat tsan への返信

Re: フォントサイズ変更時の記号類と句読点の間の空白について

- tat tsan の投稿
https://oku.edu.mie-u.ac.jp/~okumura/texfaq/qa/54425.html
のような例もあるので、\inhibitglue よりも \unskip の方が良いようです。

\textbf{} などの既存のマクロでも同様なアキが入るので、\DeclareTextFontCommand にも手を入れたく
なりますね。ただ「\texthoge{}の後に来るもの」が多種多様で、いくらでも想定外のものが出てきそうです。
tat tsan への返信

Re: フォントサイズ変更時の記号類と句読点の間の空白について

- tat tsan の投稿
本田さんもお書きになっているように \lastnodechar が新設された頃にこの種の処理をする
パッケージがあったなあと思って調べてみたら 2017年に fixjfm.sty というのが出ていましたね。
jsclasses にも「fixjfm パッケージによる修正の有無をチェックする」コードが入っていました。

%%%%%%%%%%%%%%%%%%
\ifx\DeclareFixJFMCJKTextFontCommand\@undefined
\DeclareRobustCommand\textmc[1]{%
    \relax\ifmmode \expandafter\nfss@text \fi{\mcfamily #1}}
\DeclareRobustCommand\textgt[1]{%
    \relax\ifmmode \expandafter\nfss@text \fi{\gtfamily #1}}
\fi
%%%%%%%%%%%%%%%%%%

しかし次の記述だけでもエラーが出るので、どうも \DeclareFixJFMCJKTextFontCommand には
問題があるようです。これは別の所に issue を立てるべきでしょうね。

%%%%%%%%%%%%%%%%%%
\RequirePackage{fixjfm}
\documentclass{jsarticle}
\begin{document}
\textgt{あ}
\begin{itemize}
\item a
\end{itemize}
\end{document}
%%%%%%%%%%%%%%%%%%

ここでは fixjfm パッケージの提供する \fixjfmspacing だけを拝借し、\DeclareTextFontCommand
の日本語対応をやりなおしてみました。これで \textgt{(ほげ)}\jsmall{(ほげ)} のように書体
変更が連続してもうまく行くようです。\fixjfmspacing だけだと \footnote{} で生じるアキに対応
できなかったので、本田さんのコードも混ぜました。

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\RequirePackage{fixjfm}
\documentclass[uplatex]{jsarticle}
\makeatletter
\def\DeclareTextFontCommandJPii #1#2{%
  \@namedef{@\expandafter\@gobble\string#1}{%
    \let\inhibitglue@or@empty\@empty
    \ifx \temp@next \inhibitglue \let\inhibitglue@or@empty\unskip\fi
    \ifx \temp@next \unskip \let\inhibitglue@or@empty\unskip\fi
    \relax
    \ifmmode \expandafter\nfss@text \fi
    {#2\fixjfmspacing\temp@arg}\inhibitglue@or@empty\fixjfmspacing}%
  \DeclareRobustCommand#1[1]{%
  \def\temp@arg{##1}%
  \expandafter\expandafter\expandafter\futurelet\expandafter\expandafter\expandafter\temp@next\expandafter\csname @\expandafter\expandafter\expandafter\@gobble\expandafter\string\expandafter #1\expandafter\endcsname\romannumeral-`\Q
  }%
}
\makeatother

\DeclareTextFontCommandJPii{\jsmall}{\small}
\DeclareTextFontCommandJPii{\textgt}{\gtfamily}
% \DeclareFixJFMCJKTextFontCommand{\jsmall}{\small}%% これだとエラーが出る。
% \DeclareFixJFMCJKTextFontCommand{\textgt}{\gtfamily}%% これだとエラーが出る。

\begin{document}
\def\macrotest#1{#1}
\def\macrotesti#1{{(カッコ)}}
\def\macrotestii#1{\iftrue {#1}\fi}

\begin{itemize}
\item ほげほげ(カッコ)
\item ほげほげ\jsmall{(カッコ)}
\item ほげほげ\jsmall{\macrotest{(カッコ)}}
\item ほげほげ\jsmall{\macrotesti{(カッコ)}}
\item ほげほげ\jsmall{\macrotestii{(カッコ)}}
\end{itemize}

\begin{itemize}
\item ほげほげ(カッコ)。
\item ほげほげ\jsmall{(カッコ)}。
\item ほげほげ\jsmall{\macrotest{(カッコ)}}。
\item ほげほげ\jsmall{\macrotesti{(カッコ)}}。
\item ほげほげ\jsmall{\macrotestii{(カッコ)}}。
\end{itemize}

\begin{itemize}
\item ほげほげ(カッコ)\footnote{ほげ}
\item ほげほげ\jsmall{(カッコ)}\footnote{ほげ}
\item ほげほげ\jsmall{\macrotest{(カッコ)}}\footnote{ほげ}
\item ほげほげ\jsmall{\macrotesti{(カッコ)}}\footnote{ほげ}
\item ほげほげ\jsmall{\macrotestii{(カッコ)}}\footnote{ほげ}
\end{itemize}

\begin{itemize}
\item ほげほげ(カッコ)(かっこ)。
\item ほげほげ(カッコ)\textgt{(かっこ)}。
\item ほげほげ\jsmall{(カッコ)}\textgt{(かっこ)}。
\item ほげほげ\jsmall{\macrotest{(カッコ)}}\textgt{(かっこ)}。
\item ほげほげ\jsmall{\macrotesti{(カッコ)}}\textgt{(かっこ)}。
\item ほげほげ\jsmall{\macrotestii{(カッコ)}}\textgt{(かっこ)}。
\end{itemize}

\begin{itemize}
\item ほげほげ(カッコ)文字
\item ほげほげ(カッコ)\textgt{文字}
\item ほげほげ\jsmall{(カッコ)}\textgt{文字}
\item ほげほげ\jsmall{\macrotest{(カッコ)}}\textgt{文字}
\item ほげほげ\jsmall{\macrotesti{(カッコ)}}\textgt{文字}
\item ほげほげ\jsmall{\macrotestii{(カッコ)}}\textgt{文字}
\end{itemize}

\end{document}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
tat tsan への返信

Re: フォントサイズ変更時の記号類と句読点の間の空白について

- tat tsan の投稿

fixjfm.sty でエラーが出る問題は \fixjfmspacing 自体にありました。
プルリクエストを出しておきました。

このパッチを当てた fixjfm パッケージを使えば、このスレの問題は解決します。
ただし \textgt{(猫)}\footnote{cat} には相変らずアキが入ります。
\textgt{(猫)\footnote{cat}} で回避できますが。