4

I want to display ocgs in a pdf and use the ocgx package to achieve this. Sometimes the content I have in the environment is so long it needs a page break. This is incompatible with the ocg system and the content on the second page is always displayed instead of being optional. A simple fix would be to detect if the ocg is going to contain a page break and split the environment, e.g.

\begin{ocg}{Name}{label}{0}
  \lipsum[1-10]
\end{ocg}

would be detected and the output would resemble the result of e.g.

\begin{ocg}{Name}{label1}{0}
  \lipsum[1-3]
\end{ocg}

\clearpage

\begin{ocg}{Name}{label2}{0}
  \lipsum[4-10]
\end{ocg}

How can I achieve this? I tried wrapping in a mdframed with beforebreak and afterbreak hooks to break and restart the ocg environment but I don't think ocgs like being nested in other environments...

2
  • I think the ocgs-p package is making things unneccessarily difficult here. From all I see, you should be able to use \ocg to start and \endocg to end an OCG, without nesting problems. Dec 2, 2013 at 16:00
  • @StephanLehmke : No, this cannot work out-of-the-box. Content to be marked as optional requires the insertion of opening and closing tags into the page content stream. Every PDF page has its own content stream and the scope of the tags is confined within such a page content stream. Thus, a stack of open layers must be maintained. Open layers must be automatically closed at the end of a page and reopened at the start of the new page. This has been implemented in the ocgx2 package.
    – AlexG
    Mar 4, 2016 at 12:06

2 Answers 2

2

Package ocgx2 (as of v0.11, [2015/11/23]) does it automatically.

In the code example that follows, text is placed on nested layers which extend across page breaks. In order to switch the layer visibility use the 'Layers' panel of the PDF viewer:

\documentclass[twocolumn]{article}

\usepackage{ocgx2}[2015/11/23]

\usepackage{color}
\usepackage{lipsum}

\begin{document}

\lipsum[1]
\begin{ocg}{outer layer (red)}{outer}{on}
  \color{red}\lipsum[2-3]
  \begin{ocg}{inner layer (blue)}{inner}{on}
    \color{blue}\lipsum[4-22]
  \end{ocg}
  \lipsum[23-26]
\end{ocg}
\lipsum[27-29]

\end{document}
1

I've been trying this myself but don't have the expertise to dig into mdframed.dtx and extract the obviously necessary box-splitting code. I've hacked together what seems to be a workable solution from Breakable vboxes.

I'd appreciate some help converting this plain-texy solution into a more latexy one.

\documentclass{article}
\usepackage{lipsum}
\usepackage{ocgx}

\newbox\totalocgbox
\newbox\partialocgbox
\newdimen\partialocgboxdim
\def\startocgbox{\par
\setbox\totalocgbox=\vbox\bgroup}
\def\endocgbox{\egroup\splitocgbox}

\def\splitocgbox{\ifvoid\totalocgbox\finishocgbox
  \else\continuesplitting\fi}
\def\finishocgbox{\bigskip}

\def\continuesplitting{\null % In case this starts a new page
  \dimen255=\dimexpr\pagegoal-\pagetotal-\pageshrink\relax
  \ifdim\ht\totalocgbox<\dimen255
    \setbox\partialocgbox=\box\totalocgbox
    \colorthisbox
  \else
    \setbox\partialocgbox=\vsplit\totalocgbox to\dimen255
    \colorthisbox\eject
  \fi
  \splitocgbox}

%TODO give this macro an appropriate name
\def\colorthisbox{%
    \hbox{%
        \begin{ocg}{Name}{Label}{1}%
        \vbox{%
            \unvbox\partialocgbox%
        }
        \end{ocg}%
    }
}

\begin{document}

\startocgbox
\lipsum[1-20]
\endocgbox

\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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