FEATURED · 精选文章

LaTeX多色修订系统:用xcolor与soul包实现高效协同写作

发布时间 / 2026/8/1 3:16:10
来源 / 创域科博编辑部
栏目 / 资讯中心
LaTeX多色修订系统:用xcolor与soul包实现高效协同写作 1. 从“一片红”到“五彩斑斓”为什么我们需要在LaTeX中高亮修改如果你和我一样经历过用LaTeX撰写论文、报告或者书籍的漫长过程那你一定对那个经典的“一片红”场景不陌生。导师、合作者或者审稿人发回一个满是修订的PDF你打开一看满屏都是红色的删除线和下划线密密麻麻看得人头晕眼花。更头疼的是当你有多个审稿人或者需要区分自己不同阶段的修改时传统的“红与黑”就显得力不从心了。这时候一个朴素但强烈的需求就产生了能不能让我的修改记录也“五彩斑斓”起来这不仅仅是追求美观。在协同写作、版本迭代和学术审阅中清晰地区分不同来源、不同类型、不同批次的修改内容能极大提升沟通效率和版本管理的清晰度。想象一下你可以用蓝色标出合作者A的建议用绿色标出自己第二轮的润色用橙色高亮出待确认的数据部分。这份文档瞬间就从混乱的战场变成了条理清晰的作战地图。LaTeX作为专业的排版系统其核心优势在于对内容和样式的精确控制实现这种多颜色标注正是将其精确控制能力从最终成品延伸到写作过程本身的绝佳体现。网络上相关的搜索热词如xcolor、soul已经为我们指明了道路。xcolor是LaTeX中功能强大的颜色管理扩展包而soul则是一个专门用于文本装饰如下划线、高亮、删除线的利器。将它们结合使用我们就能在LaTeX源码层面构建一套强大、灵活且可编程的修订高亮系统。这远比依赖外部PDF注释工具来得更根本、更持久因为颜色信息是直接嵌入到你的源文件中的与内容一体永不分离。2. 核心武器库xcolor与soul包深度解析在开始动手之前我们必须先理解手中的工具。很多教程只告诉你怎么用但不知道背后的机制一旦遇到问题就容易抓瞎。这里我们深入看看xcolor和soul这两个包到底提供了什么能力。2.1 xcolor不只是定义颜色xcolor包远不止是\textcolor{red}{文字}这么简单。它是一个完整的颜色管理系统。颜色模型与定义LaTeX本身支持有限的颜色名如red,green,blue,black,white等。xcolor极大地扩展了这一点。它支持多种颜色模型RGB最常用的屏幕显示模型通过红、绿、蓝三原色的强度0-255或0-1定义。例如\definecolor{myred}{RGB}{255, 0, 0}。cmyk印刷用的四分色模型青、品红、黄、黑更适合需要打印的文档。\definecolor{mycyan}{cmyk}{1, 0, 0, 0}。gray灰度单一参数0-1。\definecolor{lightgray}{gray}{0.8}。HTML直接使用网页颜色代码非常方便。\definecolor{myblue}{HTML}{1E90FF}道奇蓝。颜色混合与计算这是xcolor的高级功能能让你动态生成颜色。例如\colorlet{lightblue}{blue!30!white}表示生成一种由70%白色和30%蓝色混合而成的浅蓝色。这个功能在需要一系列深浅不同的高亮色时特别有用。预定义颜色系列xcolor加载时可以使用选项来载入额外的颜色系列比如dvipsnames提供了更多如Apricot、ForestGreen等颜色名。通常我们会在引入包时这样写\usepackage[dvipsnames]{xcolor}。注意颜色定义最好放在导言区\begin{document}之前确保全文一致。对于协同项目建议在共享的样式文件.sty或导言区统一定义所有修订颜色避免每个人用自己的定义导致混乱。2.2 soul文本装饰的“手术刀”soul包的核心命令是\hl高亮和\st删除线但它真正的威力在于其可扩展性。它不像\textcolor那样简单地给文字“刷漆”而是将文本作为一个“对象”进行装饰处理这使其能更稳定地处理换行、分页等复杂情况。工作原理浅析soul通过一个“解析-处理-输出”的过程来工作。它先读取\hl或\st括号内的文本然后将其分解成可处理的单元类似“词”再对每个单元应用你定义的装饰样式最后重新组合输出。这个过程使得它对空格、标点和一些特殊字符的处理需要格外小心。为什么是“手术刀”因为它允许你进行精细的“手术”。你可以通过\sethlcolor{颜色名}来全局设置高亮颜色也可以通过\hl的可选参数进行局部覆盖需配合一些技巧。更重要的是你可以自定义“装饰逻辑”。例如你可以定义一种不仅改变背景色还同时改变字体颜色的高亮样式。主要局限与避坑点命令嵌套\hl内部不能直接嵌套其他\hl或某些复杂命令。解决方案通常是将内部内容用{}分组或使用更稳健的\mbox{}。特殊字符与命令\hl对,%,$数学模式、\cite等命令非常敏感直接放入会报错。标准做法是将要高亮的内容封装在一个简单的\mbox{}盒子中例如\hl{\mbox{特殊内容 $x^2$}}。这是解决绝大多数soul报错的第一选择。长度限制过长的文本块可能导致问题虽然不常见但心理要有数。理解了这两个包我们就知道xcolor提供了“颜料”而soul提供了“画笔”和“绘制规则”。接下来我们就用它们来调配颜料并制定规则。3. 构建你的多色修订系统从定义到实战一套好用的系统需要事先规划。我们不能每次都在正文里临时决定用什么颜色那样会很快陷入混乱。下面是我在多年协作中总结出的一套实践流程。3.1 第一步在导言区进行颜色与命令定义这是最重要的一步相当于建立团队的“颜色宪法”。所有协作者都应遵守。\usepackage[dvipsnames]{xcolor} % 导入xcolor包并载入更多颜色名 \usepackage{soul} % 导入soul包 % 1. 定义一套专用于修订的颜色 % 原则选择对比明显、视觉舒适、在黑白打印下仍有灰度差异的颜色 \definecolor{reviseA}{RGB}{173, 216, 230} % 浅蓝色用于作者A的修改冷静、建议 \definecolor{reviseB}{RGB}{144, 238, 144} % 浅绿色用于作者B的修改通过、安全 \definecolor{reviseC}{HTML}{FFD700} % 金黄色用于待定或需注意的内容警示 \definecolor{reviseDel}{gray}{0.75} % 浅灰色用于已删除内容低调、不喧宾夺主 \definecolor{reviseComment}{RGB}{255, 182, 193} % 浅粉色用于行内注释温和的提示 % 2. 定义高亮命令使用soul % 为每种修订类型创建专用命令语义清晰 \newcommand{\ahighlight}[1]{{\sethlcolor{reviseA}\hl{#1}}} % 作者A高亮 \newcommand{\bhighlight}[1]{{\sethlcolor{reviseB}\hl{#1}}} % 作者B高亮 \newcommand{\chighlight}[1]{{\sethlcolor{reviseC}\hl{#1}}} % 重要待定高亮 \newcommand{\inlinecomment}[1]{{\sethlcolor{reviseComment}\hl{#1}}} % 行内注释 % 3. 定义删除线命令也可用soul的\st这里自定义颜色 \newcommand{\adel}[1]{{\color{reviseDel}\sout{#1}}} % 使用ulem包的\sout命令需引入ulem包 \usepackage{ulem} % 引入ulem包提供\sout等删除线命令 \normalem % 防止ulem包改变\emph的默认行为定义解析与技巧颜色选择避免使用饱和度过高的纯色如纯红、纯蓝长时间阅读容易视觉疲劳。这里选择的都是浅色调既能起到标注作用又不影响正文阅读。dvipsnames选项提供的Aquamarine,BurntOrange等也是不错的选择。命令封装\ahighlight等命令用\newcommand定义将设置颜色和高亮的细节隐藏起来。在正文中你只需要关心语义这是A的修改而不用管技术细节用什么包、颜色名是什么。这极大提升了源码的可读性和可维护性。大括号{}的作用在\newcommand的定义中{\sethlcolor{...}\hl{#1}}外层的大括号至关重要。它将\sethlcolor的颜色设置作用域限制在该命令内部不会影响到后续其他\hl的颜色。这是一个关键细节。3.2 第二步在正文中应用与实战示例定义好命令后在正文中的使用就变得直观且优雅。\section{引言} 近年来深度学习在图像识别领域取得了\ahighlight{突破性}进展。然而传统的卷积神经网络CNN在处理\bhighlight{长距离依赖}关系时仍面临挑战。为此有研究者提出了将注意力机制引入视觉任务的方法\chighlight{具体性能提升数据待补充}。 早期的研究主要集中于\adel{小规模数据集}这限制了模型的泛化能力。后来随着ImageNet等大规模数据集的公开研究者得以训练更深更宽的网络\inlinecomment{这里是否需要引用ResNet原文}从而大幅提升了准确率。编译后的效果“突破性”会有浅蓝色背景高亮。“长距离依赖”会有浅绿色背景高亮。“具体性能提升数据待补充”会有金黄色背景高亮非常醒目。“小规模数据集”会有浅灰色的删除线。“这里是否需要引用ResNet原文”会有浅粉色背景高亮像一个温和的便签。处理复杂内容公式、引用等的黄金法则 当需要高亮的内容包含特殊字符、数学公式或命令时牢记使用\mbox{}或\text{}在数学模式中将其包裹。% 正确做法 模型的损失函数定义为\ahighlight{\mbox{$L -\sum_i y_i \log(\hat{y}_i)$}}。 相关讨论见\bhighlight{\mbox{\cite{vaswani2017attention}}} 一文。 % 错误做法会导致编译错误 % \ahighlight{$L -\sum_i y_i \log(\hat{y}_i)$} % \bhighlight{\cite{vaswani2017attention}}3.3 第三步生成修订记录表可选但推荐对于大型或正式的协作项目在文档末尾或附录添加一个“修订记录表”是专业的表现。这可以帮助所有读者快速理解颜色代码。\section*{修订标记说明} \begin{table}[h] \centering \begin{tabular}{|l|l|l|} \hline \textbf{标记样式} \textbf{颜色/示例} \textbf{含义} \\ \hline 浅蓝色高亮 \ahighlight{示例文本} 由作者A添加或修改的内容 \\ \hline 浅绿色高亮 \bhighlight{示例文本} 由作者B添加或修改的内容 \\ \hline 金黄色高亮 \chighlight{示例文本} 需要重点关注、待确认或待补充的内容 \\ \hline 浅灰色删除线 \adel{示例文本} 已同意删除的旧内容 \\ \hline 浅粉色高亮 \inlinecomment{示例文本} 行内疑问或注释 \\ \hline \end{tabular} \caption{本文档使用的修订颜色标记规则} \end{table}这个表格本身也用到了你定义的颜色命令做到了“所见即所得”非常直观。4. 进阶技巧与深度定制方案基础系统搭建好后我们可以根据更复杂的需求进行定制让这套系统更加强大。4.1 实现“修改气泡”效果有时我们不仅想高亮还想在边栏做一个标记。这可以通过结合todonotes包或marginpar实现。这里展示一个利用marginpar的轻量级方法% 在导言区定义 \newcommand{\marginmark}[1]{\marginpar{\raggedleft\small\color{reviseC}$\triangleright$}} % 在边栏画一个金色三角 % 使用 这是一个普通句子\marginmark{}但这里有个需要复查的地方。更强大的方案是使用todonotes包它可以创建带有颜色、作者、列表的待办事项。4.2 自定义高亮样式边框、圆角等soul的\hl默认是纯色背景填充。如果你想要边框、圆角等效果需要深入到soul的内部命令\soulregister进行注册。这有点复杂但一个常见的需求是“仅加下划线”或“波浪线”。我们可以利用ulem包\usepackage{ulem} \newcommand{\ulhighlight}[1]{\bgroup\markoverwith{\textcolor{reviseA}{\rule[-0.5ex]{2pt}{0.4pt}}}\ULon{#1}\egroup} % 自定义颜色下划线 % 使用 这是一个\ulhighlight{带颜色下划线}的文本。4.3 与版本控制系统Git的协作这是专业工作流的关键。你的LaTeX源文件是纯文本非常适合用Git管理。颜色修订命令会成为你提交信息Commit Message的绝佳补充。提交粒度当你完成一轮针对某个问题的修订例如将所有待确认处补充完毕可以提交一次。提交信息可以写“Fix: 补充了第3节所有\chighlight{}标记的数据”。差异对比Git的diff工具可以清晰显示你添加了哪些\ahighlight{}或删除了哪些\adel{}。这比只看PDF的最终状态更能理解修改过程。分支策略可以为每位审稿人创建一个分支如reviewer-smith。在该分支上用专属颜色如\ahighlight回应这位审稿人的意见。处理完毕后合并回主分支并删除该审稿人分支。整个流程清晰可追溯。4.4 一键切换从“五彩斑斓”到“纯净最终版”文档定稿后我们可能需要提交一个没有各种颜色标记的“干净”版本。手动删除所有\ahighlight{}等命令是灾难性的。正确的做法是使用条件编译。% 在导言区顶部附近定义开关 \newif\ifshowrevisions \showrevisionstrue % 显示修订标记 % \showrevisionsfalse % 注释掉上一行取消注释本行则隐藏修订标记 % 然后修改我们的命令定义 \ifshowrevisions \newcommand{\ahighlight}[1]{{\sethlcolor{reviseA}\hl{#1}}} \newcommand{\adel}[1]{{\color{reviseDel}\sout{#1}}} \else \newcommand{\ahighlight}[1]{#1} % 如果关闭修订显示则直接输出原文 \newcommand{\adel}[1]{} % 如果关闭修订显示则删除线内容完全消失也可改为输出原文 \fi这样你只需要在导言区注释或取消注释一行代码重新编译就能在“修订版”和“纯净版”之间自由切换。对于删除线内容选择直接隐藏{}还是保留{#1}取决于你的需求。5. 常见问题排查与性能优化即使按照最佳实践操作在实际使用中仍可能遇到一些棘手问题。这里汇总了我踩过的坑和解决方案。5.1 编译错误“Argument of \hl has an extra }” 或 “Underfull \hbox”这几乎总是因为\hl内部包含了它无法正确处理的内容。根因\hl在解析参数时遇到了被它误认为是命令结束的字符如}或者遇到了复杂的命令如\cite,\ref、数学模式$...$。标准解决方案使用\mbox{}或\text{}包裹。对于普通文本和简单命令\hl{\mbox{这里有关键词\cite{key123}}}对于数学公式在数学模式内部用\text{}包裹非数学内容但整个高亮单元仍需处理。更稳妥的是\hl{\mbox{$E mc^2$}}。检查列表确保\hl的参数用一对完整的大括号{}括起来。检查内部是否有未配对的大括号。将所有宏命令、引用、公式用\mbox{}包裹。5.2 高亮区域断行异常或背景色错位有时高亮会在单词中间断开或者背景色延伸到行尾之外看起来不整齐。原因soul的断词算法和LaTeX的断行机制在某些边缘情况下配合不佳。解决方案微调断词点在长单词或特定位置插入\-允许断词的连字符或\linebreak[0]允许在此断行但无惩罚。使用\sloppy命令在受影响段落前使用\sloppy让LaTeX更宽松地处理断行可能会改善高亮框的显示。但需谨慎它可能使其他地方的间距变丑。终极方案——换用soulutf8包如果问题频繁且严重可以考虑换用soulutf8包需配合XeLaTeX或LuaLaTeX编译它对Unicode和复杂内容的支持更好。用法与soul几乎完全相同。5.3 颜色在打印的PDF中显示不正常或过深屏幕上看起来柔和的颜色打印出来可能太深或识别困难。预防在定义颜色时优先使用CMYK模型因为它专为印刷设计。\definecolor{reviseA}{cmyk}{0.1, 0, 0, 0}定义的青色系颜色打印效果更可预测。检查用PDF阅读器的“模拟打印”或“输出预览”功能查看CMYK分色效果。灰度备份对于重要的、必须黑白打印的文档确保你选择的颜色在转换成灰度后仍有明显区别。可以用\usepackage[gray]{xcolor}临时切换为灰度模式测试。5.4 与其它包如hyperref, listings的冲突soul和hyperref用于生成超链接的加载顺序很重要。hyperref包通常会重定义许多内部命令因此它应该几乎总是最后一个被加载的包除了极少数例外如cleveref。% 正确的加载顺序 \usepackage{soul} \usepackage{hyperref} % hyperref 放在最后如果与listings代码高亮包一起使用一般没有直接冲突但要注意不要用\hl去高亮lstlisting环境内的代码这几乎肯定会失败。代码的高亮应使用listings包自带的样式设置功能。构建这样一套多颜色LaTeX修订系统初期需要一些投入来定义规范和命令但一旦建立它将成为你团队协作的无价之宝。它让修改过程可视化、可讨论、可追溯将混乱的修订过程变得井然有序。最重要的是所有的信息都保存在源文件中与你的内容同在不会因为格式转换而丢失。这或许就是坚持使用LaTeX这类“内容与样式分离”工具的魅力之一你对文档的控制可以深入到创作过程的每一个细节。
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