20

I work as a Physics teacher and I am writing a "Problem-Solution-Book" with hyperlinks from problems to solutions and backreferencing -- all of it works pretty good.

Now I wanted to introduce something like a "Hint" - text at the problem header which is used as a tooltip, indicating some hints for possible ways to the solution (apart from directly clicking the "solution" link ;-))

I wonder whether it is possible to use LaTeX code in the second argument of the \pdftooltip command from pdfcomment package by Josef Kleber. I am using pdflatex and pdfcomment version 2.3a.

What I want to do is:

Using the \pdftooltip command and as the mouse moves over the relevant portion a tooltip box with, say, blue background colour, appears.

Here is a minimal working example:

\documentclass{book}

\usepackage{xcolor}

\usepackage{pdfcomment}

\begin{document}

\pdftooltip{foo}{%
\colorbox{blue}{%
Hint: What is the definition of foo?}% End of Colorbox
}% End of pdftooltip command

\end{document}

(Well it compiles without complaining, but it does not give the expected result :-( )

However, there is no blue background colour but an almost verbatim text of colorbox ... blue etc., bracketed by (presumably) pdf code.

I know, that there is the possibility of mathematical markup in pdftooltips, but what about "eye candy"? ;-)

Edited: I know of the packages fancytooltips or cooltooltips but they do not match my intents

  • 2
    Something like tex.stackexchange.com/a/108998 ? – AlexG Jun 19 '13 at 14:09
  • @AlexG: Thanks a lot for that link, but I've already seen that thread. Dragging around the tooltip box is not necessary, apart from the security issues by using fancytooltips and its insertion of javascript code into Adobe Reader. I also want to have the tooltip statement also in my problem environment and not in a separate external file, as required by fancytooltips (or have I misunderstood some options/features of that package?) – user31729 Jun 19 '13 at 14:22
  • What you see in the answer I linked does not use fancytooltips. The tooltip is inserted inline, no external file as requested. Moving the tooltip around is just a bonus feature (The tip text could be wider than the page). – AlexG Jun 19 '13 at 14:42
  • 1
    As for JavaScript, no risk no fun ;). – AlexG Jun 19 '13 at 15:03
20
\tooltip[black]{foo}[blue!50]{Hint: What is the definition of foo?}

If the mouse is moved over 'foo' the tip is shown and it disappears immediately when the mouse is moved out.

In order to drag the tip around, 'foo' must be clicked. The tip remains visible. Move the mouse over the tip, click it and move it around. Click the tip once more to pin it down at the current position.

To hide the tip, wipe over 'foo' with the mouse.

Link text and tip text colours are optional. Besides pdftex, all common drivers (xetex, dvips, ...) are supported.

It is recommended that <tip text> is not wider than \linewidth, <tiptext> should be put into a \parbox if necessary.

(Code by M. Scharrer from https://tex.stackexchange.com/a/17808 is used to compute initial left-shift for wider tip text boxes.)

enter image description here

%\documentclass[a6paper,12pt]{scrbook}
\documentclass[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}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}
\tooltip[black]{foo}[blue!50]{Hint: What is the definition of foo?}

with non-draggable tooltip: \tooltip**[black]{bar}[blue!50]{Hint: What is the definition of bar?}
\end{document}
  • Works well. But, shouldn't the tool tip go away upon mouse moving away? This requires a mouse over to toggle it on, and another mouse over to toggle it off. – Peter Grill Jun 19 '13 at 15:05
  • @Peter: I tried hard to implement this, but if one tries to relocate the tip box (the bonus feature), the mouse inevitably leaves the link area and the tip would be hidden. – AlexG Jun 19 '13 at 15:08
  • 1
    @Megachip. Done. – AlexG Nov 18 '13 at 12:41
  • 1
    @1010011010: No problem here with (frozen) TL-13. – AlexG May 19 '14 at 6:41
  • 1
    Ok, the fixed the code will compile and work again, hopefully. – AlexG Nov 23 '15 at 11:30

protected by user31729 Sep 6 '15 at 20:51

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?