39

I have a document with a significant difference between its hard-copy and soft-copy.

Something like some text-boxes which should be printed bold and big in the hard copy but should be hidden (or as unobtrusive as possible) in the soft-copy version.

Is it possible in latex to incorporate materials in a pdf which are printed but not displayed?

behzad.nouri
  • 1,635
  • 5
    See http://tex.stackexchange.com/questions/4425/is-there-a-way-to-have-coloured-hyperref-hyperlinks-in-the-pdf-but-have-them-pr for something for something related: you probably need to use 'optional content groups'. – Joseph Wright Sep 18 '12 at 18:26
  • 3
    Just to make sure: soft-copy = screen, hard-copy = printer? – yo' Sep 26 '12 at 06:40
  • @tohecz yes, wikipedia defines soft-copy as "the unprinted digital document file" – behzad.nouri Sep 26 '12 at 12:45

1 Answers1

36

Update

As Martin Schröder and AlexG pointed out, there are now three packages that support print-only content out of the box: ocg-p, ocgx and ocgx2. The syntax to create the optional content group is the same for all of them, but ocgx2 has the additional advantage of supporting LuaLaTeX as well:

\documentclass{article}

\usepackage{ocgx2}

\begin{document}
This text is always visible.

\begin{ocg}[printocg=always]{Hard copy}{printonly}{0}
This can only be seen if the document is printed.
\end{ocg}

This text is visible in both the soft and the hard copy.
\end{document}

Output

Soft copy:

soft copy version, with "This can only be seen if the document is printed." not displayed

Hard copy:

hard copy version, with all the text displayed


Original answer

This is possible using optional content groups, which offer the properties ViewState and PrintState to control whether the group content should be visible in the soft or in the hard copy. The following proof of concept defines an environment printonly for things that should only be visible when printing the document.

\documentclass{article}

\makeatletter
% Create optional content group dictionary for print-only content
\immediate\pdfobj{%
<<%
  /Type/OCG%
  /Name(Hard copy)%
  /Usage<<%
    /Print<<%
      /PrintState/ON%
     >>%
    /View<<%
      /ViewState/OFF%
    >>%
  >>%
>>}
\xdef\ocg@printonly{\the\pdflastobj\space 0 R}

% Add OCG to resource dictionary
\immediate\pdfobj{<</OCprintonly\space\ocg@printonly\space>>}
\xdef\ocg@mapping{\the\pdflastobj\space 0 R}%
\begingroup
\edef\x{\endgroup
   \pdfpageresources{%
      \the\pdfpageresources%
      /Properties \ocg@mapping%
   }%
}%
\x

% List of all optional content groups
\newcount\ocg@listocgs
\pdfobj reserveobjnum
\ocg@listocgs=\pdflastobj

% Create optional content usage dictionary
\pdfcatalog{%
/OCProperties<<%
  /OCGs \the\ocg@listocgs\space0 R\space%
  /D<<%
    /Order [\ocg@printonly\space]% if this line is removed, the OCG isn't shown in the layer toolbar of the viewer
    /OFF [\ocg@printonly\space]%
    /AS[%
      <<%
        /Event/View%
        /OCGs \the\ocg@listocgs\space0 R\space%
        /Category[/View]%
      >>%
      <<%
        /Event/Print%
        /OCGs \the\ocg@listocgs\space0 R\space%
        /Category[/Print]%
      >>%
      <<%
        /Event/Export%
        /OCGs \the\ocg@listocgs\space0 R\space%
        /Category[/Print]%
      >>%
    ]%
  >>%
>>}

% List all OCGs
\AtEndDocument{%
   \immediate\pdfobj useobjnum \ocg@listocgs {%
      [\ocg@printonly\space]%
   }%
}%

% "printonly" environment for content which should only be visible when the document is printed
\newenvironment{printonly}{%
  \pdfliteral{/OC /OCprintonly\space BDC}%
}{%
  \pdfliteral{EMC}%
}
\makeatother

\begin{document}
This text is always visible.

\begin{printonly}
This can only be seen if the document is printed.
\end{printonly}

This text is visible in both the soft and the hard copy.
\end{document}

The code is heavily inspired by ocg.sty, which is distributed with Asymptote; some information about it can be found on texample.net. However it is not necessary for this example to have the package installed.

diabonas
  • 25,784
  • 2
    Update: The ocg-p package was released recently and improves on ocg. – Martin Schröder Dec 04 '12 at 20:32
  • 1
    Further improvement was achieved by the ocgx and ocgx2 packages, the latter allowing for OCGs extending over page breaks. – AlexG Apr 11 '17 at 13:18
  • @MartinSchröder: What if I want the reverse, that is, I have a line that I want to display in the soft copy but I do not want it printed on a hard copy ? Could you show how the OCG options can reflect that ? – me10240 Oct 07 '17 at 07:31
  • @me10240 You would have to change \begin{ocg}[printocg=always]{Hard copy}{printonly}{0} to \begin{ocg}[printocg=never]{Soft copy}{viewonly}{1}, see the ocg-p documentation for more details. – diabonas Oct 07 '17 at 08:22
  • @diabonas: I did exactly that. It shows in soft copy all right, but when I print to file, it still shows up though. Is printing to file different from hard copy ? – me10240 Oct 07 '17 at 15:18
  • 1
    @me10240 Printing to a file should work for testing purposes, in fact the text should already disappear in the print preview (tested with Adobe Acrobat (Reader), Foxit Reader and PDF-XChange Viewer). Note that you must compile your document twice for the OCG to work properly, otherwise the text is always shown. If that doesn't help, your viewer probably doesn't fully support OCGs. – diabonas Oct 07 '17 at 15:37
  • 1
    @diabonas: Perhaps my viewer, Evince is the problem then. Would you know of another package that works with evince too ? – me10240 Oct 07 '17 at 16:01
  • 1
    @me10240 Evince (and indeed any viewer based on the Poppler library) has only partial OCG support, as it doesn't switch the visibility according to the information in the usage application dictionary (/AS) of the PDF. In that case you're out of luck I'm afraid, as there is no other way to recognise when a document is being printed (well apart from JavaScript, but Evince doesn't support that either, like most non-Adobe software). – diabonas Oct 07 '17 at 16:20