25

I tried using the fancytooltips package and like it a lot. One thing that I could imagine would be nice is to have the entry showing up as a movable box instead of just a tooltip. (Sometimes the tooltip obscures other text.) Is this possible at all to implement? I mean it could take a lot of work, but if it's possible at all I'd like to look into it.

The examples and screenshots of fancytooltips can be found in this post. To quote from that post:


Both Gonzalo Medina and Audrey posted an excellent solution. But the things are simpler now. See the fancy-preview webpage - based on the new version of fancytooltips (May 2012), preview.sty and some bash scripts you get tooltips for bibliographic entries, theorems, definitions, displayed equations etc. automatically.

Small example and screenshots are attached.

\documentclass{article}
\usepackage{amsmath,amsthm}
\newtheorem{lemma}{Lemma}
\usepackage{hyperref} % Important!
\begin{document}

\begin{lemma}[Lemma from \cite{M}]\label{lemma}
  If $k<0$, then
  \begin{equation}
    \label{eq:1}
    x^2+k<x^2
  \end{equation}
  for every real number $x$.
\end{lemma}

Inequality \eqref{eq:1} in Lema \ref{lemma} can be proved easily. Is
more general than \cite[Theorem 3.4]{K}.

\begin{thebibliography}{9}
\bibitem[M]{M} Me: My book related to the problem (2006), 145 p.
  % The new line is important!

\bibitem{K} Karl: Karl's paper published in some minor proceedings, 
    a local conferrence organized by his university (2005), 23--25.
  % The new line is important!


\end{thebibliography}
\end{document}

The file in Adobe Reader

enter image description here

Ref M

enter image description here

Ref 1

enter image description here

Equation (1)

enter image description here

Lemma 1.

enter image description here

4
  • 1
    Just because many users (like me) might not be familiar with fancytooltips, could you add a MWE, perhaps even demonstrating the problematic overlap, and a picture of the output?
    – doncherry
    Apr 6, 2013 at 17:00
  • 1
    @doncherry Good point, I've just edited to add that!
    – Mika H.
    Apr 6, 2013 at 17:10
  • 1
    Thanks! Perhaps you could even include (reproduce) it in this question? We kind of like to have everything in one place.
    – doncherry
    Apr 6, 2013 at 17:20
  • 1
    @doncherry Done!
    – Mika H.
    Apr 6, 2013 at 21:35

1 Answer 1

29
+50

This would require hacking the fancytooltips package.

Since fancytooltips depends on packages which are not in TeXLive, I tried something on my own.

The tool-tip command defined below supports all common output drivers (LaTeX workflows):

  • latex->dvips->ps2pdf (dvips must not be called with option -Ppdf!)
  • latex->dvipdfmx
  • xelatex, lualatex, pdflatex

The command

\tooltip[<link text colour>]{<link text>}[<tip box colour>]{<tip text>}

creates a tooltip that can be dragged around.

The colour arguments are optional and default to blue and yellow!20. Predefined colour names and colour expressions according to the colour-model of the xcolor package can be used. Ifhyperref is loaded, its colour setting for internal links (option linkcolor) is used as <link text colour>.

<link text> is breakable across line endings, except for the latex->dvips->ps2pdf workflow.

Multi-line <tip text> should be put into a \parbox or minipage.

\documentclass[a6paper,12pt]{scrbook}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% tooltips with LaTeX v. 2017/11/28
%
% \tooltip[*[*[*[*]]]][<link colour>]{<link text>}[<tip box colour>]{<tip text>}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%   \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[linkcolor=<colour>]{hyperref}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage{pdfbase}[2017/03/16]
\usepackage{xparse,ocgbase}
\usepackage{xcolor,calc}
\usepackage{tikzpagenodes}
\usetikzlibrary{calc}

\ExplSyntaxOn
\let\tpPdfLink\pbs_pdflink:nn
\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:
\ExplSyntaxOff

\makeatletter
\NewDocumentCommand{\tooltip}{%
  ssssO{\ifdefined\@linkcolor\@linkcolor\else blue\fi}mO{yellow!20}m%
}{{%
  \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
    \ocgbase@add@ocg@to@radiobtn@grp{tool@tips}{\ocgbase@last@ocg}%
  }%
  \tpPdfLink{%
    \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}%
  }%
  \edef\twd{\the\wd\tiptext}%
  \edef\tht{\the\ht\tiptext}%
  \edef\tdp{\the\dp\tiptext}%
  \measureremainder{\whatsleft}\tipshift=0pt%
  \ifdim\whatsleft<\twd\setlength\tipshift{\whatsleft-\twd}\fi%
  \IfBooleanF{#2}{\tpPdfXform{\tiptext}}%
  \raisebox{\heightof{#6}+\tdp}[0pt][0pt]{\makebox[0pt][l]{\hspace{\tipshift}%
    \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}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\parindent=0pt
\begin{document}\Huge
Einstein's \tooltip{formula}{$E=m c^2$} is well known.
  Another famous formula is due to \tooltip{Pythagoras}{$a^2+b^2=c^2$}.
\end{document}

enter image description here

How it works:

Two PDF-Annotations (mouse-sensitive regions) are created: (1) A link around the blue link text, which is breakable across line endings. (2) An interactive (/Ff 65536) button (/FT/Btn) widget (/Subtype/Widget) for the tip text.

Visibility of the tip box is controlled via a JavaScript action that is bound to the mouse-enter event of the link. In order to show/hide the tip it is sufficient to repeatedly hover the mouse pointer over the link text.

The tip text may not be directly embedded into the page content; it couldn't be moved around otherwise. Rather, it is typeset into a box (\sbox) and subsequently distilled into a so-called Form-XObject, which is a self-contained PDF entity with graphical and/or textual content. This Form-XObject is bound to the button widget appearance via the /MK entry.

The dragging is implemented as a JavaScript action, which is triggered by the mouse-up event of the tip-text button. The mouse movement is tracked by the function drag() which is repeatedly executed using a JavaScript timer (app.setInterval). The deltas of the mouse position thus determined are continuously added to the coordinates (rect property) of the JavaScript Field object that represents the tip-text button.

10
  • 1
    That looks great, AlexG! Could you please add some comment on what each part of your code is doing, so that I (and others) can understand it more easily? Thanks!
    – Mika H.
    Apr 16, 2013 at 15:33
  • Currently I am a bit short of time. Will do that later.
    – AlexG
    Apr 17, 2013 at 6:33
  • 1
    @MikaH: ...Done. Plus some code fixes.
    – AlexG
    Apr 19, 2013 at 11:57
  • @AlexG Mother of God! img.mu.cdn.li/Ao/xqefEH.jpg Excellent work! Questions: Could it be made so that (in your MWE) "formula" could be replaced by \eqref{}, if you know what I mean? Also, does the end-user require anything other than a PDF viewer?
    – User 17670
    Apr 19, 2013 at 14:52
  • 1
    For further updates of the \tooltip command, see tex.stackexchange.com/a/111932
    – AlexG
    May 16, 2013 at 12:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .