![如何创建不受任何环境约束的更好的伪枚举列表](https://linux22.com/image/294668/%E5%A6%82%E4%BD%95%E5%88%9B%E5%BB%BA%E4%B8%8D%E5%8F%97%E4%BB%BB%E4%BD%95%E7%8E%AF%E5%A2%83%E7%BA%A6%E6%9D%9F%E7%9A%84%E6%9B%B4%E5%A5%BD%E7%9A%84%E4%BC%AA%E6%9E%9A%E4%B8%BE%E5%88%97%E8%A1%A8.png)
我有一份较长的文档,不是用 LaTeX 编写的,但标记结构很容易识别。我可以编写一个 Perl 脚本将大部分文档翻译成 LaTeX。
然而,列表会带来一些麻烦,因为并不总是清楚这样的环境应该开始或结束。幸运的是,文档中出现的绝大多数(如果不是全部)列表项都由单个段落组成。所以,我想我可以编写一个简单的宏来模拟列表项的外观。
这是我第一次运行时产生的代码。
\documentclass{article}
\makeatletter
\newcounter{aelistcnt}
\newcommand\alist{\ae@list}
\def\ae@list{%%
\refstepcounter{aelistcnt}%%
\par
\vskip 2ex plus 0pt minus 2ex
\let\ae@par\par
\let\par\ae@@par
\parshape 1 2em \dimexpr\columnwidth-4em\relax
\noindent
\makebox[0pt][r]{(\arabic{aelistcnt})\hspace{0.5em}}%%
}
\def\ae@@par{%%
\ae@par
\vskip 1ex plus 0pt minus 1ex
\let\par\ae@par}
\makeatother
\def\aevbox{%%
\raisebox{0pt}[0pt][0pt]{\makebox[0pt]{\rule{1pt}{4ex}}}}
\usepackage{lipsum}
\begin{document}
\lipsum[13]
\alist \aevbox Pr
\alist b
\alist \lipsum[11]
\alist \aevbox\lipsum[39]
\alist \lipsum[65]
\lipsum[23]
\alist\lipsum[11]
\end{document}
问题在于列表如何与周围文档交互。特别是,此列表项之间是否有段落分隔符伪列表,我希望在列表前面、列表项之间以及最后一项之后保持一致的间距。我使用胶水(我不太熟悉的东西)来尝试实现所需的效果。上面的效果还不错,但我希望能够做得更好。(目的是\aevbox
帮助我看到差异。)
另一种方法是完全不用胶水。相反,我改变了 的定义\par
。
\documentclass{article}
\makeatletter
\newif\if@aelist
\newif\if@aedoublepar
\newcounter{aelistcnt}
\newcommand\alist{\ae@list}
\def\ae@list{%%
\refstepcounter{aelistcnt}%%
\ae@par@test
\parshape 1 2em \dimexpr\columnwidth-4em\relax
\noindent
\makebox[0pt][r]{(\arabic{aelistcnt})\hspace{0.5em}}%%
}
\def\ae@par@test{%%
\typeout{===>\theaelistcnt}%%
\if@aelist
\ae@@@par
\let\par\ae@@par
\typeout{\space\space\space\space:(TRUE):\space\space PREVIOUSLY LIST}%%
\else
\typeout{\space\space\space\space:(FALSE):\space NEW LIST}%%
\vspace{2ex}%%
\par
\let\ae@par\par
\let\par\ae@@par
\fi
\@aelisttrue
}
\def\ae@@par{%%
\typeout{\space\space\space\space:ae@@par:}%%
\ae@par
\vspace{2ex}%%
\@aedoublepartrue
\let\par\ae@@@@par
}
\def\ae@@@par{%%
\typeout{\space\space\space\space:ae[3@]par:}%%
\if@aedoublepar
\@aedoubleparfalse
\else
\vspace{2ex}%%
\ae@par
\fi
}
\def\ae@@@@par{%%
\typeout{\space\space\space\space:ae[4@]par:BACK TO NORMAL PAR}%%
\let\par\ae@par
\@aelistfalse
\@aedoubleparfalse
\par
}
\makeatother
\usepackage{lipsum}
\begin{document}
\lipsum[13]
\alist a
\alist b
\alist c
\alist d
\alist \lipsum[11]
\alist \lipsum[39]
\alist \lipsum[65]
\lipsum[23]
\alist\lipsum[11]
\lipsum[23]
\end{document}
这似乎做得更好。但我仍然不完全满意。似乎没有很好的方法来清理\par
早期的定义,我担心其他一些 LaTeX 代码可能会进来,并无意中用仅部分重新实现的\par
命令造成混乱。(这个练习的一个好处是,我看到了一个环境对包含和打扫干净代码,以免事情变得失控。)
因此,我感兴趣的是有关更好地处理此问题的建议,而无需实际手动创建适当的列表环境。
答案1
我相信,你想要的是\addvspace
。 的问题\par
可以通过一个团队来解决。
\documentclass{article}
\makeatletter
\newcounter{aelistcnt}
\newcommand\alist{\ae@list}
\def\ae@list{%%
\refstepcounter{aelistcnt}%%
\par
\addvspace{2ex plus 0pt minus 2ex}%
\begingroup
\let\ae@@par\par
\def\par{\ae@par}%
\parshape 1 2em \dimexpr\columnwidth-4em\relax
\noindent
\makebox[0pt][r]{(\arabic{aelistcnt})\hspace{0.5em}}%%
}
\def\ae@par{%%
\ae@@par\endgroup
\addvspace{1ex plus 0pt minus 1ex}%
}
\makeatother
\def\aevbox{%%
\raisebox{0pt}[0pt][0pt]{\makebox[0pt]{\rule{1pt}{4ex}}}}
\usepackage{lipsum}
\begin{document}
\lipsum[13]
\alist \aevbox Pr
\alist b
\alist \lipsum[11]
\alist \aevbox\lipsum[39]
\alist \lipsum[65]
\lipsum[23]
\alist\lipsum[11]
\end{document}