情况是这样的:

情况是这样的:

我希望这个问题有意义。如果我想修改以下代码以允许用户传递宏作为第一个参数,我该怎么做?

情况是这样的:

(使用pgf

\def\appendtolist#1{% <item>
  \csname pgfutil@ifundefined\endcsname{mylistmacro}{\def\mylistmacro{#1}}{% Instantiate list if not already
  \expandafter\def\expandafter\mylistmacro\expandafter{\mylistmacro^^J#1}}% Append to list
}%

我实际上想做的是:

(使用pgf

\def\appendtolist#1#2{% <macro representing list> <item>
  \csname pgfutil@ifundefined\endcsname{#1}{\def\ithapplist{#1}}{% Instantiate list if not already
  \expandafter\def\expandafter#1\expandafter{\ithapplist^^J#1}}% Append to list
}%

问题

之后\endcsname我需要提供一个不带反斜杠的宏名。

即使我使用其他语法来确定宏是否已定义,我仍然会遇到这个问题。

其他 csname 检查

TeX 内核

https://tex.stackexchange.com/a/30484/13552

\ifcsname#1\endcsname%
    ... command '#1' exists ...%
  \else%
    ... command '#1' does not exist ...%
  \fi%

LateX 内核

https://tex.stackexchange.com/a/30486/13552强调文字

\@ifundefined{foo}
  {%
    % \foo not defined
  }
  {%
    % \foo defined
  }%

最终目标

通常,我会在运行时使用 将内容吐出到日志中\typeout。相反,我想将它们附加到宏(分隔变量)中,以便稍后使用类似 的内容调用\typeout\expandafter{\aggregatedlogentries}。这会使某些内容在日志中分组。

例子

无法编译

 \documentclass{article}
 \usepackage{pgf}
 \def\appendtolist#1{% <item>
       \csname pgfutil@ifundefined\endcsname{mylistmacro}{\def\mylistmacro{#1}}{% Instantiate list if not already
       \expandafter\def\expandafter\mylistmacro\expandafter{\mylistmacro^^J#1}}% Append to list
     }%
\begin{document}
\newcount\step
\step = 0%
\loop
  \appendtolist{\step}% <== I want to be able to provide a macro name as arg1 and item as arg2!
  \advance\step by 1%
  \unless\ifnum \step>10 %space important
\repeat %

\typeout{\mylistmacro}
\end{document}

答案1

这是程序员使用复杂的宏包(如)解决不存在的问题的明显例子pgf。您可以简单地执行以下操作:

\def\appendtolist#1#2{%
   \ifx#1\undefined \def#1{#2}\else   
   \expandafter\def\expandafter#1\expandafter{#1^^J#2}\fi % Append to list
}%

\appendtolist\ithaplist{aha} \appendtolist\ithaplist{uha}

答案2

您的代码没有产生错误,而只是简单地定义\mylistmacro为 10 ,\step因为您确实将标记附加了\step^^J10 次,在这里我附加了当前值的扩展\step,尽管正如 wipet 正确指出的那样,这使用的代码比所述用例所需的代码多几个数量级。

 \documentclass{article}
%no \usepackage{etex}% for \unless
 \usepackage{pgf}
\makeatletter
 \def\appendtolist#1{% <item>
       \pgfutil@ifundefined{mylistmacro}{\def\mylistmacro{#1}}{% Instantiate list if not already
       \expandafter\def\expandafter\mylistmacro\expandafter{\mylistmacro^^J#1}}% Append to list
     }%
\begin{document}
\newcount\step
\step = 0%
\loop
  \expandafter\appendtolist\expandafter{\the\step}% <== I want to be able to provide a macro name as arg1 and item as arg2!
  \advance\step by 1%
  \unless\ifnum \step>10 %space important
\repeat %



\typeout{\mylistmacro}
\end{document}

答案3

LaTeX3 编程层expl3为这些类型的事情提供了许多宏。

\documentclass{article}
\usepackage{xparse}
\begin{document}
\ExplSyntaxOn
\seq_new:N \l_macmad_mylist_seq

\int_step_inline:nnnn { 0 } { 1 } { 10 }
 { \seq_put_right:Nn \l_macmad_mylist_seq { #1 } }

\seq_use:Nn \l_macmad_mylist_seq { ,~ }
\ExplSyntaxOff
\end{document}

在此处输入图片描述

答案4

etoolbox

\usepackage{etoolbox}

\newcommand{\appendtolist}[2]{%
  \ifundef{#1}{\gdef#1{== \string#1 ==}}{}%
  \gappto#1{^^J#2}%
}

\appendtolist\mylistmacro{abc}
\appendtolist\mylistmacro{def}
\appendtolist\mylistmacro{ghi}
\appendtolist\mylistmacro{lmn}

\typeout{\mylistmacro}

终端输出:

== \mylistmacro ==
abc
def
ghi
lmn

更加可定制,因为您可以定义所制作列表的任何用途,只需改变定义方式即可\showlist

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\appendtolist}{mm}
 {
  \seq_if_exist:cF { g_macmadness_typeout_#1_seq }
   { \seq_new:c { g_macmadness_typeout_#1_seq } }
  \seq_gput_right:cn { g_macmadness_typeout_#1_seq } { #2 }
 }
\NewDocumentCommand{\showlist}{m}
 {
  \typeout
   {
    ==~#1~==^^J
    \seq_use:cn { g_macmadness_typeout_#1_seq } { ^^J }
   }
 }
\ExplSyntaxOff

\appendtolist{mylistmacro}{abc}
\appendtolist{mylistmacro}{def}
\appendtolist{mylistmacro}{ghi}
\appendtolist{mylistmacro}{lmn}

\showlist{mylistmacro}

终端输出

== mylistmacro ==
abc
def
ghi
lmn

相关内容