偶尔遇到需求,想以指定颜色突出显示特定的参考文献条目。一种场景是,回应审稿人添加参考文献的要求。
一种方案是,在正常编译完成后,手动修改 .bbl 文件,然后再跑一次 pdflatex/xelatex。
这种方案非常自由,但不够方便,因为每次运行 bibtex/biber,都会重新生成 .bbl。
本文提供一种通过宏实现的、更自动的尝试。
思路梳理
每个参考文献条目,都由 thebibliography 环境里的一个 \bibitem 生成。其中,
thebibliography 环境是特殊的列表环境,
\bibitem 是封装过的 \item 命令。
如果使用了 .bib 文献数据库,那么 .bbl 文件就是一个完整的 thebibliography 环境。
根据用法\bibitem[]{} 和 \cite{},如果规范使用,则 和文献一一对应。
我们来 patch \bibitem,使得对特定 , 整条\bibitem 使用额外的颜色输出。
\bibitem 命令内部会调用 @bibitem 和 @lbibitem,所以实际需要 patch 后两个命令,patch 的位置是 \item 之前
具体实现
2021-09-01 更新:为每个 定义 \bib@colored@,替代 \in@{}{} \ifin@ … \else … \fi
2021-09-05 更新:
支持多个颜色,用法改为 \bibColoredItems{}{}
具体实现,把颜色储存在 \bib@colored@ 里
// An highlighted block
\usepackage{xpatch}
\makeatletter
\ExplSyntaxOn
% #1 = color
% #2 = list of bib items
\cs_new:Npn \bibColoredItems #1#2
{
\clist_map_inline:nn {#2} { \cs_new:cpn {bib@colored@##1} {#1} }
}
\ExplSyntaxOff
% #1 = one bib item
\newcommand\bib@setcolor[1]{%
\ifcsname bib@colored@#1\endcsname
\expandafter\color\expandafter{\csname bib@colored@#1\endcsname}
\else
\normalcolor
\fi
}
\xpatchcmd\@bibitem
{\item}
{\bib@setcolor{#1}\item}
{}{\fail}
\xpatchcmd\@lbibitem
{\item}
{\bib@setcolor{#2}\item}
{}{\fail}
\makeatother
% usage
\bibColoredItems{<color1>}{<item1a>, <item1b>}
\bibColoredItems{<color2>}{<item2a>, <item2b>}
其中,
\bibitem 在 latex2e 格式中的定义是
\def\bibitem{@ifnextchar[@lbibitem@bibitem}
\in@{}{} 是 latex2e 提供的工具宏,用于检查 是否包含 。若包含,则 \ifin@ 为真,否则为假。
\normalcolor 是 latex2e 提供的宏,用于恢复到默认颜色,类似的命令还有\normalfont, \normalsize 等。
测试效果
测试用完整文档
\begin{filecontents}[force]{bibtex.bib}
@inproceedings{ren2015faster,
title={Faster r-cnn: Towards real-time object detection with region proposal networks},
author={Ren, Shaoqing and He, Kaiming and Girshick, Ross and Sun, Jian},
booktitle={Advances in neural information processing systems},
pages={91--99},
year={2015}
}
@inproceedings{girshick2015fast,
title={Fast r-cnn},
author={Girshick, Ross},
booktitle={Proceedings of the IEEE international conference on computer vision},
pages={1440--1448},
year={2015}
}
@inproceedings{sharif2014cnn,
title={CNN features off-the-shelf: an astounding baseline for recognition},
author={Sharif Razavian, Ali and Azizpour, Hossein and Sullivan, Josephine and Carlsson, Stefan},
booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition workshops},
pages={806--813},
year={2014}
}
@misc{misc,
author = {X Peter Isley},
title = {The title of the work},
howpublished = {How it was published},
month = 7,
year = 1993,
note = {An optional note}
}
\end{filecontents}
\documentclass{article}
\usepackage{xcolor}
\usepackage{xpatch}
\makeatletter
\ExplSyntaxOn
% #1 = color
% #2 = list of bib items
\cs_new:Npn \bibColoredItems #1#2
{
\clist_map_inline:nn {#2} { \cs_new:cpn {bib@colored@##1} {#1} }
}
\ExplSyntaxOff
% #1 = one bib item
\newcommand\bib@setcolor[1]{%
\ifcsname bib@colored@#1\endcsname
\expandafter\color\expandafter{\csname bib@colored@#1\endcsname}
\else
\normalcolor
\fi
}
\xpatchcmd\@bibitem
{\item}
{\bib@setcolor{#1}\item}
{}{\fail}
\xpatchcmd\@lbibitem
{\item}
{\bib@setcolor{#2}\item}
{}{\fail}
\makeatother
\begin{document}
\nocite{*}
\bibliographystyle{plain}
\bibColoredItems{red}{misc, sharif2014cnn}
\bibColoredItems{blue}{ren2015faster}
aaa
\bibliography{bibtex}
bbb
\end{document}
其中,
filecontents 环境会把环境内容写入(与主文件位于相同目录的)名为 bibtex.bib 的外部文件。
此处使用,是为了能在一个例子里同时提供 .tex 和 .bib 文件,便于复制-粘贴-本地运行。