第一次提問。
我正在實施這個問題的egregs答案:突出顯示特定單字的第一次出現
%%% Code to set up special term treatment
\makeatletter
\newcommand{\specialterms}[1]{%
\@for\next:=#1\do
{\@namedef{specialterm@\detokenize\expandafter{\next}}{}}%
}
\newcommand\term[1]{%
\@ifundefined{specialterm@\detokenize{#1}}
{#1}{\emph{#1}\global\expandafter\let\csnamespecialterm@\detokenize{#1}\endcsna me\relax}%
}
\makeatother
%%% Here we define the special terms we want
\specialterms{foo,bar,baz}
這強調了清單中第一次提到的單字\specialterms
。目前這工作正常。我希望它能夠識別 中列出的單字的大寫版本\specialterms
,以便它更好地處理句子中的第一個單字。透過這個例子,我想\term{Foo}
強調的是不必將 Foo 加入\specialterms
清單。
我嘗試了以下方法:
\@ifundefined{specialterm@\MakeLowercase{\detokenize{#1}}}
但這是行不通的。我想我需要添加一些\csnames
和\expandafter
命令以及你有什麼,但我對這些命令實際作用的理解非常有限。任何建議將不勝感激。我也許應該將其作為評論發佈在原始線程中,但由於我剛剛加入該網站,因此我沒有足夠的聲譽來執行此操作。
答案1
我們可以檢查該術語的小寫版本。
\documentclass{article}
%%% Code to set up special term treatment
\makeatletter
\newcommand{\specialterms}[1]{%
\@for\next:=#1\do
{\@namedef{specialterm@\detokenize\expandafter{\next}}{}}%
}
\newcommand\term[1]{%
\specialterm@lower{#1}% save the lowercased term in \specialterm@current
\@ifundefined{specialterm@\specialterm@current}
{#1}% not the first occurrence
{% first occurrence
\emph{#1}% print it in italics
% then undefine the macro
\global\expandafter\let\csname specialterm@\specialterm@current\endcsname\relax
}%
}
\newcommand{\specialterm@lower}[1]{%
\begingroup\edef\next{\detokenize{#1}}%
\edef\x{\endgroup\lowercase{\def\noexpand\specialterm@current{\next}}}\x
}
\makeatother
%%% Here we define the special terms we want
\specialterms{foo,bar,baz}
\begin{document}
First occurrence of \term{foo} and second occurrence of \term{foo}.
First occurrence of \term{baz}. \term{Bar} and
again \term{bar} and \term{baz} and \term{foo}.
\end{document}
一個更簡單的實現expl3
,它也適用於 UTF-8(不過不是必需的)。
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{xparse}
%%% Code to set up special term treatment
\ExplSyntaxOn
\NewDocumentCommand{\specialterms}{m}
{
\clist_map_inline:nn { #1 }
{
\bool_new:c { \__lasse_boolean_name:n { ##1 } _bool }
}
}
\NewDocumentCommand{\term}{m}
{
\bool_if:cTF { \__lasse_boolean_name:n { #1 } _bool }
{
#1
}
{
\emph { #1 }
\bool_gset_true:c { \__lasse_boolean_name:n { #1 } _bool }
}
}
% syntactic sugar
\cs_new:Nn \__lasse_boolean_name:n
{
g_lasse_specialterms_ \str_lowercase:n { #1 }
}
\ExplSyntaxOff
%%% Here we define the special terms we want
\specialterms{foo,bar,báz,bäz}
\begin{document}
First occurrence of \term{foo} and second occurrence of \term{foo}.
First occurrence of \term{báz}. \term{Bar} and
again \term{bar} and \term{báz} and \term{foo}.
\term{Bäz} \term{bäz}
\end{document}
答案2
這是一個解決方案
\documentclass{article}
\newcommand*{\term}[1]{%
\lowercase{\expandafter\ifx\csname mt\detokenize{#1}term\endcsname\relax}
\emph{#1}%
\lowercase{\expandafter\let\csname mt\detokenize{#1}term\endcsname\empty}%
\else#1\fi}
\begin{document}
First occurrence of \term{foo} and second occurrence of \term{foo}.
First occurrence of \term{baz}. Now \term{bar} and
again \term{bar} and \term{baz} and \term{foo}. \term{fOo}
First occurrence of \term{BOM}. Now \term{bOm} and
again \term{BOm} and \term{bom} and \term{FOo} and \term{fOo}.
\end{document}