\g@addto@macro 附加位置特定引用

\g@addto@macro 附加位置特定引用

我想生成一个包含部分名称的自动生成表。特别是,我想控制表格形状等(该表仅用作最小示例)。我如何才能实现命令不只是简单地组合,而是\addtotable添加正确的引用,即表格的第一行应包含“第 1 节”,第二行应包含“第 2 节”(我指的是下面的最小示例)。请记住,我不想给每个部分一个标签并为每个部分单独明确引用它。\currentname\addtotable

\documentclass{article}
\usepackage{nameref}
\makeatletter
\newcommand*{\currentname}{\@currentlabelname}
\makeatother

\newcommand\foo{%
    \begin{table}[htp]
        \centering
        \begin{tabular}{ |c| }
            \hline
            Section \\ \hline % Header row
            \foorows
            \hline
        \end{tabular}
\end{table}}

\newcommand\foorows{}

\makeatletter
\newcommand\addtotable[1]{%
    \g@addto@macro\foorows{\@gobble}%
    \@for\tmp:=#1\do{%
        \expandafter\g@addto@macro\expandafter\foorows
        \expandafter{\expandafter&\tmp}%
    }%
    \g@addto@macro\foorows{\\}%
}
\makeatother

\begin{document}
    \section{Section~1}
    Current section: \currentname.\\~\\

    Partial table:
    \addtotable{\currentname}
    \foo

    \section{Section~2}
    Current section: \currentname.\\~\\

    Full table:
    \addtotable{\currentname}
    \foo 

\end{document}

答案1

不清楚为什么&只是为了吞食它们而添加它们。

除此之外,您的代码的问题在于您只扩展了一次\currentname,因此您总是添加\@currentlabelname。您需要将其扩展两次,这可以使用更多的来完成\expandafter,但也可以使用详尽扩展来实现,明确标记不应扩展的内容。

\documentclass{article}
\usepackage{nameref}

\newcommand\foo{%
  \begin{table}[htp]
  \centering
  \begin{tabular}{ |c| }
  \hline
  Section \\ \hline % Header row
  \foorows
  \hline
  \end{tabular}
  \end{table}
}

\newcommand\foorows{}

\makeatletter
\newcommand*{\currentname}{\@currentlabelname}
\newcommand\addtotable[1]{%
  \@for\tmp:=#1\do{%
    \begingroup\protected@edef\x{\endgroup
      \noexpand\g@addto@macro\noexpand\foorows{#1\noexpand\\}%
    }\x
  }%
}
\makeatother

\begin{document}

\section{Section~1}
Current section: \currentname.

Partial table:
\addtotable{\currentname}
\foo

\section{Section~2}
Current section: \currentname.

Full table:
\addtotable{\currentname}
\foo 

\end{document}

请注意,\protected@edef而不是,因此不能干净利落地生存的\edef命令(例如~或)将是安全的。\textbf\edef

在此处输入图片描述

答案2

添加 addtotable 参数时需要将其展开。可以使用以下方法完成此操作\edef:创建一个新宏\exptmp,该宏具有与 相同的值\tmp,只是它已完全展开:

\documentclass{article}
\usepackage{nameref}
\makeatletter
\newcommand*{\currentname}{\@currentlabelname}
\makeatother

\newcommand\foo{%
    \begin{table}[htp]
        \centering
        \begin{tabular}{ |c| }
            \hline
            Section \\ \hline % Header row
            \foorows
            \hline
        \end{tabular}
\end{table}}

\newcommand\foorows{}

\makeatletter
\newcommand\addtotable[1]{%
    \g@addto@macro\foorows{\@gobble}%
    \@for\tmp:=#1\do{%
        \edef\exptmp{\tmp}
        \expandafter\g@addto@macro\expandafter\foorows
        \expandafter{\expandafter&\exptmp}%
    }%
    \g@addto@macro\foorows{\\}%
}
\makeatother

\begin{document}
    \section{Section~1}
    Current section: \currentname.\\~\\

    Partial table:
    \addtotable{\currentname}
    \foo

    \section{Section~2}
    Current section: \currentname.\\~\\

    Full table:
    \addtotable{\currentname}
    \foo 

\end{document}

如果你想在 LaTeX 中进行更复杂的编程,我建议你看一下expl3。它增加了编程层,这使得编写这样的代码变得更加容易。

相关内容