다른 명령 내에서 명령 확장

다른 명령 내에서 명령 확장

나는 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

나는 광범위한 시행착오를 통해 내 자신의 질문에 대답했습니다. 기본적으로 변수를 생성하여 printingInfo0으로 설정하고 printInfo 중에만 1로 설정했습니다. 그런 다음 addInfoRef 함수는 이 printInfo=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}

이제 남은 유일한 문제는 "1장"과 섹션 사이에 남은 간격입니다.

관련 정보