Terminar um ambiente no ‘antes’ de um novo ambiente

Terminar um ambiente no ‘antes’ de um novo ambiente

Estou tentando criar um ambiente que feche um multicolsgrupo, faça uma coisa e depois inicie um novo multicols.

Algo como

\newcount{\colcount}
\newenvironment{balancedbreak}{%
\let\colcount\col@number
\end{multicols}\newpage\begin{multicols}{\colcount}
}{
}

Isso não funciona, recebo a mensagem de erro

! LaTeX Error: \begin{balancedbreak} on input line 38 ended by \end{multicols}

MWE

Isso constrói.

\documentclass{article}
\usepackage{multicol}
\usepackage{lipsum}

\newcount{\colcount}
\newenvironment{balancedbreak}{%
\let\colcount\col@number%
%\end{multicols}\newpage\begin{multicols}{\colcount}%
\newpage
}{%
}

\begin{document}
\begin{multicols}{2}
\lipsum[1]
\lipsum[2]
\begin{balancedbreak}
\textbf{Testing here}
\end{balancedbreak}
\lipsum[3]
\lipsum[4]
\end{multicols}
\end{document}

Recebo uma coluna longa e desequilibrada, depois uma nova página e colunas balanceadas. Se eu descomentar a linha que inicia \end{multicols}no novo ambiente e comentar o próximo, recebo a mensagem de erro acima.

Estou curioso sobre o caso geral: "como faço para encerrar um ambiente na seção 'antes' de um arquivo \newenvironment?

(Minha necessidade imediata é "como posso atingir melhor o objetivo de encerrar uma multicolspágina para que ela se equilibre e passe para a próxima página?". Eu simplesmente não poderia fazer isso do jeito que estou agora, mas gostaria de usar um ambiente por outras razões.)

Responder1

Seria muito mais fácil fazer isso com uma macro. Com um ambiente que você precisa acompanhar \@currenvire estar no grupo certo. O \endgroup e \begingroup devem encerrar e reiniciar o ambiente blanacedbreak.

\documentclass{article}
\usepackage{multicol}
\usepackage{lipsum}
%\tracingmacros=1

\makeatletter
\newcount{\colcount}
\newenvironment{balancedbreak}{%
\global\colcount=\col@number% current value will otherwise be lost
\endgroup\endmulticols\newpage
\multicols\colcount\begingroup
\def\@currenvir{balancedbreak}%
}{}%
\makeatother

\begin{document}
\begin{multicols}{2}
\lipsum[1]
\lipsum[2]
\begin{balancedbreak}
\textbf{Testing here}
\end{balancedbreak}
\lipsum[3]
\lipsum[4]
\end{multicols}
\end{document}

Responder2

Outras pesquisas e experimentações mostram que o novo ambiente não é apenas um “invólucro para coisas”, mas na verdade tem um significado estrutural (cria um grupo implícito). Aquilo é,

\newcount\colcount
\newenvironment{balancedbreak}{%
\let\colcount\col@number%
\end{multicols}\newpage\begin{multicols}{\colcount}%
}{%
}

age algo como

  • \begin{balancedbreak}
    • \begingroup
      • \let\colcount\col@number
      • \end{multicols}\newpage\begin{multicols}{\colcount}

Eu pensei - incorretamente, ao que parece - que o 'antes' era algo como uma substituição de texto. Eu tinha esquecido o implícito begingroup.

Acontece que usando a definição acima,

\balancedbreak
Some content goes here
\endbalancedbreak

Parece funcionar.

Solução de trabalho atual:

\newcount\colcount
\newenvironment{balancedbreak}{%
\ifnum\doublecol@number>\z@ % if multicol
  \let\colcount\col@number%
  \end{multicols}\newpage\begin{multicols}{\colcount}%
\else%
  \newpage%
\fi
}{%
}

Isso funciona se e somente se não houver outro \begin{someenv}entre o \begin{multicols}e o \balancedbreak. Pode haver uma situação \begin{someenv} some stuff goes here \end{someenv}sem problemas, mas isso não pode acontecer 'dentro' de outro ambiente ou grupo.

Isso é muito mais frágil do que realmente me deixa feliz, e não sei se o recomendaria como uma solução geral. Dito isto, entendendo como funciona e por quê, acho que posso conviver com isso. Estou, obviamente, aberto a outras soluções.

informação relacionada