在分页符和环境边界处重置存储的值

在分页符和环境边界处重置存储的值

基于问题,我创建了一个简单的宏,可以打印并存储它的参数,如果再次使用相同的参数发出它,它不会打印任何内容:

% !TEX TS-program = xelatexmk
\RequirePackage{filecontents}

\begin{filecontents}{mypackage.sty}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mypackage}

\newenvironment{myenv}{\ignorespaces}{\par\ignorespacesafterend}

\DeclareOption{skiprepetitions}{%
  \AtBeginDocument{\let\mypackage@print\mypackage@print@skip}%
}
\DeclareOption{keeprepetitions}{%
  \AtBeginDocument{\let\mypackage@print\mypackage@print@keep}%
}
\ExecuteOptions{keeprepetitions}
\ProcessOptions\relax

\RequirePackage{xifthen}

\def\mypackage@storedval{} % create a macro to later store a value in

\newcommand{\mycommand}[1]{%
  \ifthenelse{\isempty{#1}}
    {% if empty just print an empty line
     \mbox{}%
    }
    {% if not empty
     \mypackage@print{#1}%
     \def\mypackage@storedval{#1}%
    }%
}

\def\mypackage@print@skip#1{%
  \ifthenelse{\equal{#1}{\mypackage@storedval}}
   {\mbox{}}
   {#1}%
}
\def\mypackage@print@keep#1{#1\\}

\end{filecontents}

\documentclass{article} 

\usepackage[skiprepetitions]{mypackage}

\begin{document}

\begin{myenv}
\mycommand{A} \\ %A
\mycommand{A} \\  %empty
\mycommand{A} \\  %empty
\mycommand{} \\    %empty
\mycommand{B} \\  %B
\mycommand{C} \\  %C
\mycommand{C} \\  %empty
\mycommand{A} \\  %A
\end{myenv}

\begin{myenv}
\mycommand{A} \\ %A  
\mycommand{A} \\ %empty

\newpage

\mycommand{A} \\ %A 
\end{myenv}

\end{document}

我现在想让它“重置”或“忘记”在特定环境的分页符和边界处存储的内容,以便在新页面上或在新环境中打印其参数,即使前一个参数相同。

上面的文档中注释掉的是我希望看到的值。

答案1

据我了解,以下内容可以满足您的要求(感谢大卫·卡莱尔的评论有关提示perpage!):

\RequirePackage{filecontents}

\begin{filecontents}{mypackage.sty}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mypackage}

\RequirePackage{perpage}

\newcounter{mycounter}
\MakePerPage{mycounter}

\newenvironment{myenv}{%
  % \mycommand is only defined inside the environment
  \let\mycommand\my@command
  % Make sure the next \mycommand isn't ignored, even if its argument
  % matches the value stored in \mypackage@storedval.
  \setcounter{mycounter}{0}%
  \ignorespaces
}{%
  \par\ignorespacesafterend
}

\DeclareOption{skiprepetitions}{%
  \AtBeginDocument{\let\mypackage@print\mypackage@print@skip}%
}
\DeclareOption{keeprepetitions}{%
  \AtBeginDocument{\let\mypackage@print\mypackage@print@keep}%
}
\ExecuteOptions{keeprepetitions}
\ProcessOptions\relax

\RequirePackage{xifthen}

\def\mypackage@storedval{} % create a macro to later store a value in

\newcommand{\my@command}[1]{%
  \ifthenelse{\isempty{#1}}%
    {% if empty just print an empty line
     \mbox{}%
    }%
    {% If this is the first \stepcounter{mycounter} executed since the current
     % page was started, this sets 'mycounter' to 1.
     \stepcounter{mycounter}%
     \mypackage@print{#1}%
     \def\mypackage@storedval{#1}%
    }%
}

\def\mypackage@print@skip#1{%
  \ifthenelse{\cnttest{\value{mycounter}}>{1}\AND
              \equal{#1}{\mypackage@storedval}}%
   {\mbox{}}%
   {#1}%
}
\def\mypackage@print@keep#1{#1\\}

\end{filecontents}

\documentclass{article}

\usepackage[skiprepetitions]{mypackage}

\begin{document}
\setlength{\parindent}{0pt}

\begin{myenv}
\mycommand{A}\\  %A
\mycommand{A}\\  %empty
\mycommand{A}\\  %empty
\mycommand{}\\   %empty
\mycommand{B}\\  %B
\mycommand{C}\\  %C
\mycommand{C}\\  %empty
\mycommand{A}\\  %A
\end{myenv}

\begin{myenv}
\mycommand{A}\\ %A
\mycommand{A}\\ %empty

\newpage

\mycommand{A}\\ %A
\end{myenv}

\end{document}

我使用了一个名为 的新计数器,mycounter该计数器受 约束\MakePerPage{mycounter}。这意味着\stepcounter{mycounter}任何给定页面上的第一个都会重置mycounter为 1,因为的可选参数的默认值是\MakePerPage

我这样设置myenv,在 的开头,mycounter设置为 0。此外,每当以非空参数调用 时,\stepcounter{mycounter}就会执行。因此,执行此操作后,当且仅当以下情况时, 才等于 1:\mycommand\stepcounter{mycounter}mycounter

  • \mycommand这是当前页面上的第一个调用,或者;

  • \mycommand这是当前环境中的第一次通话myenv

这是您需要的“忽略标准”的基础。唯一需要检查的另一件事是,当我们处于“可能忽略模式”时,传递给b 的参数\mycommand与保存的值不同(因为所有这些都来自空虚检查)。

请注意,我将您的\mycommandto重命名为\my@command并且\let\mycommand\my@command仅在myenv环境内执行,因此如果您调用\mycommand任何环境之外的to myenv,LaTeX 将报告错误(未定义的命令)。

您可能希望将\stepcounter{mycounter}调用移到宏的开头\my@command:这取决于传递空参数时您想要的行为。它应该使新状态成为“可能忽略模式”,还是应该让状态保持不变(在我的代码中:后者)?这是属于您的决定。但由于您只是\mbox{}为空参数输出一个,因此差异通常不会很明显……

在此处输入图片描述

脚注


a. 经过两次编译运行后,由于该perpage包依赖于该.aux文件。

b. 即参数非空,且调用\mycommand既不是页面上的第一个,也不是环境中的第一个。

相关内容