XeLaTex 创建的 PDF 中的可搜索和复制的小型大写字母、连字和变音符号

XeLaTex 创建的 PDF 中的可搜索和复制的小型大写字母、连字和变音符号

我在使用 XeLaTex 创建的 PDF 中搜索和/或复制粘贴文本时遇到了一些问题。考虑以下 MWE,PDF 搜索没有给出某些词的结果。

\documentclass[%
   headsepline,
   footsepline,
   twoside,       
   numbers=noenddot,
   fontsize=11pt]{scrbook}
\usepackage[a4paper]{geometry}%
\usepackage{fontspec}
\setmainfont{Cambria}

\makeatletter\chardef\l@nohyphenation=255 \makeatother
\usepackage[ngerman=nohyphenation]{hyphsubst}
\usepackage[ngerman]{babel}
\usepackage{microtype}

\newcommand{\name}[1]{\textsc{#1}}

\begin{document}
\sloppy

\name{Albert Einstein} veröffentlichte 1905 die spezielle 
und 1916 die allgemeine Relativitätstheorie. 

Aus dem Relativitätsprinzip folgt unmittelbar, dass es keine Möglichkeit gibt, 
eine absolute Geschwindigkeit eines Beobachters im Raum zu ermitteln 
und damit ein absolut ruhendes Bezugssystem zu definieren. 

Übersetzt man die Beobachtungen des ruhenden Beobachters über eine
\name{Lorentz}-Transformation in die des Bewegten, so stellt sich heraus, 
dass dieser neben der elektrischen Kraft eine weitere, magnetische, Kraft wahrnimmt.

\end{document}
  1. 小型大写字母的单词我猜是因为没有找到“Cambria-smallcaps”字体或类似字体的定义。当我使用另一种定义了小写字母的字体(例如类似)时,PDF 中的小写字母可以搜索和复制。但是,\setmainfont[SmallCapsFont={Latin Modern Roman Caps}]{Cambria}我不喜欢在一个文档中使用多种字体。因此,实现可搜索和可复制小写字母的另一种方法是添加以下内容:

    \usepackage{accsupp}
    \newcommand*{\copyablesc}[1]{%
        \BeginAccSupp{%
            ActualText=\detokenize{#1},%
            method=escape,
        }%
        \textsc{\lowercase{#1}}%
        \EndAccSupp{}%
    }
    

    现在\newcommand{\name}[1]{\copyablesc{#1}},我得到的名称都是小写字母。这意味着大写字母,即大写字母(例如单词/名称的开头)会被忽略,这不是我想要的。有没有一种方法可以定义\copyablesc它的功能/外观与通常完全相同\textsc,或者另一种重新定义的方式\textsc,以便在 PDF 搜索中找到它而无需更改字体?

    编辑\lowercase:我刚刚意识到,只要离开并输入\textsc{#1}%上述代码,我就能得到想要的结果。对于这个错误,我深表歉意。

  2. 带连字符的单词(例如“definieren”中的“fi”)在 PDF 中找不到,当我复制粘贴它们时,我得到的是一个虚拟符号。我尝试了cmapmmap package\input{glyphtounicode},但它们在 XeLaTex 中不起作用。因此,使连字可搜索/可复制的唯一方法显然是使用将它们完全关闭\setmainfont[Ligatures={NoCommon, Tex}]{Cambria}。但我真的很想保留它们,因为它看起来更好。还有其他方法可以保留连字并使其在 PDF 中可搜索/可复制吗?

  3. 与连字符相反,变音符(ä、ö、ü)在某种程度上被视为我希望连字符的行为。这意味着,它们的行为就像两个符号的融合。

    • 当我将它们从 PDF 复制粘贴到 MS Word 中时非大写变音符号(ä、ö、ü) 被视为带有数学重音符号的字母,这意味着在 MS Word 中,所有包含它们的单词都被标记为拼写错误,删除它们时,我必须先删除重音符号,然后再删除字母。当我在 PDF 中搜索变音符号(例如“ö”)时,会找到每个“o”,这是不正确的。这些变音符号在德语中是单个符号,应如此处理。搜索“ö”应该只会找到“ö”,而不会找到“o”。

    • 大写变音符号(Ä、Ö、Ü) 根本无法搜索/复制,复制粘贴的结果分别是“A、O、U”,后面跟着一个假符号。

    那么有什么办法可以告诉 XeLaTex 将变音符号视为一个符号/连字符并使其可搜索/​​可复制吗?

答案1

正如我在评论中写道的:使用 lualatex 可能可以修补字体。作为概念证明:

\pdfvariable compresslevel 0
\documentclass[%
 fontsize=11pt,%
  ngerman,
]{scrbook}

\usepackage{luacode}

\begin{luacode}

local patch_cambriasc = function (fontdata)
 if fontdata.fontname == "Cambria"
 then
   fontdata.descriptions[983054]["unicode"]=109
   fontdata.descriptions[983055]["unicode"]=110
   fontdata.descriptions[983056]["unicode"]=111
   fontdata.descriptions[983213]["unicode"]=776 -- accent 0308
   fontdata.descriptions[983219]["unicode"]=778 -- accent 030A
   fontdata.descriptions[983078]["unicode"]=230 -- æ  
   fontdata.descriptions[983084]["unicode"]=231 -- ç
 end
end    

luatexbase.add_to_callback
 (
  "luaotfload.patch_font",
  patch_cambriasc,
  "change_cambria"
 )
\end{luacode}

\usepackage{fontspec}

\setmainfont[Ligatures={NoCommon}]{Cambria}
\newcommand{\name}[1]{\textsc{#1}}

\begin{document}
mno \name{omn}
\end{document} 

当使用 luatex 进行编译时,我得到了 pdf 中所有字形的 tounicode 条目:

7 beginbfchar
<008F> <006D>
<0090> <006E>
<0091> <006F>
<0112> <006D>
<0113> <006E>
<0114> <006F>
<0373> <0031>
endbfchar

并且文本可以完美复制和粘贴。

下面的 lua 补丁变体也有效:

local patch_cambriasc = function (fontdata)
 if fontdata.fontname == "Cambria"
 then
   fontdata.characters[983054]["tounicode"]="006D"
   fontdata.characters[983055]["tounicode"]="006E"
   fontdata.characters[983056]["tounicode"]="006F"
   fontdata.characters[983213]["tounicode"]="0308" -- accent 0308
   fontdata.characters[983219]["tounicode"]="030A" -- accent 030A
   fontdata.characters[983078]["tounicode"]="00E6" -- æ
   fontdata.characters[983084]["tounicode"]="00E7" -- ç
 end
end

但我不知道unicode字段是否只在描述表中起作用,以及tounicode是否只在字符中起作用。

答案2

Ulrike 已经给出了很好的答案。让我提供一些有用的信息。

如果您使用专为 Unicode 设计的 Open Type 字体,以 Unicode 编写文档,并使用支持 Unicode 的 TeX 引擎fontspec

在设计良好的 Unicode Open Type 字体中,连字符的字符名称采用 的形式hello_there。下划线将名为 的字符hello与名为 的字符连接起来there。可能涉及两个以上字符。因此,f和之间的连字符i名为f_i。一些连字符(例如fi)有自己的名称,可以追溯到几十年前。

字体中指定了用连字符替换字符,并且 可以理解fontspec。但是,当您获得 PDF 时,该信息已被处理。

连字符可以分配给 Unicode 中的私人/企业用户区域,有些字体确实这样做了。但标准更倾向于连字符不具有代码点。而是通过引用来找到它们。

当一个好的 PDF 阅读器看到字符 时f_i,它知道在搜索时应该看到两个字符fi,并且它知道应该在纯文本输出中提供这两个字符。原因是并非所有字体都有f_i,而那些有 的字体可能使用不同的代码点。

不幸的是,一些 PDF 阅读器(和文本提取器)不会将f_i其视为两个字符。它们将其视为单个字符,无法通过搜索找到,也无法将其作为两个字符导出为纯文本。

小型大写字母也有类似情况。WHAT小型大写字母的单词应作为 普通 进行搜索what,并作为 普通 进行导出what。好的 PDF 阅读器会这样做。但其他人只能看到小型大写字母的非标准代码点。

底线:这不是 XeTeX 或 LuaLaTeX 的属性。这是查看 PDF 的软件的属性。

老式的非 Unicode pdflatex 以及fontenc所有这些,是一个不同的问题。

编辑:一个不靠谱的字体设计师可能会使用和serdkwul之间的连字符的名称。这在技术上是允许的,只要在字体中定义了连字符,它就可以正常工作。它也会在 PDF 中正确显示和打印。但是,由于字符名称不是,PDF 阅读器将不知道它应该分解为和。fif_ifi

EDIT2:至于小型大写字母或字符的任何其他变体:在设计良好的 Open Type 字体中,字符的变体具有与基本字符相同的名称,后跟扩展名。因此,的小型大写版本可能a被命名为a.sca.smcp或类似名称。当请求小型大写字母时,字体自己的查找表将说明使用哪个字符。优秀的 PDF 阅读器知道这a.ext是的变体a。它会a在搜索中找到它,并将其导出为a纯文本。设计不良的字体会在查找中使用一些晦涩难懂的东西,例如asmcp(没有点)。这将在 PDF 中正确显示,但不能被搜索或导出为a。不合格的 PDF 阅读器不会理解这a.sc是的变体a。字符名称a.foo.bar也是合法的,作为的变体a

虽然小写字母可能带有扩展名.sc.smcp字体,但这并不是必需的。因此,PDF 阅读器仅通过查看扩展名来查找小写字母是不可靠的。如果安装了原始字体,高端 PDF 阅读器可能会做到这一点,这样阅读器就可以内部检查字体。我不确定。

相关内容