Closed aminophen closed 7 years ago
非常に素朴ですが,ひとまず \@setref
を次のように定義し直すと(\relax
の後ろに {}
を入れただけです)上のケースでは期待通りの出力をするようになりました:
\def\@setref#1#2#3{%
\ifx#1\relax
\protect\G@refundefinedtrue
\nfss@text{\reset@font\bfseries ??}%
\@latex@warning{Reference `#3' on page \thepage \space
undefined}%
\else
\expandafter#2#1\relax{}% change \null to \relax{}
\fi}
ただし副作用がないかは大変怖いところです.
ありがとうございます。私は texjporg/jsclasses#8 からの類推ですが、同じことを思っていました。
とりあえずテスト版ということで exppl2e.sty に入れるというのはどうでしょう?
aebcbb2 で exppl2e.sty に @wtsnjp さんのコードを入れ、tests/setref.tex を追加しました。
GitHub では日本語が文字化けしていて見づらいですが、追加した説明文は
% \changes{v????}{????/??/??}{目次で\cs{ref}を使った場合に後ろの空白が消える
% 現象に対処するため、\cs{relax}のあとに\{\}を追加}
% しかし、単に|\null|を|\relax|に置き換えるだけでは、|\section|のような
% 「動く引数」で|\ref|などを使った場合に、目次で後ろの空白が消えてしまいます。
% そこで、|\relax|のあとに|{}|を追加しました。
と書いています。
本家 LaTeX の場合は \null
→ \hbox {}
に展開されて aux や toc に書かれるわけですから、今回の変更により \relax {}
が書き出されるのは特に問題ないのではないかと思います。
\documentclass{jsarticle}
\makeatletter
\renewcommand{\thesection}{\kansuji\c@section}
\makeatother
\begin{document}
\tableofcontents
\section{ほげ}\label{sec:hoge}
\section{第\ref{sec:hoge}節へのアンチテーゼふが}
\end{document}
のようなときにうまくいくでしょうか?(横書きだと稀かもしれませんが,縦書きもありますので.)
aux/toc 内で 第一\relax {}節
となるので、挙動としては問題ないはずです。確かにテストファイルにも追加した方が安心しますね。(jsarticle は \kanjiskip を \section のようなフォントサイズ変更に連動させて切り替えてしまうので、\kanjiskip20pt のような可視化がキャンセルされて見づらく、jarticle でテストケースにしておきます。)
いわゆる「緑」の本 (p.169) の「\@setref
と目次・スペースファクター」というコラムに
オリジナルの定義では,"see Appendix A." のような記述が文末にあり,かつ,"Appendix A" の "A" を相互参照で取得した場合などにスペースファクターを補正する目的で
\null
(=\hbox{}
) を用いています. (…中略…) そこで,\@setref
の(オリジナルの定義の) "\expandafter#2#1\null
" の部分のnull
を "\spacefactor\@m{}
" に変更するのもよいでしょう.こうすると,"スペースファクター","和欧文間スペース","toc ファイルなどでの参照結果の直後の空白文字" の全てが正しく処理されます.
とあります。2003 年の本書で既に,pLaTeX による \@setref
の目次での不具合だけでなく,スペースファクターの未考慮についても指摘があります。前回入れた \relax
→ \relax{}
についても,やはりスペースファクター未考慮です(以下のソースで確認できます)。
\makeatletter
%% LaTeX
\def\@setref#1#2#3{%
\ifx#1\relax
\protect\G@refundefinedtrue
\nfss@text{\reset@font\bfseries ??}%
\@latex@warning{Reference `#3' on page \thepage \space
undefined}%
\else
\expandafter#2#1\null
\fi}
%% pLaTeX (old)
\def\@setref#1#2#3{%
\ifx#1\relax
\protect\G@refundefinedtrue
\nfss@text{\reset@font\bfseries ??}%
\@latex@warning{Reference `#3' on page \thepage \space
undefined}%
\else
\expandafter#2#1\relax% change \null to \relax
\fi}
%% pLaTeX (2017/04/08)
\def\@setref#1#2#3{%
\ifx#1\relax
\protect\G@refundefinedtrue
\nfss@text{\reset@font\bfseries ??}%
\@latex@warning{Reference `#3' on page \thepage \space
undefined}%
\else
\expandafter#2#1\relax{}% change \null to \relax{}
\fi}
%% "Green book"
%\def\@setref#1#2#3{%
% \ifx#1\relax
% \protect\G@refundefinedtrue
% \nfss@text{\reset@font\bfseries ??}%
% \@latex@warning{Reference `#3' on page \thepage \space
% undefined}%
% \else
% \expandafter#2#1\spacefactor\@m{}% change \null to \spacefactor\@m{}
% \fi}
\makeatother
\documentclass{article}
\parindent0pt
\ifx\xkanjiskip\undefined\else\xkanjiskip20pt\fi
\begin{document}
\tableofcontents
% cf. 1) wrong spacing (inter-word)
\section{See Appendix A. Here,}\label{test1}
% cf. 2) correct spacing (sentence-ending)
\section{See Appendix A\@. Here,}
% test for \spacefactor (should be sentence-ending)
\section{See Appendix \ref{testA}. Here,}
% cf. 1) wrong spacing (inter-word)
See Appendix A. Here,\par
% cf. 2) correct spacing (sentence-ending)
See Appendix A\@. Here,\par
% test for \spacefactor (should be sentence-ending)
See Appendix \ref{testA}. Here,\par
\appendix
% test for \xkanjiskip
\section{ここは第\ref{testA}章です。}\label{testA}
% test for trailing space in \tableofcontents
\section{Here is the section \ref{test1} for testing.}
\end{document}
次の版では,この「緑」の指摘をそのまま取り込むことを検討中です。
a06e767 でカーネルへ。
Twitter で拾いました。→ https://twitter.com/aminophen/status/823578764994936834
これは latex では問題なく処理できますが、platex では目次の \ref (今回は 1)の後に toc で \relax が吐かれてしまうために、空白が喰われてしまいます。plcore の
\@setref
が xkanjiskip 対策で \null を \relax に変えていることが原因なので、これは pLaTeX の issue のようです。