如何访问 \pagetotal 的 *真实* 值?

如何访问 \pagetotal 的 *真实* 值?

在宏中,我需要知道我是否位于页面顶部(不包括顶部浮动)。因此,我使用的长度\pagetotal来确定我是否位于页面顶部。如果\pagetotal为零,则表示我位于页面顶部。但是,我注意到这\pagetotal并不总是“最新的”,并且会扭曲我的宏的使用。

我该如何强制\pagetotal更新?还是我误解了 的意思\pagetotal

您会在下面看到一个示例,其中\pagetotal宏位于页面顶部,尺寸约为 552 pt。

在此处输入图片描述

\documentclass{article}
\usepackage{lipsum}

\newcommand{\test}{%
\par
\ifdim\pagetotal=0pt
    TRUE%
\else
    FALSE : \textbackslash pagetotal = \the\pagetotal
\fi}

\begin{document}
\lipsum[1]

\lipsum[1]

\lipsum[1]

\lipsum[3]

\test

\the\pagetotal\lipsum[1]

\the\pagetotal
\end{document}

语境

这个问题与我之前的两个问题相关:如何从文档主体判断页面是否有顶部浮动?在使用时,如何确保 a 之前或之后的间距\vbox正确\addvspace?

我正在尝试创建一个宏,根据上下文添加不同的垂直空间。
通常,我想\myLength在宏的开头和结尾插入一个值的空间。
如果宏位于页面顶部,在分页符之后(\pagetotal=0pt如果我理解正确的话,其中),则忽略 \vspace{\myLength} 并且不添加垂直空间,这正是我想要的。
但是问题出现在,如前一种情况一样,宏位于页面顶部,但前面有一个或多个顶部浮动(它不再是严格意义上的“页面顶部”,但如果我理解正确的话,我们仍然有\pagetotal=0pt)。在这种情况下,我希望宏插入垂直\vspace*{\dimexpr\myLength-\textfloatsep}以保持一致性。

举个例子来说明一下:

这里,宏的行为正确:当它位于页面顶部时,宏的开头不会插入空格;当它不在页面顶部时,\vspace{\myLength}会正确插入。

在此处输入图片描述

然而,当宏位于页面顶部并且前面有一个顶部浮动时,空间就完全不平衡了。

在此处输入图片描述

这是一个不起作用的最小示例:

\documentclass{article}
\usepackage{lipsum, mwe, refcount}

\makeatletter
%From : https://tex.stackexchange.com/questions/712713/how-to-determine-from-the-document-body-whether-or-not-a-page-has-a-top-float
\def \@combinefloats {%
    \ifx \@toplist\@empty%
    \else%
        \@cflt%
        \immediate\write\@auxout{\string\global\string\@namedef{pageWithTopFloat-\thepage}{1}}%
    \fi%
    \ifx \@botlist\@empty \else \@cflb \fi%
}

\newcounter{ifTopFloatCnt}

\def\iftopfloat#1#2{%
    \global\advance\c@ifTopFloatCnt\@ne%
    \label{\the\c@ifTopFloatCnt @ifTopFloat}%    
    \ifcsname pageWithTopFloat-\getpagerefnumber{\the\c@ifTopFloatCnt @ifTopFloat}\endcsname%
        #1%
    \else%
        #2%
    \fi%
}
\makeatother

\newlength{\myLength}
\setlength{\myLength}{30pt}% exaggerated value to illustrate

\newcommand{\mycommand}{\par%
    \iftopfloat{%
        \ifdim\pagetotal=0pt% If there's a top float AND you're right after it
            \vspace*{\dimexpr\myLength-\textfloatsep}                         
        \else% If there is a top float BUT you are not right after it
            \vspace{\myLength}
        \fi
    }{% If there is no top float
        \vspace{\myLength}
    }
    {\centering\LARGE * * *\par}
    \vspace{\myLength}
}

\begin{document}
\lipsum[1]

\lipsum[1]

