cmap 与 fontenc/hyperref 不兼容?

cmap 与 fontenc/hyperref 不兼容?

以下代码无法编译(使用pdflatex

\documentclass{article}
\usepackage{cmap}
\usepackage[T1]{fontenc}
\usepackage[pdfa=true]{hyperref}

\begin{document}

Hello.

\end{document}

除非我省略fontenc-line 或-linepdfa=true中的 -option hyperref。我收到的错误消息是:! pdfTeX error (setup): \pdfminorversion cannot be changed after data is written to the PDF file.我可以做些什么吗?或者这是不兼容吗?

答案1

你得到的致命错误是

! pdfTeX error (setup): \pdfminorversion cannot be changed after data is writte
n to the PDF file.
<to be read again> 
                   \edef 
l.6 \begin{document}

使用\tracingall,可以进一步追踪到钩子\AtBeginDocument。它看起来像是想要hyperref在给出选项时在文档开头设置一些 PDF 设置pdfa=true。通常,在此阶段不会将任何内容写入 PDF,因此一切都很好,但是已经写入 PDF,因此会破坏这一点。解决方案是在 之后cmap加载。cmaphyperref

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[pdfa=true]{hyperref}
\usepackage{cmap}
\begin{document}

Hello.

\end{document}

答案2

概括 正确答案确实是 Gernsheim 的解决方案

\RequirePackage{pdf14}

就在开始之前\documentclass

细节

PDF 文件的次要版本由 pdfTeX 设置\pdfminorversion(旧版本使用\pdfoptionpdfminorversion)。版本号写在 PDF 文件的最开头:

%!PDF-1.4

对象紧随其后。如果 pdfTeX 有写入对象,它必须以 PDF 头和其版本号开始 PDF 文件。此时版本号是固定的。

理论上,pdfTeX 可以扩展为返回文件并用更新的版本号替换次要版本字节。但是,请记住 PDF 版本号的用途。它告诉支持哪些功能以及哪些功能不在特定 PDF 版本的范围内。例如,如果版本首先设置为高值,我们就会遇到问题。一个包检测到这种情况并认为,太好了,我可以使用高级 PDF 内容,然后另一个包说,April,April,我们想要 1.4 因为 PDF/A。

因此,如果 pdfTeX 抱怨版本设置太晚的错误,这是正确的。

cmap应在字体加载之前尽早加载该包。因为它会侵入该机制,将其 Unicode 映射添加到字体中。然后\usepackage[T1]{fontenc}加载新字体,并将 T1 到 Unicode 的映射对象写入 PDF 文件。之后再更改 PDF 文件的版本号就太晚了。

软件包hyperref通常需要稍后加载。此时它不能再更改版本号。

解决方案

在 TeX 宏级别,应尽早设置 PDF 版本号。这由包完成pdf14(可以扩展以支持较旧的 pdfTeX 版本)。文档类已经可以加载其他包,如cmap和甚至hyperref,因此在一般情况下需要更早地加载包。LaTeX 不允许\usepackage在之前\documentclass,但\RequirePackage可以:

\RequirePackage{pdf14}
\documentclass{...}

ps2pdfGhostscript 使用了另一种方法。它有配套的ps2pdf12ps2pdf13ps2pdf14、...,其中包含 PDF 版本号的明确设置。

在 TeX 世界中,这可以通过生成一种pdflatex14 使用\pdfminorversion=4而不是 的新格式来实现\pdfminorversion=5

家庭作业hyperref

使用\pdflastobj和朋友可以检测是否已将某些内容写入 PDF 文件。因此,我将hyperref 在 2012/12/30 v6.82w 版本中进行扩展,并在更改版本号之前添加一些健全性检查。

答案3

放一个

\RequirePackage{pdf14}

在序言中,就在

\documentclass

对我有用。

答案4

该问题不再出现在 TeXlive 2018 上。

当使用软件包时,我可以以某种方式重现它pdfx:要制作存档 PDF,应该使用pdfx包。如果cmap已加载,则必须加载pdfx fontenc.hyperref由包内部加载pdfx

如果这三个包(cmap、pdfx、fontenc)中有一个未加载,错误就会消失。加载所有包时,顺序必须如下:

\documentclass{article}
\usepackage{cmap}
\usepackage[a-1b]{pdfx}
\usepackage[T1]{fontenc}

\begin{document}

Hello.

\end{document}

(通过反复试验找到解决方案)。请注意,fontenc在没有变音符的普通美国文本中可能没有必要。参见为什么我应该使用 \usepackage[T1]{fontenc}?

相关内容