2

Similarly to this question, I would like the optional argument of the \item command to print the number of points. Since I don't want to define a new list environment or a custom \item command I tried the following code (inspired by this answer):

\documentclass{article}

\usepackage[shortlabels]{enumitem}
\usepackage{etoolbox,xparse}

\AtBeginEnvironment{enumerate}{\let\olditem\item%
      \RenewDocumentCommand{\item}{o}{%
      \IfValueTF{#1}{#1 points}\olditem}}

\begin{document}

\begin{enumerate}[1)]
  \item This is some item
  \item[10] This item is worth something
  \item Another item
\end{enumerate}

\end{document}

However this doesn't work since it gives the result seen in the image. I'm obviously doing something (or several things wrong). Thanks in advance for the help.

BONUS: Ideally the solution should work with various enumerate levels (i.e nested environments).

enter image description here

petobens
  • 3,306
  • You need something like \IfValueTF{#1}{\olditem[#1 points]}\olditem – Gonzalo Medina Oct 26 '15 at 22:38
  • Where and how you want the number of points to be printed? – egreg Oct 26 '15 at 23:03
  • Hi @egreg. I would like the points to be printed likes this "1. [10 points] First item" i. e after the enumerate counter and before the item text. – petobens Oct 26 '15 at 23:06
  • 1
    @petobens And isn't it simpler to input \item\points{10} First item where you define \newcommand{\points}[1]{[#1 points]}? – egreg Oct 26 '15 at 23:25
  • @GonzaloMedina can you provide a complete answer? Your suggestions doesn't seem to work as expected. – petobens Oct 27 '15 at 02:18
  • @egreg it is simpler but since I never use the optional argument to the \item command I thought that maybe I could redefine it and finally use it. – petobens Oct 27 '15 at 02:19
  • 1
    That doesn't make sense. You won't finally be using it. You'll be using a different command which it would be better to treat to a name of its own. You can easily make this work for the simple case, but it breaks nested lists immediately because, as defined, you end up a definition in terms of itself. (Because at the first sub-list, \olditem is defined to the current, redefined \item and then that is redefined in terms of \olditem which is defined in terms of.... Of course, it can be done. But it cannot possibly be worth doing. It will also make your code less readable and less flexible. – cfr Oct 27 '15 at 03:16
  • You need to explain how it should work still. Try removing your redefinition and just write \item[10 points]. You will see output different than what you are probably hoping for. If that is true, you'll need to think pretty carefully about many list-related spacing issues before coming up with a solution that will work correctly in nested lists. I also have to concur that a separate macro definition is the way to go. – jon Oct 27 '15 at 03:30

1 Answers1

1

I'm not sure about the advantage of this method over a simpler input such as

\item\points{10}

but here it is. It's a bad idea to modify the stock enumerate environment, even if the document only uses it for the purpose of writing assignment texts, so I define a new environment based on enumitem features, so you can further customize it with an optional argument. Also it's better to define outside the environment the macro that replaces \item.

\documentclass{article}

\usepackage{enumitem}
\usepackage{xparse}

\let\latexitem\item
\NewDocumentCommand{\pointitem}{o}{%
  \latexitem
  \IfValueT{#1}{\everypar=\expandafter{\the\everypar\formatpoints{#1}}}%
}
\NewDocumentCommand{\formatpoints}{m}{[#1 points] }
\NewDocumentEnvironment{assignments}{O{}}
 {\begin{enumerate}[label=\arabic*),ref=\arabic*,#1]\let\item\pointitem}
 {\end{enumerate}}

\begin{document}

\begin{assignments}

\item This is some item

\item[10] This item is worth something

\item Another item

\end{assignments}

\end{document}

Using \everypar is for allowing usage of \label in the same way it can be used with the standard \item.

enter image description here

egreg
  • 1,121,712