我正在使用一种缺少许多常见字符的显示字体,包括括号、破折号和真正的“方向引号”。
我希望有一种直接的方法来替换遇到的字符,即用另一种字体中设置的匹配字符。一般来说,“如果主字体缺少此字符,则使用其他字体”就可以了,但我可以识别我关心的所有字符。我不需要更改字符;如果缺少的字符是“(”,则后备字体中将是 (。我只在有限的情况下使用该字体(memoir 中的 \chapter 和 \section),这可能会使问题更容易或更难。同样,涉及的所有字体都是 TrueType/OpenType。
新unicode字符和字符类看起来很有希望,但前者不会干扰 ASCII 字符,而后者只对整个 Unicode 块有效。
XeTeX 的 interchar 类机制看起来很有前景,这是我的 B 计划。但我更喜欢一些更便携的东西,哪怕只是在 XeLaTeX 和 LuaLaTex 之间。
最小工作示例,依赖于免费 Cyberfunk 字体。
\documentclass{article}
\usepackage{fontspec}
\begin{document}
``Dr. J---/Mr. H---'s (Missing Glyph) Day''
\fontspec{Cyberfunk}``Dr. J---/Mr. H---'s (Missing Glyph) Day''
\end{document}
如果有帮助的话,我可以提供一个更长、更现实的例子来说明我是如何在回忆录中使用它的;但是这需要很长的时间。
答案1
您可以在这里设置一个标记循环来搜索丢失的字形,并用替代字体的字形替换它们,这里采用 Calibri。
在这里,我擅自搜索并替换了以下字形/字符串:(
,,,,,,,和。)
‘
'
/
-
--
---
请注意,在 token 循环内更改 catcode 并不容易,因为 token 在执行之前会使用当前 catcode 进行扫描。例如,这会影响逐字块。
\documentclass{article}
\usepackage{fontspec,tokcycle}
\newif\ifemdash
\newif\ifendash
\newcommand\dashtest{\emdashfalse\endashfalse\tcpeek\Q
\ifx-\Q\tcpop\Q\tcpeek\QQ\ifx-\QQ\tcpop\QQ\emdashtrue\else
\endashtrue\fi\fi
}
\Characterdirective{%
\ifx(#1\addcytoks{{\setmainfont{Calibri}(}}\else
\ifx)#1\addcytoks{{\setmainfont{Calibri})}}\else
\ifx`#1\addcytoks{{\setmainfont{Calibri}`}}\else
\ifx'#1\addcytoks{{\setmainfont{Calibri}'}}\else
\ifx/#1\addcytoks{{\setmainfont{Calibri}/}}\else
\ifx-#1\dashtest
\ifemdash\addcytoks{{\setmainfont{Calibri}---}}\else
\ifendash\addcytoks{{\setmainfont{Calibri}--}}\else
\addcytoks{{\setmainfont{Calibri}-}}\fi\fi
\else
\addcytoks{#1}\fi\fi\fi\fi\fi\fi
}
\begin{document}
``Dr. J---/Mr. H---'s (Missing Glyph) Day''
Endash -- and Hyphen -
\setmainfont{Cyberfunk}
\tokencyclexpress
``Dr. J---/Mr. H---'s (Missing Glyph) Day''
Endash -- and Hyphen -
\endtokencyclexpress
\end{document}
循环中处理的标记会被缓冲,并在循环结束时输出。如果标记循环非常大(例如,包含整个文档),并且担心超出内部缓冲区大小,则可以通过\par
添加 来指示标记循环在每次取消分组后清除缓冲区,\Macrodirective
如下所示:
\Macrodirective{
\addcytoks{#1}\ifnum\tcdepth=0
\ifx\par#1\the\cytoks\cytoks{}\fi
\fi% CLEARS BUFFER ON UNGROUPED \par
}