[pdftex] Simple (?) question about \pdfobj

Heiko Oberdiek heiko.oberdiek at googlemail.com
Sat Mar 5 15:34:48 CET 2011


On Sat, Mar 05, 2011 at 07:23:19AM -0500, Duncan Murdoch wrote:

> I'm working with Sweave, a literate programming system that produces
> LaTeX files as the human readable output.  I want to embed
> information in the resulting .pdf file that gives the relation
> between the .tex intermediate file and the original inputs, so that
> viewers using Synctex can be told to jump to the original source.  A
> while ago I went looking for a standard way to do this and didn't
> find one, so I invented my own.   I construct a string of values
> describing the concordance, and embed it in the pdf using this code:
> 
> \newcommand{\Sconcordance}[1]{%
>   \ifx\pdfoutput\undefined%
>   \csname newcount\endcsname\pdfoutput\fi%
>   \ifcase\pdfoutput\special{#1}%
>   \else\immediate\pdfobj{#1}\fi}

There is package `ifpdf' to test for pdfTeX in PDF mode
in a more safe way:

\usepackage{ifpdf}
\newcommand*{\Sconcordance}[1]{%
  \ifpdf
    \special{#1}%
  \else
    \immediate\pdfobj{#1}%
  \fi
}

> The text that is in the #1 argument has no particular structure
> specific to PDF files.  Does it need to?

Yes, I recommend it. Otherwise:
* The object can get lost if the PDF file is rewritten, because
  the object is unused.
* A PDF processing program might scan the PDF file differently
  starting from the beginning to find object, e.g. if the
  cross ref table is corrupted.

> A typical call looks like
> 
> \Sconcordance{concordance:doc.tex:doc.Rnw:%
> 1 21 1 7 0 1 3 4 1 7 0 1 6 1 1 8 0 1 3 6 1 4 0 1 3 1 1 11 0 1 6 2 1 7 0 %
> 1 3 8 1 11 0 1 4 1 1 20 0 1 5 17 1 7 0 1 5 3 1 8 0 1 4 3 1 9 0 1 4 25 1}

For instance the data can put in a string.
If you have at most one \Sconcordance call per document,
then the easiest way is probably to put it into the
information dictionary as key value pair:

  \pdfinfo{/concordance(concordance:doc.tex:doc.Rnw:1 21 ... 15 1)}

The key is "/concordance", the string value is "(...)".
In general it's better to ensure that "(...)" is a valid
PDF string (some characters need escaping like the backslash).
It can be done with \pdfescapestring:

\usepackage{ifpdf}
\newcommand*{\Sconcordance}[1]{%
  \ifpdf
    \special{#1}%
  \else
    \pdfinfo{%
      /concordance%
      (\pdfescapestring{#1})%
    }%
  \fi
}

If you want to support older pdfTeX versions that miss \pdfescapestring
then package pdfescape fills the gap. It also supports LuaTeX:

\usepackage{ifpdf}
\usepackage{pdfescape}
\newcommand*{\Sconcordance}[1]{%
  \ifpdf
    \special{#1}%
  \else
    \begingroup
      \EdefEscapeString\StringValue{#1}%
      \pdfinfo{%
        /concordance%
        (\StringValue)%
     \endgroup
  \fi
}

If package hyperref is used, then additional information entries
can be added via option `pdfinfo' (since 6.80b) and hyperref
takes care of the string conversion:

\usepackage{ifpdf}
\usepackage{hyperref}[2010/01/11]
\newcommand*{\Sconcordance}[1]{%
  \ifpdf
    \special{#1}%
  \else
    \hypersetup{pdfinfo={concordance={#1}}}%
  \fi
}
 
> I am asking this because when I use this with a Beamer document, I
> end up producing a .pdf file that Acrobat Reader complains about
> with the message "There was an error opening this document.  Invalid
> action object."  With most other documents things are fine, so this
> is conceivably a Beamer bug,

Make a minimal example that shows the problem.

Yours sincerely
  Heiko Oberdiek
-- 


More information about the pdftex mailing list