jbezos / enumitem

Customize enumerate, itemize and description
MIT License
45 stars 5 forks source link

Things went wrong when I want to change several appearence of items in a newlist #33

Closed syvshc closed 2 years ago

syvshc commented 2 years ago

I want to change several appearence of item in a new enumerate-like environment exer. I wrote this

\documentclass{article}

\usepackage{enumitem}

% https://tex.stackexchange.com/a/52718/180617
\makeatletter
\def\exeritem{%
  \expandafter\let\expandafter\originallabel\csname labelexer\romannumeral\@enumdepth\endcsname
  \expandafter\def\csname labelexer\romannumeral\@enumdepth\expandafter\endcsname\expandafter{%
    \expandafter\bfseries\expandafter{\expandafter\originallabel}}%
  \item
  \expandafter\let\csname labelexer\romannumeral\@enumdepth\endcsname\originallabel
}
\def\bitem{%
  \expandafter\let\expandafter\originallabel\csname labelenum\romannumeral\@enumdepth\endcsname
  \expandafter\def\csname labelenum\romannumeral\@enumdepth\expandafter\endcsname\expandafter{%
    \expandafter\bfseries\expandafter{\expandafter\originallabel}}%
  \item
  \expandafter\let\csname labelenum\romannumeral\@enumdepth\endcsname\originallabel
}
\newlist{exer}{enumerate}{2}
\setlist[exer, 1]{leftmargin=*, label=\arabic*., widest=000, ref=\arabic*}

\begin{document}
\begin{exer}
    \exeritem \labelexeri
\end{exer}
\begin{exer}
    \let\originallabel\labelexeri
    \def\labelexeri{\bfseries\originallabel}
    \item \let\labelexeri\originallabel\labelexeri
\end{exer}
\begin{enumerate}
  \bitem \labelenumi
\end{enumerate}
\end{document}

And the output is :

image

We can notice that the definition of \bitem and \exeritem are totally the same except the label command labelexer and labelenum. However the \exeritem didn't work. But when I wrote the command directly in exer environment (the second environment), it worked. why would that happen?

muzimuzhi commented 2 years ago

This seems to be an X-Y problem. To your original requirement, try this:

\documentclass{article}
\usepackage{enumitem}
\newlist{myenum}{enumerate}{3}
\setlist[myenum,1]{label=(\arabic*)}
\setlist[myenum,2]{label=(\roman*)}

\makeatletter
% #1: label prefix typeset inside \llap
% #2: one-arg styling command
\newcommand{\uselistlabel}[2]{%
  \stepcounter{\@enumctr}%
  \llap{#1}%
  % see https://github.com/jbezos/enumitem/blob/1bdcad0987823b3716c86b126b3863f895ea9c4a/enumitem.sty#L1371
  #2{\@nameuse{label\@enumctr}}%
}
\makeatother

\begin{document}
\begin{myenum}
  \item
  \item[\uselistlabel{*}{\textbf}] \leavevmode
  \begin{myenum}
    \item
    \item[\uselistlabel{\textsuperscript{+}}{\textbf}]
  \end{myenum}
\end{myenum}
\end{document}

image

PS: Personally I recommend always specifying the language of a markdown code block. It makes the code block highlighted hence more readable, see https://github.github.com/gfm/#example-112.

syvshc commented 2 years ago

This seems to be an X-Y problem. To your original requirement,

Thanks for your reply, I found that I can't \ref the \uselistlabeled \item. Sorry for not clearify that at begining

muzimuzhi commented 2 years ago

To the attempt you shown:

Note generally, a patch working with the LaTeX2e itself will not continue to work when a package extending the same area is loaded. There're always some internals changed.

Adapting your attempt,

\documentclass{article}
\usepackage{enumitem}

% https://tex.stackexchange.com/a/52718/180617
\makeatletter
\def\exeritem{%
  \expandafter\let\expandafter\originallabel\csname labelexer\romannumeral\@listdepth\endcsname
  \expandafter\def\csname labelexer\romannumeral\@listdepth\expandafter\endcsname\expandafter{%
    \expandafter\bfseries\expandafter{\originallabel}}%
  \item
  \expandafter\let\csname labelexer\romannumeral\@listdepth\endcsname\originallabel
}
\makeatother

\newlist{exer}{enumerate}{2}
\setlist[exer, 1]{leftmargin=*, label=\arabic*., widest=000, ref=\arabic*}

\begin{document}
\begin{exer}
    \item 
    \exeritem \labelexeri
\end{exer}
\end{document}

Also you may find utility macros from etoolbox helpful in reducing number of \expandafters used:

\usepackage{etoolbox}

% https://tex.stackexchange.com/a/52718/180617
\makeatletter
\def\exeritem{%
  \letcs{\originallabel}{labelexer\romannumeral\@listdepth}%
  % the \edef variant of \@namedef
  \csedef{labelexer\romannumeral\@listdepth}%
    {\noexpand\textbf{\expandonce\originallabel}}%
  \item
  \cslet{labelexer\romannumeral\@listdepth}\originallabel
}
\makeatother
syvshc commented 2 years ago

I found that in enumitem, it uses \enit@depth to control depth

https://github.com/jbezos/enumitem/blob/1bdcad0987823b3716c86b126b3863f895ea9c4a/enumitem.sty#L514

so if I change \@enumdepth in exer to enit@depth, problem solved.

Thanks @muzimuzhi 's trick of etoolbox's macro.

syvshc commented 2 years ago

sorry for reopen this issue, I tested the code below

\documentclass{article}
\usepackage{enumitem}
\usepackage{etoolbox}

% https://tex.stackexchange.com/a/52718/180617
\makeatletter
\def\exeritem{%
  \letcs{\originallabel}{labelexer\romannumeral\enit@depth}%
  % the \edef variant of \@namedef
  \csdef{labelexer\romannumeral\enit@depth}%
    {\textbf{\originallabel}}%
  \item
  \cslet{labelexer\romannumeral\enit@depth}\originallabel
}
\makeatother

\newlist{exer}{enumerate}{2}
\setlist[exer, 1]{leftmargin=*, label=\arabic*., widest=000, ref=\arabic*}

\begin{document}
\begin{exer}
    \item 
    \exeritem \labelexeri
    \item
\end{exer}
\end{document}

image

I found that \csedef with expanding control works the same as \csdef without expanding control, so I want to ask why @muzimuzhi used \csedef?

muzimuzhi commented 2 years ago

I found that \csedef with expanding control works the same as \csdef without expanding control, so I want to ask why @muzimuzhi used \csedef?

I guess it's because in your original example (see snippet below), i thought you wanted to use the replacement text of \originallabel in defining control sequence labelexer\romannumeral\@enumdepth. I spotted the surplus \expandafter just before \originallabel which caused problem, and didn't check if any other \expandafters were all necessary.

  \expandafter\def\csname labelexer\romannumeral\@enumdepth\expandafter\endcsname\expandafter{%
    \expandafter\bfseries\expandafter{\expandafter\originallabel}}%
syvshc commented 2 years ago

I see, thanks