0

I'm not sure why the following code causes problems.

\documentclass{article}
\usepackage{array}
\newcommand{\startStatBlock}[1]
    {#1 \arraybackslash}
\newcommand{\stopStatBlock}
    {\arraybackslash}
\newenvironment{statBlock}[1]
    {\startStatBlock{#1}}
    {\stopStatBlock}

\begin{document}

% This works just fine.
\begin{tabular}{ll}
    \startStatBlock{thing}
        stat one & 2 \\
        stat two & 2 \\
    \stopStatBlock
\end{tabular}

% The following fails with the following message:
% ! Extra }, or forgotten \endgroup.
% <recently read> \egroup
% l.22 \end{tabular}

\begin{tabular}{ll}
    \begin{statBlock}{Some Stats}
        stat one & 2 \\
        stat two & 2 \\
    \end{statBlock}
\end{tabular}

\end{document}

I apologize if this has been covered before, but I wasn't able to find directly related questions. I'm not sure what the difference between the two are.

The reason I'd like to use the environment is to make the semantic structure of my document more clear, so I'd really prefer to use environments over commands to start and stop an environment. Also, this is just a simplified example to isolate an error; ideally, in the final product, there'd be a lot of presentation logic inside of the statBlock environment and similar environments, and the content inside of the environments would mainly be information, without too much stuff for specifying appearance.

5
  • a table cell is a group so your environment is like {\begin{statBlock} SomeStats} stat one} this isn't going to work without a lot of internal definitions to fake an environment Oct 15, 2017 at 19:05
  • @David Hm. Is there a technical meaning to the word "group" here? Is it just stuff that's wrapped in braces? I'm also a bit confused on the idea of "faking an environment". I'm not trying to fake an environment, I'm trying to use an actual environment. I've got stuff that I'd like to happen at the start of a stat block, and things that I'd like to occur at the end. I figured that the \begin{environment} and \end{environment} commands were just like macros. Oct 15, 2017 at 19:13
  • At the end of a group all local definitions are reverted so if you go {\bfseries xxxx} yyy the bold font is discarded at the } you will similarly see if you use \bfseries in a table cell it stops being bold at the & so if you use {\begin{foo} ..} inside a group then you will get an error at the } because \begin{foo} starts a group that has to end by \end{foo} and } is the wrong kind of group end. Oct 15, 2017 at 19:31
  • @DavidCarlisle. I see. That's disappointing. Thank you for answering. It sounds like I'm going to have to dig into TeX programming and related gymnastics to pull this off, if I ever end up doing so. Could you recommend some sources for me to go read on this matter? Normally, I'd just go reading on my own, but I find TeX particularly impenetrable. Every time I have to do something sufficiently complicated, I feel like I'm programming with the levers and pulleys of an ancient machine; like typographic assembler. Oct 15, 2017 at 19:40
  • to be honest I wouldn't do it. (but the texbook or the free tex-by-topic as an alternative is the best source) You could make the syntax not give an error but you can not make it work like an environment as any settings made by your start code will be discarded at the first & so not in scope for the rest of the enviornment, so making it look like an environment might be confusing Oct 15, 2017 at 20:04

1 Answer 1

1

It would be possible to make the environnment syntax not give an error by undoing the implicit grouping added by \begin \end so for example

\documentclass{article}
\newcommand{\startStatBlock}[1]
    {#1 \arraybackslash}
\newcommand{\stopStatBlock}
    {\arraybackslash}

\makeatletter
\newenvironment{statBlock}[1]
    {\endgroup\startStatBlock{#1}}
    {\stopStatBlock\begingroup\def\@currenvir{statBlock}}

\makeatother

\usepackage{array}

\begin{document}

% This works just fine.
\begin{tabular}{ll}
    \startStatBlock{thing}
        stat one & 2 \\
        stat two & 2 \\
    \stopStatBlock
\end{tabular}

% The following fails with the following message:
% ! Extra }, or forgotten \endgroup.
% <recently read> \egroup
% l.22 \end{tabular}

\begin{tabular}{ll}
    \begin{statBlock}{Some Stats}
        stat one & 2 \\
        stat two & 2 \\
    \end{statBlock}
\end{tabular}

\end{document}

However the environment does not work as an environment as each table cell is a group, so for example at the start of the environment you have

#1 \arraybackslash

but the \arraybackslash does nothing useful as it just sets up \\ to end the table row however that is needed in the second column but this definition is discarded at the & so it is only active in the first cell of the first column.

2
  • Ah, I think I can see what you're saying now. To make an environment that works as I wanted, I'd have to prematurely end the environment with \endgroup. This way, I end the grouping on my own terms, where an error won't happen; on the flipside, this pretty much isn't an environment anymore. It just looks like one. That said, I'm a bit confused by the use of \begingroup\def\@currenvir{statBlock} at the end of the ending command for the statBlock environment. Again, thanks so much for all the help. Oct 15, 2017 at 23:13
  • the \end command checks that it is closing the right enviornment so that \begin{wibble}...\end{wobble} gives an error, but grouping means that latex has "forgotten" that statBlock started so \end{statBlock} would give an error that \begin{tabular} ended by \end{statBlock} so you have to fake the environment start again at the end so the \end doesn't complain Oct 16, 2017 at 6:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .