Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix incorrect handling of user-defined environments introduced in #856 (#1137) #1138

Closed
wants to merge 1 commit into from

Conversation

dpvc
Copy link
Member

@dpvc dpvc commented Oct 8, 2024

This PR fixes the problem with user-defined environments that was reported in #1137 that was introduced by PR #856, that was trying to fix a potential infinite recursion. It changed how the environments end macros were processed by inserting them into the parser string followed by second \end{...} macro. A parser.stack.env value (processing) was used to track when the second \end{...} was processed and skip the insertion of the end macros.

The problem with that is that the environment where processing was added might be cleared by the ed macros. For the example in #1137, the \begin{array} in the begin macros and the \end{array} in the end macros for the boxed environment means that the processing environment value is in the environment in effect within the array environment, and that environment is ended and removed when \end{array} is processed. So the processing value is also lost, and the end macros are inserted again, leading to a new \hline being inserted outside the array environment, and the associated error about a misplaced \hline.

Because of this, and other similar situations, the parser.stack.env value can't be used to track the second \end{...}. So I've gone back to the original process of parsing the end macros, but needed a new way to avoid the potential recursion that #856 was meant to fix.

The infinite recursion was possible when the end macros included \end{...} for the user-defined environment. This was a problem because when processing the end macros that contain \end{...} that \end would cause the end macros to be inserted again, and then that is related over and over. This is because the testing for a matching \begin{...} for the \end{...} isn't done until after the end macros are processed (so that the user-defined environment can include \begin and \end as in the example from #1137), when the end stack item is pushed.

The solution introduced here is use the beginEnv stack items to form a linked list of the open (user-defined) environments, with the the top-most beginEnv stack item recorded in a parser.stack.global variable. We only insert the end macro string if there is an active beginEnv on the stack, and we remove that from the linked list once we add the end macros the first time. That way, we only add the end macros once for any \begin{...} that is on the stack, so even if the end macros include \end{...}, they can't be inserted infinitely, and eventually we get the end stack item being pushed, producing the mismatched begin/end message.

This allows

\newenvironment{boxed}
    {\begin{array}{|c|c|}\hline}
    {\\\hline\end{array}}
\begin{boxed}a&b\\c&d\end{boxed}

and also

\newenvironment{boxed}
    {\begin{array}{|c|c|}\hline}
    {\\\hline\end{array}}
\begin{boxed}
\begin{boxed}a&b\\c&d\end{boxed}
& X
\end{boxed}

to work, while having

\newenvironment{a}{x}{y\end{a}}
\begin{a} ... \end{a}

produce an appropriate error message.

Other test cases include

\newenvironment{a}{x}{y}
\newenvironment{b}{p}{q}
\begin{a} \begin{b} ... \end{b} \end{a}

that should work while

\newenvironment{a}{x}{y}
\newenvironment{b}{p}{q}
\begin{a} \begin{b} ... \end{a} \end{b}

and

\newenvironment{a}{x}{y}
\begin{a} \begin{matrix} ... \end{a}

and

\newenvironment{a}{x}{y}
\begin{a} ... \end{matrix}

and

\newenvironment{a}{x}{y}
... \end{a}

and

\newenvironment{a}{a}{b\end{a}}
\newenvironment{b}{x}{y}
\begin{a} \begin{b} ... \end{b} \end{a}

should all produce errors.

The definitions

\newenvironment{a}{\begin{b}}{\end{b}}
\newenvironment{b}{x}{y}
\begin{a} ... \end{b}\begin{b}\end{a}

should produce x...yxy,

while

\newenvironment{a}{\begin{b}}{\end{b}}
\newenvironment{b}{x}{y\end{b}}
\begin{a} ... \end{a}

should error.

@dpvc dpvc requested a review from zorkow October 8, 2024 15:38
@dpvc dpvc closed this Oct 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant