Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

How can one create a list with different types of items ? I am using the package enumitem, which is great for defining items and referring to them, but it seems to allow only one type of item. I have looked in the definition of \item in latex.ltx, but could not find any useful hint, and in enumitem.sty neither.

More concretely I wish to have items like

   1 ...
 → 2 ...
 ✓ 3 ...

and type

\normalitem ...
\arrowitem ...
\checkeditem ...

Currently, I use \item[\refstepcounter{xi}$\symbol$\arabic{thexi}] Is there a better way to do it ?

share|improve this question
    
As I am too lazy to manage complex macros as those of the great answers (+1), just after \item I would add macros making something like \hspace{-2em}\llap{$\rightarrow$}\hspace{2em}. Simplistic and limited, but simple. :) –  Fran Jan 21 at 7:38
add comment

2 Answers

up vote 19 down vote accepted

Improved version:

The idea is still the same that I used in the first version (see below), but now the process is completely transparent for the final user; in particular, no extra packages are needed (pifont and tikz were only loaded in my example to get fancy symbols) and new item types are now defined simply by using

\newitem{<prefix>}{<symbol>}

where <prefix> is the alphabetic string that will be used to call the new item, and <symbol> is the symbol that will be pre-pended to the label.

\documentclass{article}
\usepackage{pifont}
\usepackage{tikz}

\newcommand\myinfo{%
  \tikz[baseline]\node (info) [anchor=base,shape=circle,draw=orange!20,inner sep=1pt,fill=orange,text=white] {\bfseries\sffamily !};%
}

\makeatletter
\newcommand\newitem[2]{%
  \expandafter\def\csname#1item\endcsname{%
    \expandafter\@inmatherr\csname #1item\endcsname%
    \@ifnextchar[{\csname @#1item\endcsname}{\@noitemargtrue\csname @#1item\endcsname[\@itemlabel]}}%
\expandafter\def\csname @#1item\endcsname[##1]{%
\if@noparitem
\@donoparitem
\else
\if@inlabel
\indent \par
\fi
\ifhmode
\unskip\unskip \par
\fi
\if@newlist
\if@nobreak
\@nbitem
\else
\addpenalty\@beginparpenalty
\addvspace\@topsep
\addvspace{-\parskip}%
\fi
\else
\addpenalty\@itempenalty
\addvspace\itemsep
\fi
\global\@inlabeltrue
\fi
\everypar{%
\@minipagefalse
\global\@newlistfalse
\if@inlabel
\global\@inlabelfalse
{\setbox\z@\lastbox
\ifvoid\z@
\kern-\itemindent
\fi}%
\box\@labels
\penalty\z@
\fi
\if@nobreak
\@nobreakfalse
\clubpenalty \@M
\else
\clubpenalty \@clubpenalty
\everypar{}%
\fi}%
\if@noitemarg
\@noitemargfalse
\if@nmbrlist
\refstepcounter\@listctr
\fi
\fi
\sbox\@tempboxa{\makelabel{#2\kern1pt##1}}%
\global\setbox\@labels\hbox{%
\unhbox\@labels
\hskip \itemindent
\hskip -\labelwidth
\hskip -\labelsep
\ifdim \wd\@tempboxa >\labelwidth
\box\@tempboxa
\else
\hbox to\labelwidth {\unhbox\@tempboxa}%
\fi
\hskip \labelsep}%
\ignorespaces}
}
\makeatother

\newitem{diamond}{\ding{70}}
\newitem{arrow}{$\to$}
\newitem{checked}{\ding{51}}
\newitem{info}{\myinfo}

\begin{document}

\begin{enumerate}
\arrowitem First item.
\item Second item.
\checkeditem Third item.
\item Fourth item.
  \begin{enumerate}
  \item First subitem.
  \arrowitem[($\ast$)] Second subitem.
  \checkeditem Third subitem.
\end{enumerate}
\arrowitem Fifth item.
\item Sixth item.
\infoitem Seventh item.
\checkeditem Eighth item.
\end{enumerate}

\end{document}

enter image description here

This solution has an advantage and it is that it can be used on its own (without the enumitem package), but it is compatible with the use of this package, if one decides to use it, as the following example demonstrates:

\documentclass{article}
\usepackage{pifont}
\usepackage{tikz}
\usepackage{enumitem}

\newcommand\myinfo{%
  \tikz[baseline]\node (info) [anchor=base,shape=circle,draw=orange!20,inner sep=1pt,fill=orange,text=white] {\bfseries\sffamily !};%
}

\makeatletter
\newcommand\newitem[2]{%
  \expandafter\def\csname#1item\endcsname{%
    \expandafter\@inmatherr\csname #1item\endcsname%
    \@ifnextchar[{\csname @#1item\endcsname}{\@noitemargtrue\csname @#1item\endcsname[\@itemlabel]}}%
\expandafter\def\csname @#1item\endcsname[##1]{%
\if@noparitem
\@donoparitem
\else
\if@inlabel
\indent \par
\fi
\ifhmode
\unskip\unskip \par
\fi
\if@newlist
\if@nobreak
\@nbitem
\else
\addpenalty\@beginparpenalty
\addvspace\@topsep
\addvspace{-\parskip}%
\fi
\else
\addpenalty\@itempenalty
\addvspace\itemsep
\fi
\global\@inlabeltrue
\fi
\everypar{%
\@minipagefalse
\global\@newlistfalse
\if@inlabel
\global\@inlabelfalse
{\setbox\z@\lastbox
\ifvoid\z@
\kern-\itemindent
\fi}%
\box\@labels
\penalty\z@
\fi
\if@nobreak
\@nobreakfalse
\clubpenalty \@M
\else
\clubpenalty \@clubpenalty
\everypar{}%
\fi}%
\if@noitemarg
\@noitemargfalse
\if@nmbrlist
\refstepcounter\@listctr
\fi
\fi
\sbox\@tempboxa{\makelabel{#2\kern1pt##1}}%
\global\setbox\@labels\hbox{%
\unhbox\@labels
\hskip \itemindent
\hskip -\labelwidth
\hskip -\labelsep
\ifdim \wd\@tempboxa >\labelwidth
\box\@tempboxa
\else
\hbox to\labelwidth {\unhbox\@tempboxa}%
\fi
\hskip \labelsep}%
\ignorespaces}
}
\makeatother

\newitem{diamond}{\ding{70}}
\newitem{arrow}{$\to$}
\newitem{checked}{\ding{51}}
\newitem{info}{\myinfo}

\setlist[enumerate,1]{label=\roman*.}
\setlist[enumerate,2]{label=(\arabic*)}

\begin{document}

\begin{enumerate}
\arrowitem First item.
\item Second item.
\checkeditem Third item.
\item Fourth item.
  \begin{enumerate}
  \item First subitem.
  \arrowitem[($\ast$)] Second subitem.
  \checkeditem Third subitem.
\end{enumerate}
\arrowitem Fifth item.
\item Sixth item.
\infoitem Seventh item.
\checkeditem Eighth item.
\end{enumerate}

\end{document}

enter image description here

The first (preliminary) solution:

\documentclass{article}
\usepackage{pifont}
\usepackage{xpatch}

\makeatletter
\def\arrowitem{%
\@inmatherr\arrowitem
\@ifnextchar [\@arrowitem{\@noitemargtrue \@arrowitem[\@itemlabel]}}
\let\@arrowitem\@item
\xpatchcmd{\@arrowitem}
  {\makelabel{#1}}
  {\makelabel{$\to$\kern1pt#1}}
  {}
  {}

\def\checkeditem{%
\@inmatherr\checkeditem
\@ifnextchar [\@checkeditem{\@noitemargtrue \@checkeditem[\@itemlabel]}}
\let\@checkeditem\@item
\xpatchcmd{\@checkeditem}
  {\makelabel{#1}}
  {\makelabel{\ding{51}\kern1pt#1}}
  {}
  {}
\makeatother

\begin{document}

\begin{enumerate}
\arrowitem First item.
\item Second item.
\checkeditem Third item.
\item Fourth item.
  \begin{enumerate}
  \item First subitem.
  \arrowitem[($\ast$)] Second subitem.
  \checkeditem Third subitem.
\end{enumerate}
\arrowitem Fifth item.
\item Sixth item.
\item Seventh item.
\checkeditem Eighth item.
\end{enumerate}

\end{document}

enter image description here

The idea is to create copies of the original \item and \@item commands and then patch the copies to include the desired symbol.

(I shamelesly borrowed azetina's \myinfo command from his answer).

share|improve this answer
    
Thanks for this preliminary answer. I'm looking forward to the definitive one. Could we imagine an additional macro (to enumitem for instance) that would create the item in a more comprehensive way like \newitem{listname}{\itemname}{label=$\to$\arabic*.,ref=\arabic*} ? –  V. Rossetto Jan 20 at 16:19
    
@GonzaloMedina Ah sorry, I didn't read the question correctly, +1 b.t.w –  user42341 Jan 20 at 18:32
    
@Adobe No problem. Thanks for the upvote! –  Gonzalo Medina Jan 20 at 18:36
    
Could you elaborate on what each line of the code is doing? I would really like to understand this as it may be applicable else where. –  azetina Jan 20 at 19:36
    
@V.Rossetto I added to my answer an improved version; now you can easily build as many new item types as you like with a simple command \newitem{<prefix>}{<symbol>}, as you requested. –  Gonzalo Medina Jan 20 at 22:21
show 6 more comments

Here is an alternative MWE:

enter image description here

\documentclass[letterpaper]{article}
\usepackage{tikz}
\usepackage{pifont}
\usepackage{enumitem}
\setlist[enumerate]{before=\setupmodenumerate}

\newif\ifmoditem
\newcommand{\setupmodenumerate}{%
  \global\moditemfalse
  \let\origmakelabel\makelabel
  \def\moditem##1{\global\moditemtrue\def\mesymbol{##1}\item}%
  \def\makelabel##1{%
    \origmakelabel{\ifmoditem\llap{\mesymbol\enspace}\fi##1}%
    \global\moditemfalse}%
}
\newcommand{\myinfo}{\tikz[baseline] \node (info) [anchor=base,shape=circle,draw=orange!20,inner sep=1pt,fill=orange,text=white] {\bfseries\sffamily !};}
\begin{document}
\begin{enumerate}
    \item One
    \moditem{$\to$} Two
        \begin{enumerate}
            \item Two A
            \moditem{$\to$}[($\ast$)] Two B
            \item Two C 
        \end{enumerate}
    \moditem{\ding{51}} Three
    \moditem{\myinfo} Four
\end{enumerate}
\end{document}

The convenience of the command defined above is that you only need one and its argument carries the special items desired. I added an example with an image using TikZ, just for fun. The \moditem command also works with sublevels as illustrated above.

Note: I had asked something similar: Add an asterisk left of an enumerate and the solution given by @egreg here.

share|improve this answer
    
Thanks for this nice answer. I did checked if the question had been already asked, probably with bad keywords. –  V. Rossetto Jan 20 at 16:38
    
@V.Rossetto Its ok. Thumbs up because you got a new answer in a different approach. So, everyone can learn the different possibilities. –  azetina Jan 20 at 16:39
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.