以 ... (三个点)作为宏名

以 ... (三个点)作为宏名

为了方便起见(也为了加深我的 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}

在此处输入图片描述

相关内容