我已重新定义\textbullet
它以使其稍微大一些(因为 Libertinus 字体使用的字符与 Computer Modern 等效字符相比非常小),如下所示:
\documentclass[11pt]{report}
\usepackage{libertinus}
% Resize \textbullet to make it a bit larger (closer to Computer Modern)
\let\oldbullet\textbullet
\renewcommand*\textbullet{{\large\oldbullet}}
\begin{document}
\oldbullet\textbullet$\mathord\bullet$
\end{document}
就实现我的主要目标而言,这很好(\textbullet
现在生成一个稍大一点的版本)。我不明白的是为什么\oldbullet
也显示更大?我期望\oldbullet
生成一个小项目符号并\textbullet
生成一个稍大一点的项目符号,因为我认为使用\let
定义\oldbullet
为与原来的的定义\textbullet
。显然,这里的情况并非如此。
我试图查看 LaTeX 源文件 ( \DeclareUnicodeCharacter{2022}{\textbullet}
) 和\show
定义 ( ->\?-cmd \textbullet \?\textbullet .
),但我不太明白它们的含义......
关于我下一步应该看哪里,有什么指示吗?
答案1
这里发生的情况是,的定义\textbullet
在使用时查找了几件事,因此尝试用保存符号会\let
失败。
修复
如果您在现代引擎(例如 LuaLaTeX 或 XeLaTeX)中进行编译,该libertinus
包将加载fontspec
、unicode-math
以及文本和数学字体的 Unicode 版本。
这些字体支持 Unicode 符号 ⚫、•、∙ 等。它甚至为它们unicode-math
定义了宏\vysmblkcircle
、\smblkcircle
、\mdblkcircle
等。Libertinus 字体有一些但不是全部,因此如果您想重新定义\textbullet
为更大的字体,您需要首先选择包含它的字体。我选择了 DejaVu Sans。
如果您在传统的 TeX 引擎(例如 PDFLaTeX)中进行编译,则需要定义TS1 编码的\oldbullet
插槽(本质上是复制中的旧定义,而不是在现代 LaTeX 内核中保存更复杂的命令)。如果您要使用不附带 TS1 扩展的字体,则需要定义以选择字体系列和编码以及字体大小。由于您使用的是其他字体包,所以这不是问题。"88
\textbullet
textcomp
\textbullet
libertinus
但是,您并不想总是选择\large
大小,即使在脚注中也是如此。您更可能希望符号比当前字体大一号。您可以使用 来实现这一点relsize
。
一个样品:
\tracinglostchars=2 % Print a warning to the console if a character is missing.
\documentclass[11pt]{report}
\usepackage{iftex}
\usepackage{libertinus}
\ifTUTeX
% The libertinus package loaded fontspec and unicode-math, with Libertinus
% Math as the math font.
\newfontfamily\symbolfont{DejaVu Sans}[Scale=MatchLowercase]
\DeclareTextSymbol{\oldbullet}{\UnicodeEncodingName}{"2022}
\DeclareTextSymbolDefault{\oldbullet}{\UnicodeEncodingName}
\renewcommand\textbullet{{\symbolfont\symbol{"26AB}}}
\else
% The libertinus package loaded the legacy Type 1 font.
\usepackage[T1]{fontenc}
\usepackage[libertine]{newtxmath}
\usepackage{relsize}
\DeclareTextSymbol{\oldbullet}{TS1}{"88}
\DeclareTextSymbolDefault{\oldbullet}{TS1}
\renewcommand\textbullet{{\larger\oldbullet}}
\fi
\begin{document}
\oldbullet\textbullet$\mathord\bullet$
\end{document}
\textbullet
如果您还希望 U+2022在文本模式和数学模式下等效\bullet
,您可以添加类似内容:
\usepackage{newunicodechar}
\newunicodechar{^^^^2022}{\ifmmode\bullet\else\textbullet\fi}
这是怎么回事?
LaTeX 内核\textbullet
使用三种不同的编码之一进行声明:来自 TS1 8 位编码的旧符号、来自 OMS 7 位编码的更古老的旧符号以及 Unicode 符号。这意味着命令\textbullet
无法提前知道将使用哪种字体或编码,并且尝试使用 保存定义然后\let
重新定义\textbullet
将无法按预期工作。
历史原因在于,子弹运算符在 80 年代首次被定义为数学符号。1996 年,Jörg Knappen 定义了一种文本符号编码 TS1,作为新 T1 Cork 编码的配套。然而,当时大多数可用的字体仅支持不到一半的 TS1。作为一种错误解决方法,在接下来的二十年里,LaTeX 作者会加载该textcomp
包,它会尝试检测当前字体支持的符号,并在必要时回退到 poor-man 版本。
不再需要加载单独的包:此代码现在位于 LaTeX 内核中。
该定义记录在 LaTeX2e 源代码的 §20.4.1 中。相关部分是\DeclareTextCommand
扩展为代码,该代码检查当前编码以及我们是否处于数学模式。这指的是\?\textbullet
由 定义的\DeclareTextCommandDefault
,它最终以递归方式展开。
答案2
发生这种情况是因为您刚刚定义了顶层\oldbullet
,然后它扩展为\?-cmd \textbullet \?\textbullet
,最终扩展为您重新定义\textbullet
的\large\oldbullet
。
正如评论中提到的那样,这基本上与强命令的问题相同:它们不是一个宏,而是一组与顶级宏同名的宏,当您重新定义一个宏时,您必须重新定义它们全部,否则您会看到不必要的行为(但是,这并未包括在内letltxmacro
)。
要做您想做的事情,您可以不用将定义复制\textbullet
到新名称,而是可以采用与 LaTeX\oldbullet
相同的方式进行声明:\textbullet
\DeclareTextSymbol{\oldbullet}{TS1}{136}
\DeclareTextSymbolDefault{\oldbullet}{TS1}
第一行表示该命令将从当前字体的编码中\oldbullet
获取字符编号,第二行表示的默认编码是,因此 LaTeX 会在必要时更改编码以使用该符号(否则符号将始终使用当前编码,无论它是哪种编码)。136
TS1
\oldbullet
TS1
然后就可以\textbullet
正常重新定义:
\documentclass[11pt]{report}
\usepackage{libertinus}
% Resize \textbullet to make it a bit larger (closer to Computer Modern)
\DeclareTextSymbol{\oldbullet}{TS1}{136}
\DeclareTextSymbolDefault{\oldbullet}{TS1}
\renewcommand*\textbullet{{\LARGE\oldbullet}}
\begin{document}
\oldbullet\textbullet$\mathord\bullet$
\indent\kern1pt\raise5pt\hbox{$\smile$}
\end{document}