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.
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.
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:
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.
Answered by egreg on February 5, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP