列出多种类型的项目

列出多种类型的项目

如何创建包含不同类型项目的列表?我正在使用包enumitem,它非常适合定义项目并引用它们,但它似乎只允许一种类型的项目。我查看了\item中的定义latex.ltx,但找不到任何有用的提示,也没有找到enumitem.sty

更具体地说,我希望有这样的物品

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

并输入

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

目前,我使用\item[\refstepcounter{xi}$\symbol$\arabic{thexi}] 有没有更好的方法来做到这一点?

答案1

改良版:

这个想法仍然和我在第一个版本中使用的一样(见下文),但现在这个过程对最终用户来说是完全透明的;特别是,不需要额外的包(在我的例子中pifont只是tikz为了得到花哨的符号而加载的),现在只需使用

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

其中,<prefix>是用于调用新项目的字母字符串,<symbol>是将添加到标签前面的符号。

\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}

在此处输入图片描述

该解决方案有一个优点,那就是它可以单独使用(无需包enumitem),但如果决定使用它,它与该包的使用兼容,如以下示例所示:

\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}

在此处输入图片描述

第一个(初步)解决方案:

\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}

在此处输入图片描述

其想法是创建原始命令的副本\item\@item然后修补副本以包含所需的符号。

(我厚颜无耻地借用阿泽蒂纳命令\myinfo来自他的回答)。

答案2

以下是另一种 MWE:

在此处输入图片描述

\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}

上面定义的命令的便利之处在于您只需要一个命令,并且它的参数包含所需的特殊项目。我添加了一个使用 TikZ 的图像示例,只是为了好玩。该\moditem命令也适用于子级别,如上所示。

注意:我曾经问过类似的问题: 在枚举左侧添加星号以及@egreg 给出的解决方案这里

相关内容