fold / unfold system of equations in long derivation

I am showing a long derivation (simplified example here)

\documentclass{article}

\begin{document}

\begin{eqnarray*}
0 &=& 0 \\
&\downarrow& \mbox{using eq.}~\ref{eq0} \\
&=& 1 \\
&\downarrow& \mbox{using eq.}~\ref{eq1} \\
&=& 2 \\
&\downarrow& \mbox{using eq.}~\ref{eq2} \\
&=& 3
\end{eqnarray*}

$$0 \label{eq0}$$

$$1 \label{eq1}$$

$$2 \label{eq2}$$

\end{document}


I would like to have only a folded representation showing only the line "0=0" and the final "=3" in the produced PDF. The desired behaviour would be that there is a button between these 2 final lines that, when hovered or pressed, would trigger a pop up showing the entire derivation.

The objective is that the reader can quickly see the start and end without having to see all the details in between at first view. Of course, I could put the derivation in an appendix but navigation would become difficult (especially considering that the intermediate equations themselves refer to other equations).

This question is very much related to: Collapsable/expandable text in Latex

But I couldn't find a way to adapt the code with the aligned equations. The picture below gives an example of the desired behaviour.

• Ideal would be that the size of the pop up would be adapted to the number of aligned equations that it needs to host. I'm updating with a picture so you can see what I mean – ranlot May 16 '18 at 14:20
• Oh, no gap. It should just pop up on top of the existing eqnarray. When you click outside (or some other intuitive interface), the pop up would disappear – ranlot May 16 '18 at 14:39
• Which PDF-Reader do you want to use? – AlexG May 16 '18 at 14:42
• I guess Acrobat Reader is a must. But it'd be nice to support as many as possible. Note that I'm developing everything from Overleaf. – ranlot May 16 '18 at 14:48

Building on J. Kormylo's example without vertical gap and making use of the

\tootip****{...}{...}[<x-off>][<y-off>] macro (Evince, A-Reader):

\documentclass{article}
\usepackage{mathtools}

\usepackage{hyperref}
%patch hyperref to make PDF Annotations PDF-Layer-(OCG)-aware
\makeatletter
\let\Hy@setpdfborderOrig\Hy@setpdfborder
\def\Hy@setpdfborder{\ocgbase@insert@oc\Hy@setpdfborderOrig}%
\makeatother
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% tooltips with LaTeX v. 2018/01/15
%
% \tooltip[*[*[*[*]]]]
%            [<tip box colour>]{<tip text>}
%            [<x-offset>,<y-offset>]
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%   \tooltip     --> draggable tip, visible on mouse-over, hidden on mouse-out
%
%   \tooltip*    --> draggable tip, toggle visiblity on mouse-over
%
%   \tooltip**   --> NON-draggable tip, visible on mouse-over, hidden on mouse-out
%
%   \tooltip***  --> NON-draggable tip, toggle visiblity on mouse-over
%
%   \tooltip**** --> NON-draggable tip, toggle visiblity on mouse-click (Evince!)
%
% Default link colour can be set with
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage{xparse,ocgbase}
\usepackage{xcolor,calc}
\usepackage{tikzpagenodes,linegoal}
\usetikzlibrary{calc}

\ExplSyntaxOn
\let\tpPdfAnnot\pbs_pdfannot:nnnn\let\tpPdfLastAnn\pbs_pdflastann:
\let\tpAppendToFields\pbs_appendtofields:n
\def\tpPdfXform{\pbs_pdfxform:nnnnn{1}{1}{}{}}
\let\tpPdfLastXform\pbs_pdflastxform:
\let\cListSet\clist_set:Nn\let\cListItem\clist_item:Nn
\ExplSyntaxOff

