我正在尝试编写一本老式书籍。我想为整个文本使用特定的历史字体。此字体包括以下连字符:ff
、、、和(见图fi
fl
ffl
st
1为斜体样式)。
不幸的是,XeLaTeX 和 LuaLaTeX 似乎无法识别连字符的存在。我尝试了以下简单的代码。
% !TEX TS-program = xelatex
\documentclass{article}
\usepackage{fontspec}
\setmainfont[Ligatures={Required,%
Common,Contextual,Rare,Historic,TeX}]{Historical-FellTypeItalic}
\begin{document}
ff fi fl ffl st
\end{document}
不幸的是,LaTeX 结果没有连字符(字体的浅色样式也会出现同样的情况)。另一方面,不同的字体(例如 Linux Libertine)可以正常工作。我也尝试在 LaTeX 系统中安装字体,但没有得到任何结果(字体可以工作,但连字符不行)。
您知道什么解决办法吗?
另一个(也是次要的)问题。存在一些有趣的字形(如ct
、us
和as
)。我不知道如何将它们集成到 LaTeX 代码中。我想使用这些字形输入单词而无需特殊声明。
供您参考:我在 Windows 10(x64)上使用完全更新的 TeXLive。
编辑
感谢大家的回答。它运行良好,但我想用 LuaLaTeX 代码来深入研究这个问题。如果我使用的字体不止一种(例如 ITALIC.otf 和 ROMAN.otf),我该如何调整 Lua 代码以适应不同字体中缺少的字形?让我通过一个例子来解释:连字字形is
(uchar(916)) 存在于 ITALIC.otf 中,但不存在于 ROMAN.otf 中。这样,简化代码:
% all your LuaLaTeX-code
\usepackage{fontspec}
\setmainfont[ItalicFont=ITALIC.otf]{ROMAN.otf}
\begin{document}
is \textit{is}
\end{document}
is
生成一个唯一带有斜体(罗马字母is
缺失)的PDF 。我猜想,LaTeX 会尝试搜索罗马字形 uchar(916),而不是插入i
和的罗马字形s
。有解决方案吗?再次感谢您的关注。
答案1
就连字而言,此字体的问题在于内部字体表中的连字名称完全不符合标准。例如,使用 FontForge 应用程序进行搜索后发现,该字体使用的连字名称不是标准名称,如f_f
和。这可不是开玩笑!!(对这种情况的一个客观评估可能是,字体的名称对应表在编译之前的某个时间点被弄乱了。)f_f_i
Omega
approxequal
鉴于这种情况,LuaLaTeX 和 XeLaTeX 在没有特殊帮助的情况下无法找出名称映射也就不足为奇了。
使用 LuaLaTeX,我能想到两种解决方案解决这一问题。第一个解决方案是创建一个自定义“功能文件”,该文件会告知系统字体实际使用的连字符名称。第二个解决方案(如下所示)直接使用 LuaTeX 功能来使连字符正常工作。
在 FontForge 的帮助下,我找到了所有十个连字符的“名称”。这些名称用于设置一个称为 的所谓“功能文件”,addligs_HFTI.fea
该文件可以通过 之类的指令加载\addfontfeatures{FeatureFile=addligs_HFTI.fea}
。
不幸的是,尽管找到了字体中所有十个连字符的连字符“名称”,但这种方法只能成功激活其中四个(具体来说是 、 、 和 )。也许字体编译时还有其他东西被ct
弄乱ff
了ffi
?ffl
% !TEX TS-program = lualatex
\RequirePackage{filecontents}
\begin{filecontents*}{addligs_HFTI.fea}
languagesystem DFLT dflt;
languagesystem latn dflt;
# Ligatures
feature liga {
sub a s by summation;
sub i s by Delta;
sub u s by divide;
sub c t by plusminus;
sub f f by Omega;
sub f i by fi;
sub f l by fl;
sub f f i by approxequal;
sub f f l by radical;
} liga;
\end{filecontents*}
\documentclass{article}
\newcommand\liglist{as is ct ff fi fl ffi ffl}
\usepackage{fontspec}
\defaultfontfeatures{Ligatures=Common}
\setmainfont{Historical-FellTypeItalic}
\begin{document}
w/o ligatures: \liglist
\addfontfeatures{FeatureFile=addligs_HFTI.fea}
with ligatures: \liglist
\end{document}
附录。鉴于特征文件方法无法成功激活字体中存在的所有十个连字符,以下完全用 Lua 编码的解决方案可能值得考虑。它使用回调process_input_buffer
来运行一个函数,该函数将十个字符对和三元组执行“强力”替换,并将其替换为代表连字符版本的相应字形。(完整披露:下面使用的代码感谢地使用了 @michal.h21 在他的回答我最近的帖子,题为LuaLaTeX:如何在 string.gsub 函数中使用 \char 指令?) 请注意,必须特别小心,以确保任何可能包含诸如“ff”、“fi”等字符串的 LaTeX 宏都不会被卷入暴力替换。
% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{fontspec}
\setmainfont{Historical-FellTypeItalic}
\usepackage{luacode,luatexbase}
\begin{luacode}
local uchar = unicode.utf8.char
function ligsub ( s )
local x = s:gsub('(\\?)([%a%@]+)',
function(back,text)
if back~="" then
return back .. text
end
text = text:gsub ( 'ffi', uchar(8776))
text = text:gsub ( 'ffl', uchar(8730))
text = text:gsub ( 'ff', uchar(937))
text = text:gsub ( 'fi', uchar(64257))
text = text:gsub ( 'fl', uchar(64258))
text = text:gsub ( 'as', uchar(8721))
text = text:gsub ( 'is', uchar(916))
text = text:gsub ( 'us', uchar(247))
text = text:gsub ( 'ct', uchar(177))
text = text:gsub ( 'st', uchar(9674))
return text
end)
print("x", x)
return x
end
\end{luacode}
\AtBeginDocument{%
\directlua{luatexbase.add_to_callback (
"process_input_buffer", ligsub, "ligsub" )}}
\newcommand\off{off} % dummy macro (see below)
\begin{document}
off fit fly office baffle
as is us act step
\off --note: no ff-ligature
\end{document}
备注:我认为采用这种方法的唯一缺点是它肯定会搞乱屏幕阅读器的工作:十个连字符中的八个(表示ff
、ffi
和fl
、as
、is
、us
、ct
和st
)分别被渲染为Ω
、≈
、√
、Σ
、Δ
、±
和◊
。哎呀。(相比之下,fi
和fl
确实被正确渲染;可能并非巧合,这两个连字符在功能文件中具有“正常”名称,这在前面已经显示过。)不过,这并不是基于 LuaLaTeX 的方法的错;相反,字体混乱的名称表才是罪魁祸首。理想情况下,字体的作者和/或维护者会重新发布它,这次名称表会彻底清理。
答案2
事实证明你的字体是免费提供。正如我所怀疑的,该字体没有 OpenType 功能(来自 FontForge 的屏幕截图):
更糟糕的是,该字体不是 Unicode 字体。它用连字符替换了各种代码点。如果您愿意,您可以按照 Unicode 标准输入占据这些位置的字符来访问连字符:
\documentclass{article}
\usepackage{fontspec}
\setmainfont{Historical-FellTypeItalic}
\begin{document}
O≈ce ◊ar
\end{document}
或者定义更合理的快捷方式:
\documentclass{article}
\usepackage{fontspec}
\setmainfont{Historical-FellTypeItalic}
\newcommand{\ffi}{≈}
\newcommand{\st}{◊}
\begin{document}
O\ffi ce \st ar
\end{document}