突出显示特定单词的第一次出现

突出显示特定单词的第一次出现

我正在写一篇科学论文,在这篇论文中,我提出了一系列新术语。第一次提出新术语时,我希望 LaTeX 自动突出显示 - 例如使用斜体或小写字母。

有这样的包吗?如果没有,你们中有人知道其他方法来实现同样的效果吗?

答案1

您无法以完全自动化的方式完成此操作。不可能给出单词列表并让 TeX 识别第一个出现的位置。

.tex您可以做的是在给出列表和类似以下代码后在文件中标记术语:

\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]{%
  \@ifundefined{specialterm@\detokenize{#1}}
    {#1}{\emph{#1}\global\expandafter\let\csname specialterm@\detokenize{#1}\endcsname\relax}%
}
\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}. Now \term{bar} and
again \term{bar} and \term{baz} and \term{foo}.

\end{document}

在此处输入图片描述

代码的作用是什么?这\@for只是一种更简单的方法,可以避免说类似

\specialterm{foo}\specialterm{bar}\specialterm{baz}

我们对\specialterms{foo,bar,baz}每个术语执行相同的代码:例如,命令\specialterm@foo本质上被定义为不执行任何操作。实际上,我们只检查它的“存在”:当 LaTeX 发现\term{foo}它时,它会查看是否\specialterm@foo已定义:如果是,它会打印\emph{foo}取消定义 \specialterm@foo(使其相当于\relax,其中 ,对于\@ifundefined恰好未定义);否则它会打印foo

\detokenize位只是为了避免术语包含重音字符时出现问题。

答案2

我使用这个glossaries包来实现这个目的。它非常灵活,允许您定义术语,指定它在第一次和后续使用时应该如何看待,然后生成词汇表。这是一个简单的例子,它以斜体显示第一个术语,并使用将hyperref术语的使用链接到词汇表中的定义(出现在文档末尾)。该glossaries包还对首字母缩略词提供类似的支持。

\documentclass{scrbook}
\usepackage[colorlinks]{hyperref}  % Terms will also be coloured as they are hyperlinks.
\usepackage{glossaries}
\makeglossaries
\newglossaryentry{term}{
  name=term, 
  description={A word or phrase with an unfamiliar but specific meaning that
    should be flagged upon first use and defined}
}

% Customize the format of the first use.  See the manual for details if
% you want to include more information here such as the definition.
\defglsdisplayfirst[\glsdefaulttype]{\textit{#1}}

\begin{document}
% Note that there are forms for plural entries (appending an 's' by default)
% and for capitals such as should occur at the start of a sentence:
This document is about \glspl{term}.  That was the first use of the term
\gls{term}, and this is the second. \Glspl{term} may also occur at the start   
of sentences like this.

% Print the whole glossary
\printglossaries

\end{document}

为此,运行您喜欢的版本LaTeX,然后makeglossaries

pdflatex example
makeglossaries example
pdflatex example
pdflatex example

或者你可以教 latexmk 使用 makeglossaries。 我建议latexmk对于构建LaTeX文档非常有帮助,尤其是当我更改源时自动重建-pdf -pcv的选项。pdflatex

注意:该软件包的文档glossaries有点难以理解——所有信息都在那里,但请查看文章与{glossaries}先标记以节省一些时间。

词汇表条目的样例输出 示例词汇表

答案3

以下是一个解决方案luatex。其思路是使用process_input_buffer回调,这样 luatex 就会检查每行输入的文本中是否有需要强调的单词。如果找到了,并且是第一次出现,那么它会在单词周围添加一个宏来强调它。

我使用模式匹配来检测该词是否不是其他词的“子词”并检测标点符号。

请注意,我并不是使用该库进行模式匹配的专家string(我应该用...来完成lpeg)。因此,它无法检测到bar(请随意更正我的代码)。

首先是lua文件(将其保存为first-occurence.lua)。

local gsub = string.gsub
local find = string.find

first_occurence = first_occurence or {}
first_occurence.table = first_occurence.table or {}

function first_occurence.add (s)
   first_occurence.table[#first_occurence.table + 1] = 
  { [1] = s, [2] = true}
end

function first_occurence.start ()
   luatexbase.add_to_callback(
  'process_input_buffer', 
  function (s)
     for i = 1, #first_occurence.table do
    if first_occurence.table[i][2] then
       local j =  find(s, 
               '[^%a]-' .. 
                  first_occurence.table[i][1] .. 
                  '[\n\t ,.:;!?]+')
       if j then
       -- The final 1 is to limit substitutions made to one.
          s = gsub(s, '[^%a]-' .. first_occurence.table[i][1] .. '[\n\t ,.:;!?]+','\\emph{%1}',1)
       first_occurence.table[i][2] = false
       end
    end
     end
     return s
  end,
  'replace_first_occurence')
end

function first_occurence.stop ()
   luatexbase.remove_from_callback(
  'process_input_buffer', 'replace_first_occurence')
end

return first_occurence

然后是tex文件。

\documentclass{standalone}
\usepackage{luatexbase}

\directlua{dofile('first-occurence.lua')}

\def\startreplacefirstoccurence{%
  \directlua{first_occurence.start()}}

\def\stopreplacefirstoccurence{%
  \directlua{first_occurence.stop()}}

\def\addtoreplacefirstoccurence#1{%
  \directlua{first_occurence.add('\luatexluaescapestring{#1}')}}

\addtoreplacefirstoccurence{Test}
\addtoreplacefirstoccurence{foo}
\addtoreplacefirstoccurence{bar}
\begin{document}
Test 
\startreplacefirstoccurence
Test Test Test foobar foo bar 
\end{document}

答案4

如果您只想突出显示第一次出现的情况而不明确定义它们,同时保留多个选项等,您可以使用:

\usepackage{glossaries}
\makeglossaries

\let\oldgls\gls
\let\oldGls\Gls
\let\oldglspl\glspl
\let\oldGlspl\Glspl

\makeatletter
\newcommand\term[1]{%
  \newglossaryentry{#1}{
    name=#1,
    description=foo
  }%
}
\newcommand{\defineterm}[1]{%
  \expandafter\def\csname specialterm@\detokenize{#1}\endcsname{}%
}
\renewcommand\gls[1]{%
  \@ifundefined{specialterm@\detokenize{#1}}
    {\term{#1}\oldgls{#1}\defineterm{#1}}{\oldgls{#1}}%
}
\renewcommand\Gls[1]{%
  \@ifundefined{specialterm@\detokenize{#1}}
    {\term{#1}\oldGls{#1}\defineterm{#1}}{\oldGls{#1}}%
}
\renewcommand\glspl[1]{%
  \@ifundefined{specialterm@\detokenize{#1}}
    {\term{#1}\oldglspl{#1}\defineterm{#1}}{\oldglspl{#1}}%
}
\renewcommand\Glspl[1]{%
  \@ifundefined{specialterm@\detokenize{#1}}
    {\term{#1}\oldGlspl{#1}\defineterm{#1}}{\oldGlspl{#1}}%
}
\makeatother

...

\gls{foo}\gls{foo}\glspl{foo}\Gls{foo}\Gls{bar}\gls{bar}

相关内容