以下代码无法编译(使用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
加载。cmap
hyperref
\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{...}
ps2pdf
Ghostscript 使用了另一种方法。它有配套的ps2pdf12
、ps2pdf13
、ps2pdf14
、...,其中包含 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}?。