宏有什么方法可以知道下列任一项吗?
- TeX 从源文件中读取的最后一个可打印字符
- TeX 生成的最后一个字符框的内容
理由:我正在开发一个 XeLaTeX 软件包,它将支持 Stone Sans Phonetic,这是一种旧的商业 IPA 字体。Stone Sans Phonetic 是在 Unicode 时代之前创建的,并使用连字而不是组合字符——也就是说,ø̂在页面上,您编写代码来并排打印字符ø
,^
并且字体具有将它们组合在一起的连字符。
不幸的是,有些连字符缺失。例如,打印n
和^
并排不会n̂在页面上。
那么,我想要做的是使用\newunicodechar
Unicode 组合脱字符触发执行以下操作的宏:
- 确定其左侧的字符是否是能够与 产生连字的字符
^
。 - 如果是,则以
^
Stone Sans Unicode 打印。 - 如果不是,则使用某些后备字体打印一个结合 Unicode 的抑扬符。
这可行吗?
(FWIW,我本来期望\lastbox
做我想要的事情,但是这个代码
\documentclass{article}
\begin{document}
\newbox\temp
a\setbox\temp=\lastbox
\showbox\temp
\end{document}
显示\temp
为无效。我遗漏了什么,以及/或者是否有其他方法可以完成我需要的操作?
答案1
这使用tokcycle
包将当前标记保存在输入流中,以便如果下一个标记是^
,则可以比较保存的标记以进行连字处理。
如果不解决您的实际字体和问题,很难说这种方法是否足够。
在这个 MWE 中,我在环境中实现了d^
和的人工构造的连字。n^
\StoneSansLigs
\documentclass{article}
\def\svd{d}
\def\svn{n}
\usepackage{tokcycle}
\def\lastsslchar{}
\tokcycleenvironment\StoneSansLigs
{%
\ifx##1^
\ifx\svd\lastsslchar\relax\addcytoks{$\hat{\textrm{d}}$}\fi% d^ ligature
\ifx\svn\lastsslchar\relax\addcytoks{$\hat{\textrm{n}}$}\fi% n^ ligature
\gdef\lastsslchar{}%
\else
\addcytoks[1]{\lastsslchar}%
\gdef\lastsslchar{##1}%
\fi
}
{\addcytoks[1]{\lastsslchar}\processtoks{##1\expandafter}%
\addcytoks[1]{\lastsslchar}}
{\addcytoks[1]{\lastsslchar##1}\gdef\lastsslchar{}}
{\addcytoks[1]{\lastsslchar##1}\gdef\lastsslchar{}}
\begin{document}
\StoneSansLigs
abd^c \textbf{pdd^q} n^m
\endStoneSansLigs
\end{document}
答案2
字符不会生成方框,因此\lastbox
不会从当前列表中删除它们。事实上,在 classic tex 或 xetex 中确实没有办法看到前一个字符(luatex 是可能的)。
一种解决方案是制作一种.vf
具有所有必需连字符的虚拟字体(),但更简单且可能可接受的方法是使用标记\zzhat
在每种情况下添加适当的命令。
在这里我假设字体有一个a^
连字(但在这种情况下输出是错误的,因为我使用的是拉丁现代字体),对于任何未定义为使用连字的字符,都会\^
使用后备(使用标准命令),如此o
处所示。
\documentclass{article}
\def\zhat#1{%
\ifcsname zhat-\string#1\endcsname
\csname zhat-\string#1\endcsname
\else
\^{#1}%
\fi}
%if a^ ligature is there and o^ is not....
% add lines for all characters to use ligature (or any other character-specific code)
\expandafter\edef\csname zhat-a\endcsname{a\string^}
\begin{document}
zzz \zhat{a} \zhat{o} zzz
\end{document}