在页面开始时保存文本宏的值。

在页面开始时保存文本宏的值。

我有一个宏,用于存储一些文本。我想打印该宏的文本,就像它在页眉中位于页面开头一样,以及在页脚中位于页面结尾一样。我可以像这样对计数器执行此操作:

\documentclass{article}
\usepackage{scrpage2,lipsum}
\pagestyle{scrheadings}
\makeatletter
\newcounter{ctr}
\newcounter{@ctr}
\chead{\arabic{@ctr}\setcounter{@ctr}{\value{ctr}}}
\cfoot{\arabic{ctr}}
\setcounter{ctr}{1}
\setcounter{@ctr}{1}
\makeatother

当设置页眉时(在页面末尾),它会输出内部计数器的值@ctr,然后将该计数器设置为用户使用的计数器的值ctr。它将其设置为页面末尾的值(这将是新页面开头的值(这是我想要的))。

当我尝试对包含文本的宏而不是计数器执行“类似”过程时,我没有得到我想要的结果:页眉设置为宏的值,因为它位于页面末尾。我该如何修复此问题?

以下 MWE 显示了问题。计数器和文本应该始终引用相同的数字,但事实并非如此。

\documentclass{article}
\usepackage{scrpage2,lipsum}
\pagestyle{scrheadings}
\ohead{}

\makeatletter

\newcounter{ctr}
\newcounter{@ctr}
\chead{\arabic{@ctr}\setcounter{@ctr}{\value{ctr}}}
\cfoot{\arabic{ctr}}
\setcounter{ctr}{1}
\setcounter{@ctr}{1}

\def\thetext{First text}
\def\@thetext{\thetext}
\ihead{\@thetext\def\@thetext{\thetext}}
\ifoot{\thetext}

\makeatother

\begin{document}
\lipsum[1-4]

{\Large Becoming Second text}\stepcounter{ctr}
\def\thetext{Second text}

\lipsum[5-7]

{\Large Becoming Third text}\stepcounter{ctr}
\def\thetext{Third text}

\lipsum[8-11]

{\Large Becoming Fourth text}\stepcounter{ctr}
\def\thetext{Fourth text}

\lipsum[12]
\end{document}

在我看来,这可能是某种扩展问题。我尝试使用\edef而不是\def,但是没有得到想要的结果。我做错了什么?

答案1

您需要使用\edef(扩展\def) 或更好的\xdef(全局扩展) 代替\def,否则您只是定义\@thetext扩展到\thetext,然后扩展到其当前定义。因此不断说\def\@thetext{\thetext}不会改变其定义。您想要做的是分配当前的值以\thetext\@thetext“引用”它。

LaTeX 提供了一个扩展版本,称为 ,\protected@xdef它可以确保\protect在其参数中正常工作。(还有一个\protected@edef。)

\def\thetext{First text}
\def\@thetext{\thetext}
\ihead{\@thetext\protected@xdef\@thetext{\thetext}}
\ifoot{\thetext}

答案2

这是使用 的第一次近似值\marks

\documentclass{article}
\usepackage{lipsum,etex}
\usepackage{scrpage2}
\pagestyle{scrheadings}
\ohead{}

\makeatletter

\newmarks\grillmark

\newcounter{ctr}
\newcounter{@ctr}
\chead{\arabic{@ctr}\setcounter{@ctr}{\value{ctr}}}
\cfoot{\arabic{ctr}}
\setcounter{ctr}{1}
\setcounter{@ctr}{1}

\ihead{%
  \ifnum\value{page}=1 
    \expandafter\firstmarks
  \else
    \expandafter\topmarks
  \fi\grillmark}% changed per Martin's suggestion
\ifoot{\botmarks\grillmark}

\makeatother

\begin{document}
\marks\grillmark{First text}
\lipsum[1-4]

{\Large Becoming Second text}\stepcounter{ctr}
\marks\grillmark{Second text}

\lipsum[5-7]

{\Large Becoming Third text}\stepcounter{ctr}
\marks\grillmark{Third text}

\lipsum[8-11]

{\Large Becoming Fourth text}\stepcounter{ctr}
\marks\grillmark{Fourth text}

\lipsum[12]

{\Large Becoming Fifth text}\stepcounter{ctr}
\marks\grillmark{Fifth text}
\lipsum[13-15]
\vspace{0.75in}% Enough to get to end of page

{\Large Becoming Sixth text}\stepcounter{ctr}
\marks\grillmark{Sixth text}
\lipsum[16]
\end{document}

TeXbook 或 TeX by Topic 中有解释:通用标记与 TeX 中的标准标记相同,不同之处在于命令以“s”结尾,后面需要一个数字。此处的数字由\newmarks提供的分配埃泰克斯。标准分数也可用于\marks0设置分数和\firstmarks0\topmarks0以及\botmarks0检索分数。有 32767 个分数类别:我认为绰绰有余。

答案3

这不是答案,而是评论。我需要添加代码,因此将其发布在这里。

如果宏的值在页面顶部发生变化,则此解决方案似乎存在问题。以下 MWE 包括 Martin 和 Seamus 建议的修复,并附加了第五第六测试来说明问题:

\documentclass{article}
\usepackage{lipsum}
\usepackage{scrpage2}
\pagestyle{scrheadings}
\ohead{}

\makeatletter

\newcounter{ctr}
\newcounter{@ctr}
\chead{\arabic{@ctr}\setcounter{@ctr}{\value{ctr}}}
\cfoot{\arabic{ctr}}
\setcounter{ctr}{1}
\setcounter{@ctr}{1}

\def\thetext{First text}
\xdef\@thetext{\thetext}% changed \def to \xdef per Seamus's comment
\ihead{\@thetext\protected@xdef\@thetext{\thetext}}% changed per Martin's suggestion
\ifoot{\thetext}

\makeatother

\begin{document}
\lipsum[1-4]

{\Large Becoming Second text}\stepcounter{ctr}
\def\thetext{Second text}

\lipsum[5-7]

{\Large Becoming Third text}\stepcounter{ctr}
\def\thetext{Third text}

\lipsum[8-11]

{\Large Becoming Fourth text}\stepcounter{ctr}
\def\thetext{Fourth text}

\lipsum[12]

{\Large Becoming Fifth text}\stepcounter{ctr}
\def\thetext{Fifth text}
\lipsum[13-15]
\vspace{0.75in}% Enough to get to end of page

{\Large Becoming Sixth text}\stepcounter{ctr}
\def\thetext{Sixth text}
\lipsum[16]
\end{document}

请注意,第 3 页底部应该提到5, 并不是6

相关内容