我不喜欢\textperiodcentered
OpenType 中 Latin Modern 字体的 U+00B7 间距。与 Computer Modern 不同(事实上,与我系统上的任何字体都不同),LM 为字符提供了相当宽的侧边距。无论如何,我认为这是个错误,因此已将其报告给 Bogusław Jackowski等在阵风。
但是,在我等待 Jacko 修复这个问题的同时,LuaTeX 字体修补(参见,例如,非侵入式字距/间距修改:有哪些选项?) 可用于在运行时调整此字符的侧边距吗?如何实现此类修补?
(通过实验,我确定点两侧的字距为 -0.25em 时,其间距与句点“。”相同,所以这就是我想要削减字形边界框的量。)
下面的代码说明了这个问题。在我的实际代码中,我使用的是 Unicode 中点 (U+00B7) “·”,并且它的使用是在宏中,该宏的定义被复制\cs_set_eq:
到另一个宏中(通过),因此重新定义\textperiodcentered
和重新定义都\newunicodechar
无法直接提供帮助。(这是我的代码存在问题,我将修复它;上面的问题对我来说仍然很有趣。)
\documentclass{article}
\newif\ifot\ottrue
\ifot
\usepackage{fontspec} % uses LM OpenType
\fi
\begin{document}
\ifot LMRoman OTF: \else Computer Modern: \fi
800\textperiodcentered 555\textperiodcentered 1212
\end{document}
\ottrue
两次单独运行(第一次使用,第二次使用)的结果\otfalse
如下:
Computer Modern 版本在印刷上是正确的,或者至少与使用任何其他字体的结果相似。尝试在任何应用程序中渲染文本“800·555·1212”(使用 U+00B7“·”),将 LMRoman 与其他字体进行比较;它很少有如此宽的侧边距。(Lucida 字体,例如,本网站上使用的,是我见过的其他的。)
答案1
答案2
如果在 textcomp 的帮助下使用 real char,则可以获得与 type1 lmodern 相同的间距:
\documentclass{article}
\usepackage{lmodern} % uses LM Type1
\usepackage[T1]{fontenc}
\usepackage{textcomp}
\begin{document}
800\textperiodcentered 555\textperiodcentered 1212
\end{document}
答案3
LM Type1 字体有 U+00B7,type1 字体中的字符可以显示为 OpenType 版本。例如:
\documentclass{article} \usepackage{lmodern} \begin{document} 800\char189 555\char189 1212 \end{document}
该命令的
\textperiodcentered
作用与\cdot
文本模式相同。这两个命令映射到同一个字符。% filename: test.tex \documentclass{article} \usepackage{lmodern} \pagestyle{empty} \begin{document} \textperiodcentered$\cdot$ \end{document}
使用
pdffonts test.pdf
PDF 输出中获取字体的信息:name type emb sub uni object ID ------------------------------------ ----------------- --- --- --- --------- SQTJQN+LMMathSymbols10-Regular Type 1 yes yes no 4 0
所以,这不是字体的错误,而是字符映射的错误。
答案4
让我们做一些实验texdef
:
> texdef -t latex textperiodcentered
\textperiodcentered:
macro:->\OMS-cmd \textperiodcentered \OMS\textperiodcentered
> texdef -t latex -p textcomp textperiodcentered
\textperiodcentered:
macro:->\TS1-cmd \textperiodcentered \TS1\textperiodcentered
这是什么意思?我们慢慢来。诸如\<dENC>-cmd
where<dENC>
是已知编码的大写名称之类的命令会检查该命令是否<cENC><arg>
已定义、where<cENC>
是当前编码以及<arg>
是之后的第一个标记\<dENC>-cmd
(“d” 表示“默认”)。如果是,则<cENC><arg>
使用,否则<dENC><arg>
使用。
示例(我将跳过不重要的细节)。LaTeX 将\textperiodcentered
其扩展为
\OMS-cmd \textperiodcentered \OMS\textperiodcentered
如果当前编码是OT1
(如您的\otfalse
设置),LaTeX 会尝试查看是否已\OT1\textperiodcentered
定义(如果不使用一些技巧,则无法发出该命令,内部反斜杠是名称的一部分),但未定义。因此,将遵循“默认分支”,这相当于执行
{\fontencoding{OMS}\selectfont \OMS\textperiodcentered}
因此\char"1
从与 OMS 编码相关的字体进行打印,通常是数学符号字体,它没有在数学中自动添加的边距。
如果当前编码是EU1
(如您的\ottrue
设置),则检查定义性\EU1\textperiodcentered
成功,因此所做的只是
\EU1\textperiodcentered
没有任何不必要的分组,以\char"00B7
当前字体打印。此字形具有由字体设计者选择的侧边距。
所做textcomp
的就是将与 关联的默认编码更改\textperiodcentered
为TS1
,但效果类似;唯一的区别是默认将使用来自文本伴随字体的字符。
如果您想要更改 的工作方式,只需修改其针对(XeLaTeX) 或(LuaLaTeX) 编码\textperiodcentered
的定义即可。宏将扩展为正确的编码。EU1
EU2
\encodingdefault
\documentclass{article}
\usepackage{fontspec}
\AtBeginDocument{%
\DeclareTextCommand{\textperiodcentered}{\encodingdefault}{\kern-.25em\char"00B7\kern-.25em }%
}
\begin{document}
800\textperiodcentered 555\textperiodcentered 1212
\end{document}
总之,这绝对不是一个错误,而是预期的行为。OpenType 字体可以有一个“U+2E31 WORD SEPARATOR MIDDLE DOT”字符,它没有侧边距(恐怕不是 Latin Modern OT)。
其他字体的居中间隔较小;一个很好的猜测似乎是宽度为 0.25em,如以下示例所示:
\documentclass{article}
\usepackage{fontspec}
\usepackage{xparse}
\NewDocumentCommand{\periodsep}{}{\makebox[.25em]{\symbol{"00B7}}}
\begin{document}
\newcommand{\test}{800\periodsep 555\periodsep 1212\par
800\symbol{"00B7}555\symbol{"00B7}1212\par\medskip}
\test
\fontspec{Linux Libertine O}\test
\fontspec{TeX Gyre Termes}\test
\fontspec{TeX Gyre Pagella}\test
\end{document}
如果您的应用程序不直接使用该字符,而是通过宏生成它,这似乎是最好的方法。
\periodsep
或者,你可以接受中心周期的任何宽度,除非它超过固定阈值,方法是将的定义更改为
\NewDocumentCommand{\periodsep}{}
{%
\ifdim\fontcharwd\font"00B7>.3em % threshold value
\makebox[.25em]{\symbol{"00B7}}%
\else
\symbol{"00B7}%
\fi
}