多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

LaTeX中优雅输出钩号与叉号:方案对比与实战指南

LaTeX中优雅输出钩号与叉号:方案对比与实战指南 1. 为什么要在文档里折腾钩和叉写文档这件事最让人抓狂的往往不是内容本身而是那些看起来微不足道的符号。你辛辛苦苦排好了一篇技术报告或者一份检查清单结果到了要标记通过和未通过的地方发现键盘上根本找不到一个像样的钩和叉。直接打字母v和x吧放在正文里显得特别随意跟周围精致的排版格格不入用输入法自带的特殊符号吧又经常遇到字体不匹配、大小不一致、复制到别的设备上变成方框的尴尬情况。这个需求在LaTeX写作场景里尤其突出。LaTeX的排版质量是公认的数学公式、表格、交叉引用都处理得干净利落但偏偏就是这种打个钩画个叉的小事让不少刚接触LaTeX的朋友卡住了。我见过太多人在文档里用\checkmark结果编译报错或者用\times画出来的叉跟钩风格完全不搭一个粗一个细一个圆润一个尖锐放在同一行里看着就难受。这篇文章要解决的问题很具体在LaTeX文档中如何优雅、稳定、风格统一地输出钩号和对号也就是打勾以及叉号也就是打叉。不管你是写项目检查清单、做实验记录表、整理待办事项还是给文档做批注标记这套方法都能直接用上。我会从最基础的符号命令讲起一路讲到不同场景下的选型策略、字体兼容性处理、以及我这些年踩过的各种坑。哪怕你昨天才装好LaTeX环境跟着走一遍也能在自己的文档里把钩和叉安排得明明白白。2. 钩和叉的符号来源与底层逻辑2.1 两个符号在Unicode里的身份证要搞清楚LaTeX里怎么打出钩和叉得先知道这两个符号在字符编码体系里的位置。钩号在Unicode里的正式名称叫Check Mark码位是U2713对应的HTML实体是#10003;。叉号的情况稍微复杂一点因为叉有好几种不同的形态有细长的乘号U00D7也就是×有粗壮的叉号U2717也就是✗还有更粗的 ballot XU2718也就是✘。这三个东西看起来都是叉但用途和视觉效果差别很大。为什么要在意这个区别因为LaTeX里不同的命令调用的就是不同的Unicode码位。\times输出的是数学乘号\checkmark输出的是钩号而\XSolidBrush之类的命令又是另一套。如果你在文档里混用就会出现这个叉是数学符号那个叉是装饰符号的割裂感。我个人的经验是如果钩和叉是成对出现的比如清单里的完成/未完成那它们必须来自同一套符号体系视觉重量要匹配。2.2 为什么LaTeX默认没有内置钩号很多人第一次在LaTeX里尝试打钩会本能地敲\checkmark然后发现编译报错说Undefined control sequence。这不是你的错而是LaTeX核心确实没有定义这个命令。原因要追溯到TeX的诞生年代——那个时代的排版系统主要面向数学和科技文献钩号这种手写标记类的符号并不在核心符号表里。钩号最早是由amssymb宏包引入的这个宏包是美国数学学会提供的扩展符号集。它里面定义了\checkmark命令输出的是U2713。但问题在于amssymb的字体是数学字体钩号的线条偏细跟正文的衬线字体放在一起有时候会显得飘。后来dingbat宏包、pifont宏包、fontawesome5宏包都提供了各自的钩号实现风格各不相同。这就是为什么你在网上搜LaTeX打钩会看到五花八门的方案——它们背后用的是不同的字体和宏包。2.3 叉号的三种常见实现路径叉号在LaTeX里的实现路径比钩号更多样。第一种是数学模式下的\times输出的是乘号线条细、角度标准适合跟数学公式混排。第二种是\texttimes在文本模式下输出乘号但需要textcomp宏包支持。第三种是pifont宏包里的\ding{55}输出的是装饰性的粗叉视觉重量大适合做清单标记。这三种叉的选用逻辑是这样的如果你的文档里钩和叉是对等的标记符号那叉应该选跟钩视觉重量相近的版本。\checkmark配\times会显得钩粗叉细\checkmark配\ding{55}又可能钩细叉粗。最稳妥的做法是钩和叉都从同一个宏包里取比如都用pifont的\ding{51}和\ding{55}或者都用fontawesome5的对应图标。这个原则我在后面会反复强调因为它直接决定了文档的视觉专业度。3. 主流实现方案全对比3.1 amssymb方案最轻量的选择amssymb是绝大多数LaTeX发行版都预装的宏包调用方式极其简单\usepackage{amssymb} ... \checkmark这个方案的优点是零配置、编译快、兼容性好。钩号的线条偏细跟Computer Modern字体的正文搭配起来有一种学术感。缺点是它只提供了钩号没有配套的叉号。你要打叉还得另外找命令这就破坏了符号体系的一致性。我早期写文档一直用这个方案后来发现一个问题\checkmark在某些字体下会显得特别小跟正文的x-height不匹配。如果你用的是\large或\Large字号钩号不会跟着放大看起来就像个蚂蚁趴在纸上。解决办法是用\scalebox手动放大但那样又引入了graphicx宏包增加了依赖。3.2 pifont方案风格最统一的组合pifont宏包提供了一整套Zapf Dingbats符号其中\ding{51}是钩号\ding{55}是叉号。这两个符号来自同一套字体线条粗细、大小、风格完全一致放在一起非常协调。\usepackage{pifont} ... \ding{51} % 钩 \ding{55} % 叉这个方案是我目前最推荐的原因有三第一钩和叉天然配对不需要额外调整第二符号的视觉重量适中既不会太细也不会太粗第三pifont宏包稳定成熟几乎所有的LaTeX发行版都自带。不过有一个细节要注意\ding{51}和\ding{55}的基线位置跟正文文字不完全对齐有时候会显得偏高或偏低。如果是在表格里使用可能需要用\raisebox微调。我一般会在导言区定义一个快捷命令来处理这个对齐问题后面会详细讲。3.3 fontawesome5方案图标化的现代风格如果你追求更现代的视觉效果fontawesome5宏包提供了\faCheck和\faTimes两个命令输出的是矢量图标风格的钩和叉。这个方案的优点是符号清晰锐利缩放不失真而且可以方便地调整颜色和大小。\usepackage{fontawesome5} ... \faCheck \faTimes缺点是fontawesome5宏包体积较大编译时会明显拖慢速度。而且图标的风格偏网页感放在传统的学术文档里可能显得不够正式。我一般只在做演示文稿或者非正式文档时才用这个方案。3.4 三种方案的关键参数对比对比维度amssymbpifontfontawesome5钩号命令\checkmark\ding{51}\faCheck叉号命令无内置\ding{55}\faTimes风格统一性差需另找叉号优优编译速度快快较慢符号粗细细中中粗缩放表现不跟随字号不跟随字号可调适用场景学术论文通用文档演示文稿这个表格里的缩放表现一栏需要特别说明amssymb和pifont的符号都是固定大小的不会随着\Large之类的字号命令自动放大。如果你在标题里用钩号会发现它比周围的文字小很多。解决办法是用\scalebox{1.5}{\ding{51}}手动放大但这样又需要graphicx宏包。fontawesome5的图标可以通过\faIcon[scale1.5]之类的参数调整相对灵活一些。4. 手把手实操从零搭建一个带钩叉的检查清单4.1 最小可用示例的完整代码先来看一个最简化的例子把钩和叉放进一个表格里模拟检查清单的效果。这段代码可以直接复制到Overleaf或者本地编辑器里编译\documentclass[11pt]{article} \usepackage[margin2.5cm]{geometry} \usepackage{pifont} \usepackage{array} % 定义带颜色的钩和叉 \newcommand{\cmark}{\ding{51}} \newcommand{\xmark}{\ding{55}} \begin{document} \section*{项目检查清单} \begin{tabular}{clc} \hline \textbf{序号} \textbf{检查项} \textbf{状态} \\ \hline 1 文档结构完整性 \cmark \\ 2 参考文献格式 \cmark \\ 3 图表编号一致性 \xmark \\ 4 公式符号统一性 \cmark \\ 5 附录材料齐全 \xmark \\ \hline \end{tabular} \end{document}这段代码编译出来的效果是一个三列表格最后一列显示钩或叉。\cmark和\xmark是我自定义的快捷命令这样在正文里写起来更顺手而且以后想换符号风格只需要改导言区的一行定义。4.2 让钩和叉带上颜色纯黑色的钩和叉有时候不够醒目尤其是做检查清单的时候绿色的钩和红色的叉能让人一眼看出状态。给符号上色需要xcolor宏包\usepackage{xcolor} \newcommand{\cmark}{\textcolor{green!70!black}{\ding{51}}} \newcommand{\xmark}{\textcolor{red!80!black}{\ding{55}}}这里我用了green!70!black而不是纯green原因是纯绿色的饱和度太高在屏幕上看着刺眼打印出来也偏亮。混入30%的黑色之后颜色变得沉稳跟正文的黑色文字搭配更和谐。红色的处理同理red!80!black比纯红更耐看。注意如果你的文档最终要打印成黑白稿颜色区分就失效了。这种情况下建议在钩和叉旁边加上文字标注比如通过和未通过不要只依赖符号本身。4.3 在表格中精确对齐钩和叉pifont的符号在表格单元格里经常会出现垂直对齐问题——符号偏上或偏下跟同一行的文字不在一条基线上。这个问题的根源是\ding命令输出的符号基线跟正文基线不一致。解决办法是用\raisebox手动调整\newcommand{\cmark}{\raisebox{-0.1ex}{\ding{51}}} \newcommand{\xmark}{\raisebox{-0.1ex}{\ding{55}}}-0.1ex这个值是我反复试出来的对于11pt的正文大小下移0.1ex正好让符号跟文字视觉居中。如果你用的是10pt或12pt这个值可能需要微调。调整的方法很简单编译一次用PDF阅读器的放大功能看符号和文字的基线关系偏上就减小负值偏下就增大负值。4.4 处理部分完成的中间状态实际项目中检查项的状态往往不是非黑即白的完成或未完成还有进行中、待确认之类的中间状态。这时候可以用一个空心方块或者斜杠钩来表示。pifont里没有现成的斜杠钩但可以用\ding{51}叠加一个斜线来实现\newcommand{\pmark}{\raisebox{-0.1ex}{\ding{51}\llap{\textcolor{red}{\rule{0.8em}{0.4pt}}}}}这段代码的思路是先画钩号然后用\llap在钩号上面叠一条红色横线。\rule{0.8em}{0.4pt}是一条宽0.8em、高0.4pt的横线颜色设为红色。实际效果就是一个被划掉的钩表示部分完成或已取消。这个技巧我在做项目进度表的时候经常用比单纯的空格或者问号直观得多。5. 不同场景下的选型策略与避坑指南5.1 学术论文场景低调优先学术论文的排版规范通常比较严格钩和叉不能太花哨。这种情况下我推荐用amssymb的\checkmark配\times虽然风格略有差异但都是数学符号体系里的东西审稿人看着不会觉得突兀。如果期刊模板已经加载了amssymb那就直接用不需要额外引入宏包。有一个坑要注意部分期刊的模板会重定义\checkmark命令或者用newtxmath之类的数学字体宏包替换了默认的符号字体。这种情况下\checkmark的输出可能跟你预期的不一样。解决办法是在导言区加一行\let\oldcheckmark\checkmark备份原始命令如果发现符号不对可以回退到\oldcheckmark。5.2 项目文档场景清晰优先项目文档、检查清单、进度表这类场景钩和叉的辨识度比风格统一更重要。我推荐用pifont方案配合颜色区分。如果文档要在会议上投影展示可以把符号放大到\Large或\LARGE让后排的人也能看清。这里有一个实操心得在表格里用钩叉的时候把符号列单独设成一列不要跟文字混在同一格。比如文档结构完整性 \cmark这种写法符号会紧跟在文字后面对齐全靠运气。正确的做法是表格分三列检查项、状态符号、备注。符号单独占一列用c格式居中这样无论文字多长符号都在同一垂直线上。5.3 演示文稿场景视觉冲击优先做Beamer演示文稿的时候钩和叉可以更大胆一些。fontawesome5的图标在投影仪上显示效果很好而且可以用\faCheck和\faTimes配合\textcolor做出醒目的效果。如果想让钩号有弹出来的感觉可以用tikz画一个带阴影的钩但那样代码复杂度会上升不少。Beamer里有一个特殊的坑某些主题会重定义itemize环境的符号如果你在列表里用钩号作为item marker可能会跟主题的默认设置冲突。解决办法是用\setbeamertemplate{itemize item}{\cmark}显式指定而不是依赖默认行为。5.4 跨平台兼容性避坑LaTeX文档经常需要在不同的编译引擎之间切换pdfLaTeX、XeLaTeX、LuaLaTeX不同引擎对符号字体的处理方式不一样。pifont在pdfLaTeX下表现稳定但在XeLaTeX下如果用了fontspec宏包自定义字体\ding命令可能会失效或者显示成方框。这个问题的根源是pifont依赖Type1字体而XeLaTeX默认使用OpenType字体。解决办法有两个一是改用fontawesome5它对新引擎的支持更好二是在XeLaTeX下显式加载pifont的Type1字体映射。我一般推荐第一个方案因为fontawesome5的跨引擎兼容性确实更省心。还有一个常见的坑是复制粘贴问题\ding{51}编译出来的PDF里钩号是一个图形字符复制出来可能变成乱码或者空白。如果你的文档需要让别人复制里面的内容最好在钩号旁边保留文字说明或者用accsupp宏包给符号加上可复制的文本替代。6. 常见问题排查与独家技巧实录6.1 编译报错Undefined control sequence怎么办这是最常见的问题99%的情况是忘记加载宏包了。\checkmark需要amssymb\ding需要pifont\faCheck需要fontawesome5。检查导言区有没有对应的\usepackage命令。如果已经加载了还是报错可能是宏包冲突——比如amssymb和mathabx同时加载会打架。这种情况下把冲突的宏包去掉一个或者用\let命令重定义。6.2 钩号显示成方框或乱码这个问题通常出现在XeLaTeX或LuaLaTeX下原因是当前字体没有包含钩号的字形。解决办法是换用fontawesome5或者用\setmainfont指定一个包含钩号的字体。如果不想换字体可以用\usepackage{newunicodechar}配合\newunicodechar{✓}{\ding{51}}手动映射。6.3 钩和叉大小不一致这是混用不同宏包导致的。比如钩用amssymb的\checkmark叉用pifont的\ding{55}两者的设计尺寸本来就不一样。解决办法是统一到一个宏包或者用\scalebox手动调整其中一个的大小。我一般会在导言区定义两个命令把大小调成一致\newcommand{\cmark}{\scalebox{1.2}{\ding{51}}} \newcommand{\xmark}{\scalebox{1.0}{\ding{55}}}这里的1.2和1.0是我根据实际视觉效果调出来的不同字体可能需要不同的比例。调整的原则是让两个符号的视觉重量不是实际尺寸看起来差不多。6.4 表格里钩叉导致行高异常\ding命令输出的符号高度可能超过正文的行高导致表格行被撑高看起来不整齐。解决办法是用\smash命令把符号的高度压扁\newcommand{\cmark}{\smash{\raisebox{-0.1ex}{\ding{51}}}}\smash告诉LaTeX忽略这个符号的高度和深度这样表格行高就由文字决定不会被符号撑开。但要注意如果符号本身很大\smash之后可能会跟上下行的内容重叠。这种情况下需要手动增加行距或者把符号缩小一点。6.5 常见问题速查表问题现象可能原因解决方法编译报错Undefined未加载宏包加载amssymb/pifont/fontawesome5符号显示为方框字体缺字形换fontawesome5或指定字体钩叉大小不一混用宏包统一宏包或scalebox调整表格行高异常符号撑高行用smash压扁符号偏上/偏下基线不对齐raisebox微调复制出来是乱码图形字符加accsupp文本替代XeLaTeX下失效Type1字体不兼容改用OpenType图标宏包6.6 一个我用了五年的导言区配置最后分享一段我几乎每个文档都会用的导言区配置把钩和叉的定义、颜色、对齐都封装好了直接复制就能用\usepackage{pifont} \usepackage{xcolor} \usepackage{graphicx} \newcommand{\cmark}{\smash{\raisebox{-0.1ex}{\textcolor{green!70!black}{\ding{51}}}}} \newcommand{\xmark}{\smash{\raisebox{-0.1ex}{\textcolor{red!80!black}{\ding{55}}}}} \newcommand{\pmark}{\smash{\raisebox{-0.1ex}{\ding{51}\llap{\textcolor{red}{\rule{0.8em}{0.4pt}}}}}}这段配置的好处是钩和叉来自同一套字体风格统一颜色沉稳不刺眼基线对齐处理好了还额外提供了一个部分完成的标记。\smash保证了在表格里不会撑高行距\raisebox解决了垂直对齐问题。你唯一需要根据自己文档调整的可能就是-0.1ex这个值如果发现符号偏上就改成-0.15ex偏下就改成-0.05ex。我在实际使用中发现这套配置在pdfLaTeX下表现最稳定XeLaTeX下如果遇到问题把pifont换成fontawesome5的\faCheck和\faTimes即可其他部分不用动。另外提醒一句如果你的文档要提交给期刊或出版社最好先确认他们的模板是否允许自定义命令有些严格的模板会拒绝编译包含\newcommand的文档。这种情况下就把定义直接内联到使用的地方虽然麻烦一点但能保证顺利通过。
返回列表