![如何自动按照最长的标签对齐项目标签?](https://linux22.com/image/309031/%E5%A6%82%E4%BD%95%E8%87%AA%E5%8A%A8%E6%8C%89%E7%85%A7%E6%9C%80%E9%95%BF%E7%9A%84%E6%A0%87%E7%AD%BE%E5%AF%B9%E9%BD%90%E9%A1%B9%E7%9B%AE%E6%A0%87%E7%AD%BE%EF%BC%9F.png)
报仇的时候到了!我已经与这个问题斗争了一段时间,即根据最长的标签自动对齐项目(见下面的前两个示例)。最长标签的左侧与段落的开头相匹配(\parindent
)。这种情况并不常见,但在我润色的文档中看起来不错。作者使用它来缩写假设、条件、属性、定理,随便什么都可以。
常见的选项是\begin{itemize}[Example a)]
通过enumerate
包。或者借助\leftskip
维度直接写入环境中。
在生产中我没有使用 LuaTeX(回调),因为我无法对其进行编程。我可能可以将该环境转换为表格,但我预计会遇到很多麻烦。我不知道environ
当时包装不好,因此我用了一把重锤:
- 在 Lua 级别,我
itemize
从 TeX 文件(正则表达式)中逐个选择环境。 - 然后我从命令中选择所有标签
\item[label]
,并使用一系列\measureme{label}
命令(Lua)创建一个新的 TeX 文件。 - 我通过外部 TeX 文件(
\input
)加载该文件并找到最长的标签,然后通过命令将该维度存储\message
在日志文件中。 - 我用 Lua 解析该日志文件,并在第一次出现之前将其添加
\leftskip
到该环境中。itemize
\item[]
虽然速度很慢,效率很低,但确实有效。我关心的是第一级itemize
,而不是更高级别,因为在我润色的文档中,它们很少见(换句话说,不需要\leftskip
在那里添加)。
此过程不能itemize
很好地处理嵌套,但我可以通过itemize
在步骤 1 处理平衡itemize
选择后删除内部环境来改进它(例如通过使用 LPeg 或用单个未使用的字符替换\begin{itemize}
和,例如和,我第一次成功尝试了\end{itemize}
\002
\003
这里)。完成此步骤后,只有\item
实际级别的 sitemize
保持不变以供进一步分析。这是我的待办事项。
我在想是否有更简单的方法来处理这种对齐。这是我在environ
itemize
包。这个想法是处理两次的内容:
- 在第一次运行期间,算法应该测量标签并挑选最长的标签(在框中进行虚拟排版)。
- 在第二次运行期间,算法应该用来
\leftskip
改变环境(真实排版)。
itemize
我附上了一个最小的工作示例。它很适合我。它处理示例中所示的第一级。但是如果我们尝试处理嵌套环境,我们会收到错误消息。请注释掉第一个\end{document}
命令以查看最小的非工作示例(我打开\nonstopmode
以获取一些 PDF)。我原本想添加\ifnum
和级别itemize
,但我还没有尝试过。我们运行任何 LaTeX 引擎,例如lualatex mal-example.tex
。
处理这种对齐方式的方法可能与我的方法完全不同。有吗?
% *latex mal-example.tex
\documentclass[a4paper]{article}
\pagestyle{empty}
\usepackage{environ}
\let\olditemize=\itemize % original \begin{itemize}
\let\endolditemize=\enditemize % original \end{itemize}
\let\olditem=\item % original \item command
\newdimen\measureme % for storing maximum width of item labels
\RenewEnviron{itemize}{% redefinition of itemize environment
\measureme=0mm% set maximum width to zero, initial value
\def\item[##1]{\setbox0=\hbox{##1}% redefinition of \item
\ifdim\wd0>\measureme % getting the maximum value
\global\measureme=\wd0 % store the width maximum
\fi % End of \ifdim...
}% End of redefinition of \item.
\setbox1=\hbox{\BODY}% measure labels virtually
\setbox1=\hbox{\enspace}% measuring space
\advance\measureme by -\wd1\relax % width of space
\let\item=\olditem% Back to common \item.
\begin{olditemize}% common itemize + \leftskip - width of space
\leftskip=\measureme % aproach I use
\BODY % common typesetting of \items...
\end{olditemize}
}% End of redefinition of the itemize environment.
\begin{document}
Text before. Text before. Text before. Text before. Text before. Text before. Text before. Text before. Text before. Text before. Text before. Text before. Text before. Text before.
\begin{itemize}
\item[(malabc)] First item.
\item[(longer one)] Second item.
\item[(3rd)] Third item.
\end{itemize}
Text in the middle. Text in the middle. Text in the middle. Text in the middle. Text in the middle. Text in the middle. Text in the middle.
\begin{itemize}
\item[(cond1)] First item.
\item[(cond11)] Second item.
\item[(cond111)] Third item.
\end{itemize}
\end{document} % to be commented out
Additional text. Additional text. Additional text. Additional text. Additional text. Additional text. Additional text. Additional text. Additional text. Additional text.
\nonstopmode
\begin{itemize}
\item[(a)] First item.
\item[(b)] Second item.
\begin{itemize}
\item[(cba)] First item.
\item[(abc)] Second item.
\item[(cab)] Third item.
\end{itemize}
\item[(c)] Third item.
\end{itemize}
\end{document}