为了方便起见(也为了加深我的 LaTeX 知识),我尝试以一种简单的方式定义一个列表:\mylist(First, Second, Third, ...)
用其他东西替换逗号(在本例中是\texttt{,}
有效的,但我很难转换最后的省略号。当任何部分有一个点时,我的解决方案就会失败。
这是我的 MWE:
\documentclass[a4paper]{article}
\makeatletter
\def\mylist (#1){%
\begingroup%
\begingroup\lccode`~=`, \lowercase{\endgroup\def~}{\texttt{,} }%
\begingroup\lccode`~=`. \lowercase{\endgroup\def~~~}{\texttt{...}}%
\catcode`,=\active%
\catcode`.=\active%
\texttt{(}\scantokens{#1}\texttt{)}%
\endgroup%
}%
\makeatother
\begin{document}
% This works:
\mylist(First, Second, Third, ...)
% This should always work:
Some text with ... dots ... that \ldots should not be changed. Dots in \textbf{.} commands should also work.
% This does not work:
% Expected: \texttt{(}First\texttt{,} Second\texttt{, } Th.rd\texttt{, }\texttt{...}\texttt{)}
% Error: ! Use of . doesn't match its definition.
\mylist(First, Second, Th.rd, ...)
\end{document}
此外,如果您有任何其他改进建议,请随时告诉我。
答案1
您可以检查 TeX 基元后面是否有下一个点\futurelet
:
\def\mylist (#1){%
\begingroup%
\catcode`,=\active
\catcode`.=\active
\texttt{(}\scantokens{#1}\texttt{)}%
\endgroup%
}%
\begingroup\lccode`~=`, \lowercase{\endgroup\def~}{\texttt{,} }
\begingroup\lccode`~=`. \lowercase{\endgroup
\def~{\threedots}
\def\threedots{\futurelet\next\threedotsA}
\def\threedotsA{\ifx\next~\expandafter\threedotsB \else .\fi}
\def\threedotsB~~{\texttt{...}}
}% end \lowercase
在宏定义时,作用域中的 被替换为活动点。本身\lowercase
是非活动点。~
.
答案2
不\scantokens
。
\documentclass[a4paper]{article}
\ExplSyntaxOn
\NewDocumentCommand{\mylist}{r()}
{
\tl_set:Nn \l_tmpa_tl { #1 }
\tl_replace_all:Nnn \l_tmpa_tl { , } { \texttt{,} }
\tl_replace_all:Nnn \l_tmpa_tl { ... } { \texttt{...} }
\texttt{(} \tl_use:N \l_tmpa_tl \texttt{)}
}
\ExplSyntaxOff
\begin{document}
\mylist(First, Second, Third, ...)
\mylist(First, Second, Th.rd, ...)
\end{document}
答案3
以下是通过以下方式完成解析的方法listofitems
:
\documentclass{article}
\usepackage{listofitems}
\setsepchar{,/...}
\def\mylist(#1){\readlist*\mylistitems{#1}%
\foreachitem\z\in\mylistitems{%
\ifnum\zcnt=1\else\texttt{, }\fi
\ifnum\listlen\mylistitems[\zcnt]=1\relax\z\else\texttt{\z}\fi
}%
}
\begin{document}
\mylist(First, Second, Third, ...)
\mylist(First, Second, Th.rd, ...)
\end{document}