TransWikia.com

Setting a newif to false ignored on first check in custom itemize environment

TeX - LaTeX Asked by Tom Carpenter on February 5, 2021

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
newififistitemopen

% 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

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
ifnumthevalue{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
    ifnumthevalue{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}{
ifnumthevalue{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

Answered by Tom Carpenter on February 5, 2021

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
newififistitemopen
% redefine the associated commands to act globally
defistitemopentrue{globalletifistitemopeniftrue}
defistitemopenfalse{globalletifistitemopeniffalse}

% 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 globalistitemopentrue and globalistitemopenfalse in the code.

enter image description here

Answered by egreg on February 5, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP