New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

目次の中の \ref で後ろの空白が喰われる + スペースファクター #31

Closed
aminophen opened this Issue Jan 23, 2017 · 7 comments

Comments

Projects
None yet
3 participants
@aminophen
Member

aminophen commented Jan 23, 2017

Twitter で拾いました。→ https://twitter.com/aminophen/status/823578764994936834

\documentclass{article}
\begin{document}
\tableofcontents
\section{Something}\label{a}
\section{Sec. \ref{a} is empty}
\end{document}

これは latex では問題なく処理できますが、platex では目次の \ref (今回は 1)の後に toc で \relax が吐かれてしまうために、空白が喰われてしまいます。plcore の \@setref が xkanjiskip 対策で \null を \relax に変えていることが原因なので、これは pLaTeX の issue のようです。

@wtsnjp

This comment has been minimized.

Show comment
Hide comment
@wtsnjp

wtsnjp Jan 24, 2017

非常に素朴ですが,ひとまず \@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}

ただし副作用がないかは大変怖いところです.

wtsnjp commented Jan 24, 2017

非常に素朴ですが,ひとまず \@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}

ただし副作用がないかは大変怖いところです.

@aminophen

This comment has been minimized.

Show comment
Hide comment
@aminophen

aminophen Jan 24, 2017

Member

ありがとうございます。私は texjporg/jsclasses#8 からの類推ですが、同じことを思っていました。

とりあえずテスト版ということで exppl2e.sty に入れるというのはどうでしょう?

Member

aminophen commented Jan 24, 2017

ありがとうございます。私は texjporg/jsclasses#8 からの類推ですが、同じことを思っていました。

とりあえずテスト版ということで exppl2e.sty に入れるというのはどうでしょう?

@aminophen

This comment has been minimized.

Show comment
Hide comment
@aminophen

aminophen Jan 24, 2017

Member

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 {} が書き出されるのは特に問題ないのではないかと思います。

Member

aminophen commented Jan 24, 2017

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 {} が書き出されるのは特に問題ないのではないかと思います。

@kuroky49

This comment has been minimized.

Show comment
Hide comment
@kuroky49

kuroky49 Jan 24, 2017

\documentclass{jsarticle}
\makeatletter
\renewcommand{\thesection}{\kansuji\c@section}
\makeatother

\begin{document}
\tableofcontents

\section{ほげ}\label{sec:hoge}
\section{第\ref{sec:hoge}節へのアンチテーゼふが}
\end{document}

のようなときにうまくいくでしょうか?(横書きだと稀かもしれませんが,縦書きもありますので.)

kuroky49 commented Jan 24, 2017

\documentclass{jsarticle}
\makeatletter
\renewcommand{\thesection}{\kansuji\c@section}
\makeatother

\begin{document}
\tableofcontents

\section{ほげ}\label{sec:hoge}
\section{第\ref{sec:hoge}節へのアンチテーゼふが}
\end{document}

のようなときにうまくいくでしょうか?(横書きだと稀かもしれませんが,縦書きもありますので.)

@aminophen

This comment has been minimized.

Show comment
Hide comment
@aminophen

aminophen Jan 24, 2017

Member

aux/toc 内で 第一\relax {}節 となるので、挙動としては問題ないはずです。確かにテストファイルにも追加した方が安心しますね。(jsarticle は \kanjiskip を \section のようなフォントサイズ変更に連動させて切り替えてしまうので、\kanjiskip20pt のような可視化がキャンセルされて見づらく、jarticle でテストケースにしておきます。)

Member

aminophen commented Jan 24, 2017

aux/toc 内で 第一\relax {}節 となるので、挙動としては問題ないはずです。確かにテストファイルにも追加した方が安心しますね。(jsarticle は \kanjiskip を \section のようなフォントサイズ変更に連動させて切り替えてしまうので、\kanjiskip20pt のような可視化がキャンセルされて見づらく、jarticle でテストケースにしておきます。)

@aminophen

This comment has been minimized.

Show comment
Hide comment
@aminophen

aminophen Aug 10, 2017

Member

いわゆる「緑」の本 (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}

次の版では,この「緑」の指摘をそのまま取り込むことを検討中です。

Member

aminophen commented Aug 10, 2017

いわゆる「緑」の本 (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}

次の版では,この「緑」の指摘をそのまま取り込むことを検討中です。

@aminophen aminophen changed the title from 目次の中の \ref で後ろの空白が喰われる to 目次の中の \ref で後ろの空白が喰われる + スペースファクター Aug 10, 2017

@aminophen

This comment has been minimized.

Show comment
Hide comment
@aminophen

aminophen Sep 24, 2017

Member

a06e767 でカーネルへ。

Member

aminophen commented Sep 24, 2017

a06e767 でカーネルへ。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment