在另一个命令内展开一个命令

在另一个命令内展开一个命令

我继续我的传奇故事,使用 LaTeX 来扩展东西etoolbox

这次我有下面一段代码。

\documentclass[8pt]{book}
\usepackage{etoolbox}
\usepackage{hyperref}

\newcount\infoCounter

\newcommand{\addInfoRef}[1]{
\unexpanded{\nameref{\csuse{info#1Label}}}
\cseappto{info#1Ref}{Mentioned in %
                    \unexpanded{\unexpanded{\nameref}}{\csuse{info\currentname Label}}%
                    \unexpanded{\unexpanded{\\}}
                    }
}


\newcommand{\newInfon}[3][]{
\listxadd\listInfo{#2}
\edef\currentname{#2}
\csedef{info#2Label}{infoKey\the\infoCounter}
\advance\infoCounter by 1
\ifstrempty{#1}{}{\csedef{info#2Img}{#1}}
\csedef{info#2Cnt}{#3}
\nullfont#3\normalfont
}

\newcommand{\printInfo}[1]{%
\edef\currentName{#1}
\section{#1}\label{\expandafter\csuse{info#1Label}}%
\csuse{info#1Cnt}
\ifcsname info#1Ref\endcsname
\\\begin{tabular}{p{9cm}}
  \csuse{info#1Ref}
\end{tabular}
\fi}

\begin{document}

\chapter{Tests Result}

\newInfon{Test Case 1}{%
The result was inconclusive.}

\newInfon{Test Case 2}{%
The result was more conclusive than in \addInfoRef{Test Case 1}, but was still inconclusive.}

\newInfon{Test Case 3}{%
The result less conclusive than in \addInfoRef{Test Case 2}, but was still more conclusive than in \addInfoRef{Test Case 1}.}

\printInfo{Test Case 1}
\printInfo{Test Case 2}
\printInfo{Test Case 3}

\end{document}

期望的输出是......嗯,几乎是生成的内容:

在此处输入图片描述

顶部的两个红点表示在时间之前引用了某件事。如果您尝试重新排序\printInfo{Test Case X},您会注意到“提及”不再正确打印。例如,如果我重新排序:

\printInfo{Test Case 3}
\printInfo{Test Case 2}
\printInfo{Test Case 1}

我明白了

在此处输入图片描述

也就是说,一些“提及”条目是重复的!我考虑做类似的事情

\ifcsname info\currentname#2Switch\endcsname{\relax}{%
  \cseappto{info#2Ref}{Mentioned in...}
}
\csedef{info\currentname#2Switch}{1}

\addInfoRef但是那没有用而且我不知道为什么。

任何帮助都非常感谢!提前致谢!

答案1

expl3以下是使用(via xparse)的实现。\newInfon如果第一个强制参数包含非 ASCII 字符,则该命令有一个可选参数可供使用(我做了一个示例):可选参数只是一个键,可在引用案例时使用。

诀窍是做两件不同的事情,并在框内执行\addInfoRef时执行,因此输出最终被丢弃。\newInfon

\documentclass{book}
\usepackage[utf8]{inputenc}
\usepackage[greek,english]{babel}
\usepackage{xparse}
\usepackage{etoolbox}
\usepackage[unicode]{hyperref}

\pdfstringdefDisableCommands{\let\textgreek\relax}

\ExplSyntaxOn

\prop_new:N \g_benedict_info_items_prop
\bool_new:N \l_benedict_info_add_bool

\NewDocumentCommand{\newInfon}{O{#2}mm}
 {
  \prop_gput:Nnn \g_benedict_info_items_prop
   { #1 key }  % key
   { #2 }
  \prop_gput:Nnx \g_benedict_info_items_prop
   { #1 text } % text
   { \tl_trim_spaces:n { #3 } }
  \tl_set:Nn \l__benedict_info_temp_tl { #1 }
  \hbox_set:Nn \l_tmpa_box
   {
    \bool_set_true:N \l_benedict_info_add_bool #3
   }
 }

\NewDocumentCommand{\addInfoRef}{m}
 {
  \bool_if:NTF \l_benedict_info_add_bool
   {
    \seq_if_exist:cF { g_benedict_info_#1_seq }
     {
      \seq_new:c { g_benedict_info_#1_seq }
     }
    \seq_gput_right:cx { g_benedict_info_#1_seq }
     {
      Mentioned ~ in ~ \exp_not:N \nameref{\l__benedict_info_temp_tl label}
     }
   }
   {
    \prop_item:Nn \g_benedict_info_items_prop { #1 key }
   }
 }

\NewDocumentCommand{\printInfo}{m}
 {
  \exp_args:Nx \section {\prop_item:Nn \g_benedict_info_items_prop { #1 key }}\label{#1label}
  \prop_item:Nn \g_benedict_info_items_prop { #1 text }
  \seq_if_exist:cT { g_benedict_info_#1_seq }
   {
    \\*[\medskipamount]
    \begin{tabular}{@{} p{9cm} @{}}
    \seq_use:cn { g_benedict_info_#1_seq } { \\ }
    \end{tabular}
    \par\addvspace{\medskipamount}
   }
 }
\ExplSyntaxOff

\begin{document}

\chapter{Tests Result}

\newInfon[TC1]{Test Case (\textgreek{δοκιμή}) 1}{
  The result was inconclusive.
}

\newInfon{Test Case 2}{
  The result was more conclusive than in \addInfoRef{TC1},
  but was still inconclusive.
}

\newInfon{Test Case 3}{
  The result less conclusive than in \addInfoRef{Test Case 2},
  but was still more conclusive than in \addInfoRef{TC1}.
}

\printInfo{TC1}
\printInfo{Test Case 2}
\printInfo{Test Case 3}

\end{document}

在此处输入图片描述

答案2

我通过大量的反复试验回答了自己的问题。基本上,我创建了一个printingInfo变量,将其设置为 0,并且只在 printInfo 期间将其设置为 1。然后,如果该 printingInfo=0,addInfoRef 函数才会执行 cseappto。

这是可行的解决方案:

\documentclass[8pt]{book}
\usepackage{etoolbox}
\usepackage{hyperref}

\newcount\infoCounter

\edef\printingInfo{0}%
\newcommand{\addInfoRef}[1]{%
\ifstrequal{\printingInfo}{0}{\unexpanded{\nameref{\csuse{info#1Label}}}}{%
\cseappto{info#1Ref}{Mentioned in %
\unexpanded{\unexpanded{\nameref}}{\csuse{info\currentname Label}}%
\unexpanded{\unexpanded{\\}}}%
}%
}


\newcommand{\newInfon}[3][]{
\edef\printingInfo{0}%
\edef\currentname{#2}
\csedef{info#2Label}{infoKey\the\infoCounter}
\advance\infoCounter by 1
\ifstrempty{#1}{}{\csedef{info#2Img}{#1}}
\csedef{info#2Cnt}{#3}
\nullfont#3\normalfont
}

\newcommand{\printInfo}[1]{%
\edef\printingInfo{1}%
\edef\currentname{#1}
\section{#1}\label{\expandafter\csuse{info#1Label}}%
\csuse{info#1Cnt}
\ifcsname info#1Ref\endcsname
\\\begin{tabular}{p{9cm}}
  \csuse{info#1Ref}
\end{tabular}
\fi}

\begin{document}

\chapter{Tests Result}

\newInfon{Test Case 1}{%
The result was inconclusive.}

\newInfon{Test Case 2}{%
The result was more conclusive than in \addInfoRef{Test Case 1}, but was still inconclusive.}

\newInfon{Test Case 3}{%
The result less conclusive than in \addInfoRef{Test Case 2}, but was still more conclusive than in \addInfoRef{Test Case 1}.}

\printInfo{Test Case 1}
\printInfo{Test Case 2}
\printInfo{Test Case 3}

\end{document}

现在唯一剩下的问题是“第 1 章”与各章节之间剩余的间距。

相关内容