6

Is there anyway to detect if the code is currently inside a list, no matter itemize, enumerate or description?

Note: I'm using enumitem for configuring lists.

Motivation: The reason I'm asking this is because that an environment in my document needs different vertical spacing outside or inside lists.

\documentclass{article}
\usepackage{enumitem}
\newcommand{\IfInList}[2]{...} % How to define this?

\begin{document}
\begin{itemize}
    \item \IfInList{code if in list}{code if not in list}
\end{itemize}
\IfInList{code if in list}{code if not in list}
\end{document}
5
  • you can check \leftmargin but the exact definition depends on what you mean by "in a list" is text in a minipage in a list "in a list" is text in a center (or quote or flushleft) environment all of which are implemented as one item lists "in a list" Mar 24, 2022 at 11:39
  • You can more easily check "immediately after an \item as that is \if@inlabel see the spacing trivlist does fornested cases: \if@inlabel \@noparitemtrue \@noparlisttrue \else \if@newlist \@noitemerr \fi \@noparlistfalse \@topsep \@topsepadd \fi Mar 24, 2022 at 11:41
  • Reading the source code it seems that you can check if macro enit@list has the same meaning as enit@enlist or enit@dylist, but is enumitem package guaranteed?
    – user202729
    Mar 24, 2022 at 11:49
  • Actually until inline list it seems to be equal to neither somehow...
    – user202729
    Mar 24, 2022 at 11:52
  • @user202729 It seems \ifx\enit@list\enit@dylist does work, at least this is the case in my document.
    – Jinwen
    Mar 24, 2022 at 11:56

1 Answer 1

6

We can emulate a stack by increasing to a counter when entering one of the specified environments and decreasing it at the end.

The \IfInList command can test whether the counter is positive.

The \listenvironments command can be issued multiple times, better not with the same environment name (I'm sure you can solve the problem yourself, if needed).

\ExplSyntaxOn
\NewDocumentCommand{\listenvironments}{m}
 {
  \clist_map_inline:nn { #1 }
   {
    \AddToHook{env/##1/begin}{\int_gincr:N \g_jinwen_list_int}
    \AddToHook{env/##1/end}{\int_gdecr:N \g_jinwen_list_int}
   }
 }
\NewExpandableDocumentCommand{\IfInList}{mm}
 {
  \int_compare:nTF { \g_jinwen_list_int > 0 } { #1 } { #2 }
 }
\int_new:N \g_jinwen_list_int
\ExplSyntaxOff

Complete example:

\documentclass{article}
\usepackage{enumitem}

\ExplSyntaxOn
\NewDocumentCommand{\listenvironments}{m}
 {
  \clist_map_inline:nn { #1 }
   {
    \AddToHook{env/##1/begin}{\int_gincr:N \g_jinwen_list_int}
    \AddToHook{env/##1/end}{\int_gdecr:N \g_jinwen_list_int}
   }
 }
\NewExpandableDocumentCommand{\IfInList}{mm}
 {
  \int_compare:nTF { \g_jinwen_list_int > 0 } { #1 } { #2 }
 }
\int_new:N \g_jinwen_list_int
\ExplSyntaxOff

\listenvironments{itemize,enumerate,description}

\begin{document}

\begin{itemize}
    \item \IfInList{code if in list}{code if not in list}
\end{itemize}

\IfInList{code if in list}{code if not in list}

\end{document}

enter image description here

1
  • Thank you! The idea of your code is very clear and easy to understand, and can also apply to other situations.
    – Jinwen
    Mar 24, 2022 at 17:18

You must log in to answer this question.

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