使用 fontspec 临时更改字体的正确方法

使用 fontspec 临时更改字体的正确方法

我一直在 lualatex 文档中使用 fontspec,按照手册的指示,我在序言中使用一些默认功能设置了我的 main/sans/mono 字体。

然而在某些时候,我希望暂时重新定义单色字体(在我的特定情况下是在 longtabu 中,但任何跨越多页的东西的行为都相同。)

该文档的另一个特点是我在标题内有我的电子邮件地址\url{}

尝试一下 我将 longtabu 放在一个组中,并在表格前的组中调用 setmonofont。这工作正常,表格中的 mono 字体文本被适当更改,表格外 monofont 中的文本与序言中定义的一致,但包含多页表格的第一页的页眉中的电子邮件地址更改为重新定义的 monofont(第二页的页眉具有正确的字体)。

我最初以为这是 longtabu 中的一个错误,然后用 longtable 重现了它,但后来也用一个简单的包含跨越 2 页的文本的组重现了它。

我猜这也可能是 fancyhdr 中的一个错误,但 scrpage2 也出现了同样的行为。所以要么是 fontspec 中的一个错误,要么是我做错了什么。手册明确指出该\set{main,sans,mono}font命令应该在序言中发生。如果是这样,我该如何重新定义或临时向设置字体添加功能。

我不想不加区别地在组中使用 \addfeatures{},因为我只想影响该组内\texttt\url组内的文本,因此重新定义了单字体。

编译以下 MWE,您可以看到在第 1 页上,文本已按应有的方式更改,但是在第 2 页上,页面中的文本正常,但标题和组中的文本都发生了变化,而在第 3 页上,标题恢复正常。

\documentclass[a4paper]{article}
\usepackage{fontspec}
\usepackage{lipsum}
\usepackage{longtable}
\usepackage{url}
%\usepackage{scrpage2}
\usepackage{fancyhdr}
\usepackage{hyperref}
\setmainfont{Iwona}
\setmonofont{Inconsolata}

%\clearscrheadfoot
\lhead{\href{mailto:[email protected]}{\nolinkurl{[email protected]}}}
\rhead{\texttt{\thepage}}

%\pagestyle{scrheadings}
\pagestyle{fancy}
\begin{document}

\lipsum[1]

\texttt{some text in monospace font}

\lipsum[2]

{\setmonofont{Courier New}
\lipsum[3]

\texttt{some text in monospace font}

\lipsum[4]
}
\newpage
\lipsum[5]

\texttt{some text in monospace font}

\lipsum[6]

\begingroup
\setmonofont{Courier New}
\lipsum[7]

\texttt{some text in monospace font}

\lipsum[8-9]

\texttt{some text in monospace font}

\lipsum[10-11]

\texttt{some text in monospace font}

\lipsum[12]
\endgroup

\lipsum[13]

\texttt{some text in monospace font}

\lipsum[14]
\end{document}

我对于 MWE 的长度感到抱歉,但我想在这种情况下它确实是一个 MNWE。

我想我的问题是我做错了什么,如果答案是“什么都没有”,那么我该如何修复这个错误。

答案1

该问题与 fontspec 无关。您可以为 pdflatex 构建类似的示例。行为取决于两件事:

  1. TeX 首先构建文本主体,然后在 shipout 时添加页眉和页脚。因此,在 shipout 时仍处于活动状态的页面上的字体定义更改将影响该页面的页眉和页脚。

  2. 在构建页面时,TeX 会提前考虑一些事情。因此,当前页面发出时,下一页的代码/文本通常已经由 TeX 处理和执行。(“异步页面构建”)。因此,文本中的微小变化可能意味着,\endgroup之前在发出后看到的命令或结束括号现在在发出前就可以看到。

这意味着您不应该依赖分组来获取标题和字体中的正确字体,除非该组以 开始和结束\newpage

答案2

当第 1 页和第 2 页之间出现分页符时,等宽字体为 Courier New,因此\ttfamily发出的声明\nolinkurl遵循此设置。

我建议使用不同的策略:在序言中说

\newfontfamily{\differenttt}{Courier New}
\DeclareTextFontCommand{\textdifferenttt}{\differenttt}

当您想使用 Courier New 作为等宽字体时,使用\textdifferenttt或。\differenttt

还将命令名称更改为更简单的名称。:)

主要问题是什么?LaTeX 在执行以下代码时会排版标题:输出例程,通常在 LaTeX 积累了更多的填充页面所需的材料比实际所需材料多。随着字体的改变,页眉中使用的等宽字体变得不可预测:当您用来限制新设置的组\setmonofont已经结束时,可以调用输出例程。

如果您想确保 Inconsolata 始终在标题中使用,则不要\setmonofont在文档中发出或\setmonofont{Inconsolata}在标题的代码中指定(这不是我推荐的,但它应该有效,因为输出例程是在组内执行的,类似于您重置的方式\setmonofont)。

答案3

我假设您希望标题中的 URL 和页码具有固定字体(Inconsolata),并且希望在 Courier New 中显示一些文本。最简单的方法是重新定义 URL 字体并为 Inconsolata 创建新的字体命令。以下命令可满足您的需要:

\documentclass[a4paper]{article}
\usepackage{fontspec}
\usepackage{lipsum}
\usepackage{url}
\usepackage{fancyhdr}
\usepackage{hyperref}
\setmainfont{Iwona}
\setmonofont{Inconsolata}
\newfontfamily\nicemono{Inconsolata}
\DeclareTextFontCommand{\textnicemono}{\nicemono}
\newfontfamily\courier{Courier New}
\renewcommand{\UrlFont}{\nicemono}
\lhead{\href{mailto:[email protected]}{\nolinkurl{[email protected]}}}
\rhead{\textnicemono{\thepage}}

\pagestyle{fancy}
\begin{document}

\lipsum[1]

\texttt{some text in monospace font}

\lipsum[2]

{\setmonofont{Courier New}
\lipsum[3]

\texttt{some text in monospace font}

\lipsum[4]
}
\newpage
\lipsum[5]

\texttt{some text in monospace font}

\lipsum[6]

\begingroup
\setmonofont{Courier New}
\lipsum[7]

\texttt{some text in monospace font}

\lipsum[8-9]

\texttt{some text in monospace font}

\lipsum[10-11]

\texttt{some text in monospace font}

\lipsum[12]
\endgroup

\lipsum[13]

\texttt{some text in monospace font}

\lipsum[14]
\end{document}

相关内容