Я продолжаю свою сагу по расширению материала в 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
(через 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 и установил ее в 1 только во время printInfo. Затем функция addInfoRef выполняет cseappto только если эта printingInfo=0.
Вот рабочее решение:
\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» и разделами.