1

I'm working on a document template in which I have some nested itemize lists which I need to add some commands before and after each list element.

To accomplish this, I've created a new environment with the \newenvironment command, which I'll call tlist which is a wrapper around the itemize environment, and also created a new command called \titem which is a wrapper around the \item command.

I'm then using a \newif to detect whether or not an item has been opened and closed to allow list nesting without needing anything after the \titem. A MWE is shown below.

\documentclass{article}

\usepackage{ifpdf}
\usepackage{etoolbox}

% Keep track of whether we are in a titem
\newif\ifistitemopen

% TList environment
\newenvironment{tlist}{
    % Begin list
    \begin{itemize}
    % Check if an item is open already
\ifistitemopen
    % Must be in a nested list. Close just the body
    \item close by tlist begin
\fi
    % No item is open
    \istitemopenfalse
}{
    % No item is open
    \ifistitemopen
        % Close previous list item if open
        \item close by tlist end
        \istitemopenfalse
    \fi
    % End list
    \end{itemize}
}

% New user command \titem replaces \item
\newcommand{\titem}{
\ifistitemopen
    % Close previous list item if open
    \item close by new item
\fi
    \istitemopentrue
    % Open new list item
    \item open by new item
    \item
}

\begin{document}


\textbf{Bad Example 1:}

\begin{tlist}
    \titem Foo
    
    \begin{tlist}
        \titem Bar
    \end{tlist}
    
\end{tlist}

\textbf{Bad Example 2:}

\begin{tlist}
    \titem Foo
    
    \begin{tlist}
        \titem Bar
    \end{tlist}
    
    \titem Fizz
    
\end{tlist}

\end{document}

Currently this is mostly working, except for reasons I can't fathom the first time the \if... is checked after it has been set false seems to detect it as true. To try and visualise this, I've added some extra \item commands into the code to print out when things are happening. I've shown two examples, where the if is checked were even though it should be false, an \item is output as if it were true - highlighted on the image below.

Bad Examples with extra close item

I'm not an expert on LaTeX, so any advice as to why this is happening and how I can fix it would be greatly received.

2 Answers 2

2

The reason it works with counters and not with conditionals is that counters are acted on globally (transcending the group in which they are set in, and environments form groups).

To the contrary, \newif makes the \...false and \...true commands to only act locally, so their effect ends with the group where they appear. You can fix them by hand, if you want that the commands act globally.

\documentclass{article}

\usepackage{ifpdf}
\usepackage{etoolbox}

% Keep track of whether we are in a titem
\newif\ifistitemopen
% redefine the associated commands to act globally
\def\istitemopentrue{\global\let\ifistitemopen\iftrue}
\def\istitemopenfalse{\global\let\ifistitemopen\iffalse}

% TList environment
\newenvironment{tlist}{%
    % Begin list
    \begin{itemize}
    % Check if an item is open already
\ifistitemopen
    % Must be in a nested list. Close just the body
    \item close by tlist begin
\fi
    % No item is open
    \istitemopenfalse
}{%
    % No item is open
    \ifistitemopen
        % Close previous list item if open
        \item close by tlist end
        \istitemopenfalse
    \fi
    % End list
    \end{itemize}
}

% New user command \titem replaces \item
\newcommand{\titem}{%
\ifistitemopen
    % Close previous list item if open
    \item close by new item
\fi
    \istitemopentrue
    % Open new list item
    \item open by new item
    \item
}

\begin{document}


\textbf{Bad Example 1:}

\begin{tlist}
    \titem Foo
    
    \begin{tlist}
        \titem Bar
    \end{tlist}
    
\end{tlist}

\textbf{Bad Example 2:}

\begin{tlist}
    \titem Foo
    
    \begin{tlist}
        \titem Bar
    \end{tlist}
    
    \titem Fizz
    
\end{tlist}

\end{document}

Alternatively, do \global\istitemopentrue and \global\istitemopenfalse in the code.

enter image description here

1
  • Cheers, that makes a lot of sense. I thought I was going mad for a while there. I'll change back to using the global if as it seems a tad cleaner than a counter going from 0 to 1 and back again. Oct 15, 2020 at 9:25
0

I don't know why the \newif wasn't working as expected, but I've found a work around using a counter:


\documentclass{article}

\usepackage{ifpdf}
\usepackage{etoolbox}

% Keep track of whether we are in a titem
\newcounter{titemopencount}
\setcounter{titemopencount}{0}

% TList environment
\newenvironment{tlist}{
    % Begin list
    \begin{itemize}
    % Check if an item is open already
\ifnum\the\value{titemopencount}>0
    % Must be in a nested list. Close just the body
    \item close by tlist begin
    \addtocounter{titemopencount}{-1}
\fi
    % No item is open
}{
    % No item is open
    \ifnum\the\value{titemopencount}>0
        % Close previous list item if open
        \item close by tlist end
        \addtocounter{titemopencount}{-1}
    \fi
    % End list
    \end{itemize}
}

% New user command \titem replaces \item
\newcommand{\titem}{
\ifnum\the\value{titemopencount}>0
    % Close previous list item if open
    \item close by new item
    \addtocounter{titemopencount}{-1}
\fi
    \addtocounter{titemopencount}{1}
    % Open new list item
    \item open by new item
    \item
}

\begin{document}


\textbf{Good Example 1:}

\begin{tlist}
    \titem Foo
    
    \begin{tlist}
        \titem Bar
    \end{tlist}
    
\end{tlist}

\textbf{Good Example 2:}

\begin{tlist}
    \titem Foo
    
    \begin{tlist}
        \titem Bar
    \end{tlist}
    
    \titem Fizz
    
\end{tlist}

\end{document}


Which now produces:

Good Example

You must log in to answer this question.

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