1

I used the answer from here for checking if an environment is placed on another page than the enclosing environment. I want to execute other commands as soon as I am on a new page, but only once on that page, even if there are multiple sections B on that new page. Thus I modified it as shown here:

\documentclass{article}
\usepackage{refcount}
\usepackage{etoolbox}
\newcounter{envAcounter}
\newcounter{envBcounter}
\newtoggle{newPage}
\togglefalse{newPage}
\newenvironment{A}{%
  \stepcounter{envAcounter}%
  \null\label{env:A:start:\arabic{envAcounter}}%
}{\label{env:A:end:\arabic{envAcounter}}
\togglefalse{newPage}
}%

\newenvironment{B}{%
  \stepcounter{envBcounter}%
  \null\label{env:B:start:\arabic{envBcounter}}%
  \iftoggle{newPage}{}{
  \ifnum\getpagerefnumber{env:A:start:\arabic{envAcounter}}=%
        \getpagerefnumber{env:B:start:\arabic{envBcounter}}\relax%
    Pagebreak did not take place before starting environment B!% 
  \else
    Pagebreak took place before starting environment B!%
    \toggletrue{newPage}
  \fi}
}{\label{env:B:end:\arabic{envBcounter}}}%

\begin{document}

\begin{A}
Text
\begin{B}
SubText
\end{B}
\end{A}
\begin{A}
Text2
\newpage
\begin{B}
SubText2
\end{B}
\begin{B}
SubText3
\end{B}
\end{A}
\end{document}

The idea was to set a true-value as soon as the first page break is detected, and then afterwards skip the check. But that does not work, I still get the check if I am at a new page executed every time I am in environment B. Why is the toggle not working as expected, and how can I fix that?

  • 1
    Try \global\togglefalse etc. Your working inside of groups – user31729 Apr 2 '16 at 8:35
  • Yes, that works. Is there an extended explanation, when I have to use \global? – arc_lupus Apr 2 '16 at 8:46
  • Otherwise, the toggle is local to the environment – Guido Apr 2 '16 at 8:50
  • @arc_lupus: The \toggle..... stuff is (as far as now) nothing different than a wrapper for a plain \if.... conditional. The boolean states true and false 'survive' only within a group, and \ifsomething .... \fi is a group, the environment is also a group. Your state must be available after the conditional or the environment ends, as such, you must \globalize the state. – user31729 Apr 2 '16 at 9:43
2

Certain things in (La)TeX have limited scope. If you want its modifications to survive the group within which the change is made, you have to ensure that it's made \globally (or, perhaps, in such a way that it happens after the group):

enter image description here

\documentclass{article}

\usepackage{etoolbox,etextools}

\newcommand{\showtoggle}[1]{#1: \iftoggle{#1}{true}{false}\par}

\newtoggle{mytoggle}
%\togglefalse{mytoggle}% default

\newenvironment{myenv}%
  {\bigskip
   begin: \showtoggle{mytoggle}}
  {end: \showtoggle{mytoggle}}

\begin{document}

\togglefalse{mytoggle}
\begin{myenv}% false
inside: \showtoggle{mytoggle}% false
\end{myenv}% false

outside: \showtoggle{mytoggle}% false

\toggletrue{mytoggle}
\begin{myenv}% true
inside: \showtoggle{mytoggle}% true
\end{myenv}% true

outside: \showtoggle{mytoggle}% true

\togglefalse{mytoggle}
\begin{myenv}% false
\toggletrue{mytoggle}
inside: \showtoggle{mytoggle}% true
\end{myenv}% true

outside: \showtoggle{mytoggle}% false

\togglefalse{mytoggle}
\begin{myenv}% false
\AfterGroup{\toggletrue{mytoggle}}
inside: \showtoggle{mytoggle}% false
\end{myenv}% false

outside: \showtoggle{mytoggle}% true

\togglefalse{mytoggle}
\begin{myenv}% false
\global\toggletrue{mytoggle}
inside: \showtoggle{mytoggle}% true
\end{myenv}% true

outside: \showtoggle{mytoggle}% true

\end{document}

Counters are different...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.