我读过很多次,你不应该重新发明轮子,但有时你必须这样做。我正在尝试创建一个基于LaTeX 提供的基本环境的enumerate
样式环境,而不使用mylist
list
enumitem
环境,而不使用该包。我可以处理基本参数,但是,我无法理解层次的嵌套。
通过比较,我想要得到类似的东西:
我的代码如下:
\documentclass{article}
\usepackage{xparse}
\usepackage{enumitem}
\setlist[enumerate,1]{label= \arabic*., left=0pt, labelsep=5pt, itemsep=4pt, partopsep=2pt}
\setlist[enumerate,2]{leftmargin=16pt, itemsep=0pt, nosep, label=\Alph*)}
\setlength{\parindent}{0pt}
\ExplSyntaxOn
\newcounter{mycount}
\cs_new_eq:NN \__mylist_start_list:nn \list
\cs_new_eq:NN \__mylist_stop_list: \endlist
\tl_new:N \l_mylist_label_tl
\keys_define:nn { mylist }
{
label .code:n = \tl_set:Nn \l_tmpa_tl {#1}
\tl_put_right:Nx \l_mylist_label_tl
{ \exp_not:V \l_tmpa_tl },
label .initial:n = \arabic{mycount}.,
itemsep .dim_set:N = \l_mylist_itemsep_dim,
itemsep .initial:n = 0pt,
itemindent .dim_set:N = \l_mylist_itemindent_dim,
itemindent .initial:n = 0in,
labelsep .dim_set:N = \l_mylist_labelsep_dim,
labelsep .initial:n = 0.5em,
leftmargin .dim_set:N = \l_mylist_leftmargin_dim,
leftmargin .initial:n = 0in,
rightmargin .dim_set:N = \l_mylist_rightmargin_dim,
rightmargin .initial:n = 0pt,
labelwidth .dim_set:N = \l_mylist_labelwidth_dim,
labelwidth .initial:n = \l_mylist_leftmargin_dim - \l_mylist_labelsep_dim,
topsep .dim_set:N = \l_mylist_topsep_dim,
topsep .initial:n = -0.3ex,
parsep .dim_set:N = \l_mylist_parsep_dim,
parsep .initial:n = 0pt,
partopsep .dim_set:N = \l_mylist_partopsep_dim,
partopsep .initial:n = 2pt,
listparindent .dim_set:N = \l_mylist_listparindent_dim,
listparindent .initial:n = 0.5in,
}
\NewDocumentEnvironment{mylist}{ O{} }
{
\IfNoValueF{#1}{ \keys_set:nn { mylist } {#1} }
\__mylist_start_list:nn
{ \tl_use:N \l_mylist_label_tl }
{
\usecounter{mycount}
\dim_set:Nn \itemsep { \l_mylist_itemsep_dim }
\dim_set:Nn \itemindent { \l_mylist_itemindent_dim }
\dim_set:Nn \labelsep { \l_mylist_labelsep_dim }
\dim_set:Nn \labelwidth { \l_mylist_labelwidth_dim }
\dim_set:Nn \leftmargin { \l_mylist_leftmargin_dim }
\dim_set:Nn \rightmargin { \l_mylist_rightmargin_dim }
\dim_set:Nn \topsep { \l_mylist_topsep_dim }
\dim_set:Nn \parsep { \l_mylist_parsep_dim }
\dim_set:Nn \partopsep { \l_mylist_partopsep_dim }
\dim_set:Nn \listparindent { \l_mylist_listparindent_dim }
}
}
{
\__mylist_stop_list:
}
\ExplSyntaxOff
\begin{document}
XXXX
\hrule
\begin{enumerate}
\item Using enumerate redefined by enumitem pkg
\begin{enumerate}
\item value second level
\item value second level
\item value second level
\end{enumerate}
\end{enumerate}
\hrule
YYY
\begin{mylist}[leftmargin=0cm]
\item Using mylist environment nested here:
\begin{mylist}
\item value second level
\item value second level
\item value second level
\end{mylist}
\end{mylist}
\hrule
\end{document}
我不知道如何创建和访问枚举的不同级别的嵌套。
第一次尝试:添加计数器并检测嵌套级别。
\documentclass{article}
\usepackage{xparse}
\usepackage{enumitem}
\setlist[enumerate,1]{label= \arabic*., left=0pt, labelsep=5pt, itemsep=4pt, partopsep=2pt}
\setlist[enumerate,2]{leftmargin=16pt, itemsep=0pt, nosep, label=\Alph*)}
\setlength{\parindent}{0pt}
\ExplSyntaxOn
\newcounter{mycounti}
\newcounter{mycountii}
\newcounter{mycountiii}
\int_new:N \l_mylist_level_int
\cs_new_eq:NN \__mylist_start_list:nn \list
\cs_new_eq:NN \__mylist_stop_list: \endlist
\tl_new:N \l_mylist_label_i_tl
\tl_new:N \l_mylist_label_ii_tl
\tl_new:N \l_mylist_label_iii_tl
% topsep partopsep parsep itemsep
\cs_new_protected:Npn \__mylist_vspace_keys:nnnnn #1#2#3#4#5
{
\keys_define:nn { mylist/level-#1 }
{
topsep .dim_set:c = { l_mylist_topsep_#1_dim },
topsep .initial:n = {#2},
partopsep .dim_set:c = { l_mylist_partopsep_#1_dim },
partopsep .initial:n = {#3},
parsep .dim_set:c = { l_mylist_parsep_#1_dim },
parsep .initial:n = {#4},
itemsep .dim_set:c = { l_mylist_itemsep_#1_dim },
itemsep .initial:n = {#5},
}
}
\__mylist_vspace_keys:nnnnn { i }{ 0cm }{ 0cm }{ 0cm }{ 0mm }
\__mylist_vspace_keys:nnnnn { ii }{ 0cm }{ 0cm }{ 0cm }{ 0mm }
% leftmargin rightmargin listparindent labelwidth labelsep itemindent
\cs_new_protected:Npn \__mylist_hspace_keys:nnnnnnn #1#2#3#4#5#6#7
{
\keys_define:nn { mylist/level-#1 }
{
leftmargin .dim_set:c = { l_mylist_leftmargin_#1_dim },
leftmargin .initial:n = {#2},
rightmargin .dim_set:c = { l_mylist_rightmargin_#1_dim },
rightmargin .initial:n = {#3},
listparindent .dim_set:c = { l_mylist_listparindent_#1_dim },
listparindent .initial:n = {#4},
labelwidth .dim_set:c = { l_mylist_labelwidth_#1_dim },
labelwidth .initial:n = {#5},
labelsep .dim_set:c = { l_mylist_labelsep_#1_dim },
labelsep .initial:n = {#6},
itemindent .dim_set:c = { l_mylist_itemindent_#1_dim },
itemindent .initial:n = {#7},
}
}
\__mylist_hspace_keys:nnnnnnn {i }{ 0cm }{ 0cm }{ 0cm }{ 0.5in }{ 0.5em }{ 0cm }
\__mylist_hspace_keys:nnnnnnn {ii}{ 1cm }{ 0cm }{ 16pt }{ 0cm }{ 0.25cm }{ 0cm }
\cs_new_protected:Npn \__mylist_level_i_defns:
{
\usecounter{mycounti}
\dim_set:Nn \itemsep { \l_mylist_itemsep_i_dim }
\dim_set:Nn \itemindent { \l_mylist_itemindent_i_dim }
\dim_set:Nn \labelsep { \l_mylist_labelsep_i_dim }
\dim_set:Nn \labelwidth { \l_mylist_labelwidth_i_dim }
\dim_set:Nn \leftmargin { \l_mylist_leftmargin_i_dim }
\dim_set:Nn \rightmargin { \l_mylist_rightmargin_i_dim }
\dim_set:Nn \topsep { \l_mylist_topsep_i_dim }
\dim_set:Nn \parsep { \l_mylist_parsep_i_dim }
\dim_set:Nn \partopsep { \l_mylist_partopsep_i_dim }
\dim_set:Nn \listparindent { \l_mylist_listparindent_i_dim }
}
\cs_new_protected:Npn \__mylist_level_ii_defns:
{
\usecounter{mycountii}
\dim_set:Nn \itemsep { \l_mylist_itemsep_ii_dim }
\dim_set:Nn \itemindent { \l_mylist_itemindent_ii_dim }
\dim_set:Nn \labelsep { \l_mylist_labelsep_ii_dim }
\dim_set:Nn \labelwidth { \l_mylist_labelwidth_ii_dim }
\dim_set:Nn \leftmargin { \l_mylist_leftmargin_ii_dim }
\dim_set:Nn \rightmargin { \l_mylist_rightmargin_ii_dim }
\dim_set:Nn \topsep { \l_mylist_topsep_ii_dim }
\dim_set:Nn \parsep { \l_mylist_parsep_ii_dim }
\dim_set:Nn \partopsep { \l_mylist_partopsep_ii_dim }
\dim_set:Nn \listparindent { \l_mylist_listparindent_ii_dim }
}
% label
\keys_define:nn { mylist/level-i }
{
label .code:n = \tl_set:Nn \l_tmpa_tl {#1}
\tl_put_right:Nx \l_mylist_label_i_tl { \exp_not:V \l_tmpa_tl },
label .initial:n = \arabic{mycounti}.,
}
\keys_define:nn { mylist/level-ii }
{
label .code:n = \tl_set:Nn \l_tmpa_tl {#1}
\tl_put_right:Nx \l_mylist_label_ii_tl { \exp_not:V \l_tmpa_tl },
label .initial:n = \Alph{mycountii}),
}
\NewDocumentEnvironment{mylist}{ O{} }
{
\int_incr:N \l_mylist_level_int
\IfNoValueF{#1}
{
\int_case:nn { \l_mylist_level_int }
{
{1} { \keys_set:nn { mylist / level-i } {#1} }
{2} { \keys_set:nn { mylist / level-ii } {#1} }
}
}
\__mylist_start_list:nn
{
\int_case:nn { \l_mylist_level_int }
{
{1} { \tl_use:N \l_mylist_label_i_tl }
{2} { \tl_use:N \l_mylist_label_ii_tl }
}
}
{
\def\makelabel##1{\hss\llap{##1}} % ugly :(
\use:c { __mylist_level_ \int_to_roman:n { \l_mylist_level_int } _defns: }
}
}
{ \__mylist_stop_list: }
\ExplSyntaxOff
\begin{document}
XXXX
\hrule
\begin{enumerate}
\item Using enumerate redefined by enumitem pkg
\begin{enumerate}
\item value second level
\item value second level
\item value second level
\end{enumerate}
\end{enumerate}
\hrule
YYY
\begin{mylist}
\item Using mylist environment nested here:
\begin{mylist}
\item value second level
\item value second level
\item value second level
\end{mylist}
\end{mylist}
\hrule
\end{document}
第二次尝试:现在更接近我想要的并且具有更明确的水平。
\documentclass{article}
\usepackage{xparse}
\usepackage{enumitem}
\setlist[enumerate,1]{label= \arabic*., left=0pt, labelsep=5pt, itemsep=4pt, partopsep=2pt}
\setlist[enumerate,2]{leftmargin=16pt, itemsep=0pt, nosep, label=\Alph*)}
\setlength{\parindent}{0pt}
\ExplSyntaxOn
\newcounter{mycounti}
\newcounter{mycountii}
\newcounter{mycountiii}
\int_new:N \l_mylist_level_int
\cs_new_eq:NN \__mylist_start_list:nn \list
\cs_new_eq:NN \__mylist_stop_list: \endlist
\tl_new:N \l_mylist_label_i_tl
\tl_new:N \l_mylist_label_ii_tl
\tl_new:N \l_mylist_label_iii_tl
% topsep partopsep parsep itemsep
\cs_new_protected:Npn \__mylist_vspace_keys:nnnnn #1#2#3#4#5
{
\keys_define:nn { mylist / level-#1 }
{
topsep .dim_set:c = { l_mylist_topsep_#1_dim },
topsep .initial:n = {#2},
partopsep .dim_set:c = { l_mylist_partopsep_#1_dim },
partopsep .initial:n = {#3},
parsep .dim_set:c = { l_mylist_parsep_#1_dim },
parsep .initial:n = {#4},
itemsep .dim_set:c = { l_mylist_itemsep_#1_dim },
itemsep .initial:n = {#5},
}
}
\__mylist_vspace_keys:nnnnn { i }{ 0cm }{ 0cm }{ 0cm }{ 0mm }
\__mylist_vspace_keys:nnnnn { ii }{ 0cm }{ 0cm }{ 0cm }{ 0mm }
\__mylist_vspace_keys:nnnnn { iii }{ 0cm }{ 0cm }{ 0cm }{ 0mm }
% rightmargin listparindent itemindent labelwidth labelsep (no leftmargin here)
\cs_new_protected:Npn \__mylist_hspace_keys:nnnnnn #1#2#3#4#5#6%#7
{
\keys_define:nn { mylist / level-#1 }
{
rightmargin .dim_set:c = { l_mylist_rightmargin_#1_dim },
rightmargin .initial:n = {#2},
listparindent .dim_set:c = { l_mylist_listparindent_#1_dim },
listparindent .initial:n = {#3},
itemindent .dim_set:c = { l_mylist_itemindent_#1_dim },
itemindent .initial:n = {#4},
labelwidth .dim_set:c = { l_mylist_labelwidth_#1_dim },
labelwidth .initial:n = {#5},
labelsep .dim_set:c = { l_mylist_labelsep_#1_dim },
labelsep .initial:n = {#6},
%leftmargin .dim_set:c = { l_mylist_leftmargin_#1_dim },
%leftmargin .initial:n = {#7},
}
}
\__mylist_hspace_keys:nnnnnn { i }{ 0cm }{ 0cm }{ 0cm }{ 1.25em }{ 0.50em }%{ 1.75em }
\__mylist_hspace_keys:nnnnnn { ii }{ 0cm }{ 0cm }{ 0cm }{ 1.25em }{ 0.50em }%{ 1.75em }
\__mylist_hspace_keys:nnnnnn { iii }{ 0cm }{ 0cm }{ 0cm }{ 1.25em }{ 0.50em }%{ 1.75em }
\cs_new_protected:Npn \__mylist_level_i_defns:
{
\usecounter{mycounti}
\dim_set:Nn \itemsep { \l_mylist_itemsep_i_dim }
\dim_set:Nn \itemindent { \l_mylist_itemindent_i_dim }
\dim_set:Nn \labelsep { \l_mylist_labelsep_i_dim }
\dim_set:Nn \labelwidth { \l_mylist_labelwidth_i_dim }
\dim_set:Nn \leftmargin { \l_mylist_leftmargin_i_dim }
\dim_set:Nn \rightmargin { \l_mylist_rightmargin_i_dim }
\dim_set:Nn \topsep { \l_mylist_topsep_i_dim }
\dim_set:Nn \parsep { \l_mylist_parsep_i_dim }
\dim_set:Nn \partopsep { \l_mylist_partopsep_i_dim }
\dim_set:Nn \listparindent { \l_mylist_listparindent_i_dim }
}
\cs_new_protected:Npn \__mylist_level_ii_defns:
{
\usecounter{mycountii}
\dim_set:Nn \itemsep { \l_mylist_itemsep_ii_dim }
\dim_set:Nn \itemindent { \l_mylist_itemindent_ii_dim }
\dim_set:Nn \labelsep { \l_mylist_labelsep_ii_dim }
\dim_set:Nn \labelwidth { \l_mylist_labelwidth_ii_dim }
\dim_set:Nn \leftmargin { \l_mylist_leftmargin_ii_dim }
\dim_set:Nn \rightmargin { \l_mylist_rightmargin_ii_dim }
\dim_set:Nn \topsep { \l_mylist_topsep_ii_dim }
\dim_set:Nn \parsep { \l_mylist_parsep_ii_dim }
\dim_set:Nn \partopsep { \l_mylist_partopsep_ii_dim }
\dim_set:Nn \listparindent { \l_mylist_listparindent_ii_dim }
}
\cs_new_protected:Npn \__mylist_level_iii_defns:
{
\usecounter{mycountiii}
\dim_set:Nn \itemsep { \l_mylist_itemsep_iii_dim }
\dim_set:Nn \itemindent { \l_mylist_itemindent_iii_dim }
\dim_set:Nn \labelsep { \l_mylist_labelsep_iii_dim }
\dim_set:Nn \labelwidth { \l_mylist_labelwidth_iii_dim }
\dim_set:Nn \leftmargin { \l_mylist_leftmargin_iii_dim }
\dim_set:Nn \rightmargin { \l_mylist_rightmargin_iii_dim }
\dim_set:Nn \topsep { \l_mylist_topsep_iii_dim }
\dim_set:Nn \parsep { \l_mylist_parsep_iii_dim }
\dim_set:Nn \partopsep { \l_mylist_partopsep_iii_dim }
\dim_set:Nn \listparindent { \l_mylist_listparindent_iii_dim }
}
% Set label and leftmargin
\keys_define:nn { mylist / level-i }
{
label .code:n = \tl_set:Nn \l_tmpa_tl {#1}
\tl_put_right:Nx \l_mylist_label_i_tl { \exp_not:V \l_tmpa_tl },
label .initial:n = \arabic{mycounti}.,
leftmargin .dim_set:c = { l_mylist_leftmargin_i_dim },
leftmargin .initial:n = {1.75em},
}
\keys_define:nn { mylist / level-ii }
{
label .code:n = \tl_set:Nn \l_tmpa_tl {#1}
\tl_put_right:Nx \l_mylist_label_ii_tl { \exp_not:V \l_tmpa_tl },
label .initial:n = \Alph{mycountii}),
leftmargin .dim_set:c = { l_mylist_leftmargin_ii_dim },
leftmargin .initial:n = {1.75em},
}
\keys_define:nn { mylist / level-iii }
{
label .code:n = \tl_set:Nn \l_tmpa_tl {#1}
\tl_put_right:Nx \l_mylist_label_iii_tl { \exp_not:V \l_tmpa_tl },
label .initial:n = \roman{mycountiii}.,
leftmargin .dim_set:c = { l_mylist_leftmargin_iii_dim },
leftmargin .initial:n = {1.75em},
}
\NewDocumentEnvironment{mylist}{ O{} }
{
\int_incr:N \l_mylist_level_int
\IfNoValueF{#1}
{
\int_case:nn { \l_mylist_level_int }
{
{1} { \keys_set:nn { mylist / level-i } {#1} }
{2} { \keys_set:nn { mylist / level-ii } {#1} }
{3} { \keys_set:nn { mylist / level-iii } {#1} }
}
}
\__mylist_start_list:nn
{
\int_case:nn { \l_mylist_level_int }
{
{1} { \tl_use:N \l_mylist_label_i_tl }
{2} { \tl_use:N \l_mylist_label_ii_tl }
{3} { \tl_use:N \l_mylist_label_iii_tl }
}
}
{
\use:c { __mylist_level_ \int_to_roman:n { \l_mylist_level_int } _defns: }
}
}
{ \__mylist_stop_list: }
\ExplSyntaxOff
\begin{document}
XXXX
\hrule
\begin{enumerate}
\item Using enumerate redefined by enumitem pkg
\begin{enumerate}
\item value second level
\item value second level
\item value second level
\end{enumerate}
\end{enumerate}
\hrule
YYY
\begin{mylist}[itemsep=4pt, parsep=2pt]
\item Using mylist environment nested here:
\begin{mylist}
\item value second level
\item value second level
\item value second level
\end{mylist}
\end{mylist}
\hrule
\end{document}
我无法使用与 中相同的值,enumitem
并且 的使用leftmargin
是一个问题,但它非常接近我想要的。我不知道代码是否完全正确,但它是有用的。