我正在写一篇科学论文,在这篇论文中,我提出了一系列新术语。第一次提出新术语时,我希望 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}