\lipsum[1]

\lipsum[3]

\begin{figure}[t]
\centering
\includegraphics{example-image}
\end{figure}

\mycommand

\lipsum[1]

\lipsum[2]

\mycommand

\lipsum[1]

\mycommand

\lipsum[1]
\end{document}

测试\pdfsavepos

正如评论中所建议的,我尝试使用\pdfsavepos\pdflastypos原语。这似乎比使用效果更好\pagetotal,但我在使用我的命令时仍然遇到了一些“错误”。

在某些情况下,\pdfsavepos给出命令位于页面顶部(\pdflastypos= 0)的信息,但实际上并非如此(请参阅下面的 MWE)。另一方面,有时当命令位于页面顶部时,页面顶部浮动之后,\pdflastypos不为零,这表明\pdflastypos实际上指的是上一页的底部。

示例:\pdflastypos尽管命令位于页面顶部,但这里我得到的结果却是 ≠ 0。

在此处输入图片描述

\documentclass{article}
\usepackage{lipsum, mwe, refcount, iftex}

\ifluatex% For compatibility with LuaTeX, which I generally use.
    \let\pdfsavepos\savepos
    \let\pdflastypos\lastypos
\fi

\makeatletter
%From : https://tex.stackexchange.com/questions/712713/how-to-determine-from-the-document-body-whether-or-not-a-page-has-a-top-float
\def \@combinefloats {%
    \ifx \@toplist\@empty%
    \else%
        \@cflt%
        \immediate\write\@auxout{\string\global\string\@namedef{pageWithTopFloat-\thepage}{1}}%
    \fi%
    \ifx \@botlist\@empty \else \@cflb \fi%
}

\newcounter{ifTopFloatCnt}

\long\def\ifTopFloat#1#2{%
    \global\advance\c@ifTopFloatCnt\@ne%
    \label{\the\c@ifTopFloatCnt @ifTopFloat}\nopagebreak%
    \ifcsname pageWithTopFloat-\getpagerefnumber{\the\c@ifTopFloatCnt @ifTopFloat}\endcsname%
        #1%
    \else%
        #2%
    \fi%
}

\newlength{\myLength}
\setlength{\myLength}{30pt}% exaggerated value to illustrate

\newcounter{myCommandCnt}
\newcounter{myCommandCntAux}

\newcommand{\myCommand}{\par%
    \stepcounter{myCommandCnt}%
    \pdfsavepos%
    \write\@auxout{%
        \string\global\string\stepcounter{myCommandCntAux}%
        \string\global\string\@namedef{myCommand-\string\themyCommandCntAux}{\the\pdflastypos}%
    }%
    \ifTopFloat{%
        \ifnum\@nameuse{myCommand-\themyCommandCnt}=0% If there's a top float AND you're right after it
            \vspace*{\dimexpr\myLength-\textfloatsep}
            {\centering\LARGE * * * (a, \textbackslash lastypos: \@nameuse{myCommand-\themyCommandCnt} )\par}
        \else% If there is a top float BUT you are not right after it
            \vspace{\myLength}
            {\centering\LARGE * * * (b, \textbackslash lastypos: \@nameuse{myCommand-\themyCommandCnt} )\par}
        \fi
    }{% If there is no top float
        \vspace{\myLength}
        {\centering\LARGE * * * (c, \textbackslash lastypos: \@nameuse{myCommand-\themyCommandCnt} )\par}
    }    
    \vspace{\myLength}
}

\makeatother

\begin{document}

\lipsum[1]

\lipsum[1]

\lipsum[1]

\lipsum[2]

\begin{figure}[t]
\centering
\includegraphics{example-image}
\end{figure}

\myCommand

\lipsum[1]

\lipsum[2]

\begin{figure}[t]
\centering
\includegraphics{example-image-9x16}
\end{figure}

\myCommand

\lipsum[2]

\myCommand

\lipsum[1]

\myCommand

\lipsum[1]
\end{document}

相关内容