\makeatletter
\NewDocumentCommand{\tooltip}{%
}{{%
\leavevmode%
\IfBooleanT{#2}{%
%for variants with two and more stars, put tip box on a PDF Layer (OCG)
\ocgbase@new@ocg{tipOCG.\thetcnt}{%
/Print<</PrintState/OFF>>/Export<</ExportState/OFF>>%
}{false}%
\xdef\tpTipOcg{\ocgbase@last@ocg}%
%prevent simultaneous visibility of multiple non-draggable tooltips
}%
\IfBooleanTF{#4}{%
/Subtype/Link/Border[0 0 0]/A <</S/SetOCGState/State [/Toggle \tpTipOcg]>>
}{%
/Subtype/Screen%
/AA<<%
\IfBooleanTF{#3}{%
/E<</S/SetOCGState/State [/Toggle \tpTipOcg]>>%
}{%
\IfBooleanTF{#2}{%
/E<</S/SetOCGState/State [/ON \tpTipOcg]>>%
/X<</S/SetOCGState/State [/OFF \tpTipOcg]>>%
}{
\IfBooleanTF{#1}{%
/E<</S/JavaScript/JS(%
var fd=this.getField('tip.\thetcnt');%
if(typeof(click\thetcnt)=='undefined'){%
var click\thetcnt=false;%
var fdor\thetcnt=fd.rect;var dragging\thetcnt=false;%
}%
if(fd.display==display.hidden){%
fd.delay=true;fd.display=display.visible;fd.delay=false;%
}else{%
if(!click\thetcnt&&!dragging\thetcnt){fd.display=display.hidden;}%
if(!dragging\thetcnt){click\thetcnt=false;}%
}%
this.dirty=false;%
)>>%
}{%
/E<</S/JavaScript/JS(%
var fd=this.getField('tip.\thetcnt');%
if(typeof(click\thetcnt)=='undefined'){%
var click\thetcnt=false;%
var fdor\thetcnt=fd.rect;var dragging\thetcnt=false;%
}%
if(fd.display==display.hidden){%
fd.delay=true;fd.display=display.visible;fd.delay=false;%
}%
this.dirty=false;%
)>>%
/X<</S/JavaScript/JS(%
if(!click\thetcnt&&!dragging\thetcnt){fd.display=display.hidden;}%
if(!dragging\thetcnt){click\thetcnt=false;}%
this.dirty=false;%
)>>%
}%
/U<</S/JavaScript/JS(click\thetcnt=true;this.dirty=false;)>>%
/PC<</S/JavaScript/JS (%
var fd=this.getField('tip.\thetcnt');%
try{fd.rect=fdor\thetcnt;}catch(e){}%
fd.display=display.hidden;this.dirty=false;%
)>>%
/PO<</S/JavaScript/JS(this.dirty=false;)>>%
}%
}%
>>%
}%
}{{\color{#5}#6}}%
\sbox\tiptext{%
\IfBooleanT{#2}{%
\ocgbase@oc@bdc{\tpTipOcg}\ocgbase@open@stack@push{\tpTipOcg}}%
\fcolorbox{black}{#7}{#8}%
\IfBooleanT{#2}{\ocgbase@oc@emc\ocgbase@open@stack@pop\tpNull}%
}%
\cListSet\tpOffsets{#9}%
\edef\twd{\the\wd\tiptext}%
\edef\tht{\the\ht\tiptext}%
\edef\tdp{\the\dp\tiptext}%
\tipshift=0pt%
\IfBooleanTF{#2}{%
%OCG-based (that is, all non-draggable) boxes should not extend beyond the
%current column as they may get overlaid by text in the neighbouring column
\setlength\whatsleft{\linegoal}%
}{%
\measureremainder{\whatsleft}%
}%
\ifdim\whatsleft<\dimexpr\twd+\cListItem\tpOffsets{1}\relax%
\setlength\tipshift{\whatsleft-\twd-\cListItem\tpOffsets{1}}\fi%
\IfBooleanF{#2}{\tpPdfXform{\tiptext}}%
\raisebox{\heightof{#6}+\tdp+\cListItem\tpOffsets{2}}[0pt][0pt]{%
\makebox[0pt][l]{\hspace{\dimexpr\tipshift+\cListItem\tpOffsets{1}\relax}%
\IfBooleanTF{#2}{\usebox{\tiptext}}{%
\tpPdfAnnot{\twd}{\tht}{\tdp}{%
/Subtype/Widget/FT/Btn/T (tip.\thetcnt)%
/AP<</N \tpPdfLastXform>>%
/MK<</TP 1/I \tpPdfLastXform/IF<</S/A/FB true/A [0.0 0.0]>>>>%
/Ff 65536/F 3%
/AA <<%
/U <<%
/S/JavaScript/JS(%
var fd=event.target;%
var mX=this.mouseX;var mY=this.mouseY;%
var drag=function(){%
var nX=this.mouseX;var nY=this.mouseY;%
var dX=nX-mX;var dY=nY-mY;%
var fdr=fd.rect;%
fdr[0]+=dX;fdr[1]+=dY;fdr[2]+=dX;fdr[3]+=dY;%
fd.rect=fdr;mX=nX;mY=nY;%
};%
if(!dragging\thetcnt){%
dragging\thetcnt=true;Int=app.setInterval("drag()",1);%
}%
else{app.clearInterval(Int);dragging\thetcnt=false;}%
this.dirty=false;%
)%
>>%
>>%
}%
\tpAppendToFields{\tpPdfLastAnn}%
}%
}}%
\stepcounter{tcnt}%
}}
\makeatother
\newsavebox\tiptext\newcounter{tcnt}
\newlength{\whatsleft}\newlength{\tipshift}
\newcommand{\measureremainder}[1]{%
\begin{tikzpicture}[overlay,remember picture]
\path let \p0 = (0,0), \p1 = (current page.east) in
[/utils/exec={\pgfmathsetlength#1{\x1-\x0}\global#1=#1}];
\end{tikzpicture}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcommand{\centerwithin}[2]{% #1=small symbol, #2=wide symbol
{\mathmakebox[\widthof{\ensuremath{{}#2{}}}][c]{{#1}}}}

\begin{document}

\newcommand\tempbox{%
\begin{minipage}{0.18\textwidth}% almost impassible to pre-measure
\abovedisplayskip=0pt
\belowdisplayskip=0pt
\begin{align*}
&\centerwithin{\downarrow}{=} \text{using eq.~\eqref{eq0}} \\
&= 1 \\
&\centerwithin{\downarrow}{=} \mbox{using eq.~\eqref{eq1}} \\
&= 2 \\
&\centerwithin{\downarrow}{=} \mbox{using eq.}~\eqref{eq2}
\end{align*}
\end{minipage}}

\begin{align*}
0 &= 0\\
&\makebox[0pt][r]{%
\tooltip****{\fbox{\bfseries +}}{\tempbox}[-0.4em,-4ex]%
}\\
& = 3
\end{align*}

$$0 \label{eq0}$$

$$1 \label{eq1}$$

$$2 \label{eq2}$$

\end{document}

• Argument of \tpPdfLink has an extra }. <inserted text> \par l.209 \end{align*} – ranlot May 16 '18 at 15:10
• Get mirrors.ctan.org/macros/latex/contrib/media9/pdfbase.sty and mirrors.ctan.org/macros/latex/contrib/ocgx2/ocgbase.sty and upload them into your project directory on overleaf. – AlexG May 16 '18 at 15:12
• The links to referenced equations in the popup don't work – ranlot May 16 '18 at 15:24
• I mean the part "using eq. ()" doesn't click to the place where the equation is defined – ranlot May 16 '18 at 15:31
• See updated answer: As usual, hyperref must be loaded for this and a bit of patching hyperref is required. You may want to use AR as the PDF viewer, because in Evince the hyperlinked \eqref's won't disappear with the tip-box. – AlexG May 16 '18 at 15:40

I wasn't sure what to do with the equations (1) through (3), so I just left them as is. I used \tempbox to separate the long derivation from the OCG code, and \switchbox to align the derivation to the equation.

Note the use of flalign to left justify the derivation. Since equations expand to fill the entire column, it would be difficult to measure the width needed.

\documentclass{article}
\usepackage{mathtools}
\usepackage{ocgx}

\newsavebox{\tempbox}% simplify source
\newsavebox{\switchbox}% measure width
\savebox{\switchbox}{\fcolorbox{blue}{red}{\bfseries +}}

\newcommand{\centerwithin}[2]{% #1=small symbol, #2=wide symbol
{\mathmakebox[\widthof{\ensuremath{{}#2{}}}][c]{{#1}}}}

\begin{document}

\savebox{\tempbox}{\begin{minipage}{0.5\textwidth}% almost impassible to pre-measure
\abovedisplayskip=0pt
\belowdisplayskip=0pt
\begin{flalign*}
&\centerwithin{\downarrow}{=} \text{using eq.~\ref{eq0}} &\\
&= 1 \\
&\centerwithin{\downarrow}{=} \mbox{using eq.~\ref{eq1}} &\\
&= 2 \\
&\centerwithin{\downarrow}{=} \mbox{using eq.}~\ref{eq2}
\end{flalign*}
\end{minipage}}

\begin{align*}
0 &= 0\\
&\mbox{\hspace*{-\wd\switchbox}\switchocg{ocg1}{\usebox{\switchbox}}\begin{ocg}{OCG 1}{ocg1}{0}
\usebox{\tempbox}%
\end{ocg}}\\
& = 3
\end{align*}

$$0 \label{eq0}$$

$$1 \label{eq1}$$

$$2 \label{eq2}$$

\end{document}


Here is a variant which overlaps the text. Notice that only the text that comes after the OCG is visible.

\documentclass{article}
\usepackage{mathtools}
\usepackage{ocgx}

\newsavebox{\tempbox}% simplify source
\newsavebox{\switchbox}% measure width
\savebox{\switchbox}{\fcolorbox{blue}{red}{\bfseries +}}

\newcommand{\centerwithin}[2]{% #1=small symbol, #2=wide symbol
{\mathmakebox[\widthof{\ensuremath{{}#2{}}}][c]{{#1}}}}

\begin{document}

\savebox{\tempbox}{\begin{minipage}{\dimexpr\textwidth-\wd\switchbox-0.666ex}%

\abovedisplayskip=0pt
\belowdisplayskip=0pt
\begin{align*}
0 &= 0 \\
&\centerwithin{\downarrow}{=} \text{using eq.~\ref{eq0}} \\
&= 1 \\
&\centerwithin{\downarrow}{=} \mbox{using eq.~\ref{eq1}} \\
&= 2 \\
&\centerwithin{\downarrow}{=} \mbox{using eq.}~\ref{eq2} \\
&= 3
\end{align*}
\end{minipage}}

\begin{flalign*}
&&0 &= 0 &\\
\rlap{\switchocg{ocg1}{\usebox{\switchbox}}\begin{ocg}{OCG 1}{ocg1}{0}
\smash{\fcolorbox{black}{yellow}{\usebox{\tempbox}}}%
\end{ocg}} &&&&\\
&&& = 3
\end{flalign*}

$$0 \label{eq0}$$

$$1 \label{eq1}$$

$$2 \label{eq2}$$

\end{document}

• Is there a way so that the vertical gap (when the box is hidden) would be just for the 3 lines "0=0 \n + \n =3"? I don't care that the pop up would be completely on top (without transparency) even if it goes over surrounding text after it is revealed. The reason is that the derivations may be much longer (not more than 1 page) but such a large empty vertical gap would look weird... – ranlot May 16 '18 at 15:02
• oxgx has some issues (e. g, not working with other engines than pdflatex, such as lualatex). Use ocgx2 instead. – AlexG May 16 '18 at 15:21
• One can \smash it, but the result overlays the old text. One would need to make the OCG background opaque (if possible). Personally, I put all my derivations into apendixes (see elfsoft2000.com/acoustic/enclosure.pdf for example). – John Kormylo May 16 '18 at 15:29