为什么当你摆弄 everypar 钩子时,\@startsection 中 skip 之后的负数会变得很奇怪?

为什么当你摆弄 everypar 钩子时,\@startsection 中 skip 之后的负数会变得很奇怪?

因此,我尝试回答这个问题:扩展草稿模式,包括用于手动打印输出到源同步的源信息 我遇到了一个奇怪的问题。看看这个例子:

\documentclass{article}
\usepackage{everyhook,marginnote}
\newif\ifnotmarginhook
\notmarginhooktrue
\PushPreHook{par}{%
  \ifnotmarginhook
  \notmarginhookfalse
  \smash{\marginnote{\small\ttfamily\the\inputlineno}}
  \notmarginhooktrue
  \fi
}
\makeatletter
% \renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}%
%                                     {3.25ex \@plus1ex \@minus.2ex}%
%                                     {1em}%
%                                     {\normalfont\normalsize\bfseries}}
\makeatother
\begin{document}

\section{This works}

Here is some text and it will go on and on
Here is some text and it will go on and on
Here is some text and it will go on and on

\subsection{This too}

Here is some text and it will go on and on
Here is some text and it will go on and on
Here is some text and it will go on and on

\paragraph{Broken!}

Here is some text and it will go on and on
Here is some text and it will go on and on
Here is some text and it will go on and on

\end{document}

破碎的!

如果您将的定义更改\paragraph为 afterskip 具有正值(如注释掉的重新定义中所示),则一切都很好。发生了什么事,我该如何解决?看起来好像有什么东西弄乱了方框,但我不明白是什么...

看起来有些奇怪的事情正在发生:我猜负跳过意味着 TeX 会处理\rlap段落名称,测量段落标题的文本,然后在无缩进段落的开头放置那么多空间加上 afterskip 量。有这样的事情发生吗?我该如何阻止它重叠?

答案1

\marginnote命令,当分解为它在您的上下文中执行的操作时,或多或少

\newcommand*{\marginnote}[1]{\setbox0\vbox{#1}\wd0=0pt\box0}

并且\paragraph

\renewcommand*{\paragraph}[1]{%
  \global\@noskipsectrue
  \everypar{%
    \if@noskipsec
      \global\@noskipsecfalse
      {\normalfont\textbf{#1}}\quad
    \else
      \everypar{}%
    \fi
  }%
}

问题出在\vbox\marginnote如果你把它改成\hbox,问题在你的上下文中就消失了)。导致 单词 Broken!排版在段落文本上的原因只是 宽度的变化\vbox(实际上\marginnote也修改了它的高度和深度,这就是为什么在你的例子中它也被上移了)。

以下是显示该现象的完整精简代码(边距数字放置不正确,因为\marginnote必须为此做更多的事情):

\documentclass{article}

\usepackage{everyhook}

\newif\ifnotmarginhook
\notmarginhooktrue
\PushPreHook{par}{%
  \ifnotmarginhook
    \notmarginhookfalse
    \marginnote{\small\ttfamily\the\inputlineno}%
    \notmarginhooktrue
  \fi
}

%\newcommand*{\marginnote}[1]{\setbox0\hbox{#1}\wd0=0pt\box0}% works
\newcommand*{\marginnote}[1]{\setbox0\vbox{#1}\wd0=0pt\box0}% doesn't work

\makeatletter
\renewcommand*{\paragraph}[1]{%
  \global\@noskipsectrue
  \everypar{%
    \if@noskipsec
      \global\@noskipsecfalse
      {\normalfont\textbf{#1}}\quad
    \else
      \everypar{}%
    \fi
  }%
}
\makeatother

\begin{document}

\section{This works}

Here is some text and it will go on and on
Here is some text and it will go on and on
Here is some text and it will go on and on

\subsection{This too}

Here is some text and it will go on and on
Here is some text and it will go on and on
Here is some text and it will go on and on

\paragraph{Broken!}

Here is some text and it will go on and on
Here is some text and it will go on and on
Here is some text and it will go on and on

\end{document}

当然,这里您的解决方案是使用\PushPostHook前面提到的方法。

答案2

(这并没有回答问题本身,但确实提供了一种解决方法。)

将命令附加\marginpar到 post-par 钩子上(即\PushPostHook)似乎可以神奇地解决这个问题: 在此处输入图片描述

(行首看到的多余空格来自钩子中的空格。)

相关内容