Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

The following code doesn't compile (with pdflatex)

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

\begin{document}

Hello.

\end{document}

unless I omit either the fontenc-line or the pdfa=true-option from the hyperref-line. The error message I get says: ! pdfTeX error (setup): \pdfminorversion cannot be changed after data is written to the PDF file. Is there something I can do or is this an incompatibility?

share|improve this question
2  
Your MWE runs if you do not use cmap or without fontenc you said. The option pdfa=true is not documented jet so I would prefer not to use it. You can change your document later to pdf/a if you need. \pdfminorversion defines the pdf versionnummer you will be allowed to include in your document. –  Kurt Jul 25 '12 at 1:04

3 Answers 3

up vote 11 down vote accepted

The fatal error you get is

! 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}

Using \tracingall, this can be tracked down a bit more to the \AtBeginDocument hook. What it looks like is that hyperref wants to set some PDF settings at the start of the document when given the pdfa=true option. Normally, nothing will have been written to the PDF at that stage, so all is fine, but cmap has already written to the PDF so breaks this. The solution is to load cmap after hyperref.

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

Hello.

\end{document}
share|improve this answer
    
Compiling your MWE I get the warning: Package cmap Warning: fontenc already loaded - some fonts may be unprocessed. You too? –  Kurt Jul 27 '12 at 0:20

Putting a

\RequirePackage{pdf14}

in the preamble, just behind the

\documentclass

worked for me.

share|improve this answer
    
Thank you, that works! Perhaps someone else can help with identifying the reason for the original incompatibility. –  Lover of Structure Jul 25 '12 at 1:03

Summary The correct answer is indeed the solution of Gernsheim with

\RequirePackage{pdf14}

right at the beginning before \documentclass.

Details

The minor version of the PDF file is set by \pdfminorversion in pdfTeX (Older versions are using \pdfoptionpdfminorversion). The version number is written in the very beginning of the PDF file:

%!PDF-1.4

The objects are following afterwards. If pdfTeX has written objects, it had to start the PDF file with the PDF header and its version number. At this time the version number is fixed.

Theoretically pdfTeX could be extended to go back in the file and replace the minor version byte by an updated version number. However, keep in mind, what the purpose of the PDF version number is. It tells what features are supported and which features are not in the scope of the particular PDF version. For instance, we would have a problem if the version is first set to a high value. A packages detects this and thinks, hurray I can use advanced PDF stuff, and then another package says, April, April, we want to have 1.4 because of PDF/A.

Therefore it is correct if pdfTeX complains with an error that the version setting is too late.

The package cmap should be loaded at an early stage, before fonts are loaded. Because it hacks into this machinery to add its Unicode mappings to the fonts. By \usepackage[T1]{fontenc} new fonts are loaded and the object for the mapping T1 to Unicode is written to the PDF file. Afterwards it is too late for changing the version number of the PDF file.

Package hyperref usually needs to be loaded later. At this stage it cannot change the version number anymore.

Solutions

At TeX macro level the PDF version number should be set at early as possible. This is done by package pdf14 (it could be extended to support older pdfTeX versions). A document class can already load other packages like cmap and even hyperref, therefore the packages needs to be loaded even earlier in the general case. LaTeX does not allow \usepackage before \documentclass, but \RequirePackage works:

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

An alternative method is used by ps2pdf of Ghostscript. It has companions ps2pdf12, ps2pdf13, ps2pdf14, … that contain an explicite setting of the version number for PDF.

In the TeX world this can be achieved by generating a new format pdflatex14 that uses \pdfminorversion=4 instead of \pdfminorversion=5.

Homework for hyperref

Using \pdflastobj and friends it is possible to detect, if something has already been written to the PDF file. Therefore I will extend hyperref in version 2012/12/30 v6.82w and add some sanity checks before the version number is changed.

share|improve this answer
    
Thanks, this is great! User JosephWright's solution works for me, so I'll keep it as the chosen answer for now for its simplicity (unless there are other issues with it). User Gernsheim's original answer didn't provide enough context for me to understand why, though your explanation is great. Btw, there is another completely different thing I wrote about elsewhere, I hope you don't mind me drawing your attention to this. –  Lover of Structure Jul 30 '12 at 6:33

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.