在另一個命令中展開一個命令

在另一個命令中展開一個命令

我繼續我的傳奇,使用 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。如果第一個強制參數包含非 ASCII 字元(我舉了一個例子),則該\newInfon命令有一個可選參數:可選參數只是在引用案例時使用的鍵。

訣竅是 make做兩件不同的事情,並在盒子內執行\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。那麼addInfoRef函數只在該printingInfo=0時才執行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}

現在唯一剩下的問題是「第一章」和各部分之間的剩餘間距。

相關內容