如何创建包含不同类型项目的列表?我正在使用包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
命令也适用于子级别,如上所示。