私は、 を使用して 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}
望ましい出力は... まあ、生成されるものとほぼ同様です:
上部の 2 つの赤い点は、時間の前に何かが参照されていることを示しています。並べ替えを試みると\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 文字が含まれている場合に使用されるオプションの引数があります (例を作成しました)。オプションの引数は、ケースへの参照が行われる場所で使用されるキーにすぎません。
秘訣は、2 つの異なることを実行し、ボックス内で実行された\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}
残っている唯一の問題は、「第 1 章」とセクションの間に残っているスペースです。