23

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

AlexG
  • 54,894
  • 2
    Something like http://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?) –  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

1 Answers1

27
\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}
AlexG
  • 54,894
  • 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
  • @AlexG: I seem to have missed the point in that link, that fancytooltips is just mentioned but not used at all in that example. Regarding your code: I will give a try, although it makes use of XeTeX. Thanks –  Jun 19 '13 at 15:17
  • @Christian: It doesn't make use of XeTeX if you don't want it to be used. The code is just able to cope with any tool-chain, be it pdflatex, latex+dvips+ps2pdf, lualatex, ..., and xelatex. – AlexG Jun 19 '13 at 15:20
  • @AlexG: You are right, Alex... However, the code fails to compile, but I suspect, my TexLive 2010 distribution is to old and it misses some new features such as LaTeX3 extensions. Perhaps, I should update to a newer release before starting manually adding some packages each time my old pdflatex distribution complains about missing or incompatible packages... ;-) –  Jun 19 '13 at 15:30
  • @AlexG: Moving the mouse away is not sufficient to get the tool tip to go away. You have to move the mouse away, and then move it back to get it to go away. – Peter Grill Jun 19 '13 at 16:20
  • @Peter Yes, this is necessary to make the tip draggable. If I had coded it such that the tip goes away when the mouse is moved away, I couldn't move the mouse over the tip to drag it around. The tip would disappear before I could click on it for dragging. – AlexG Jun 19 '13 at 20:35
  • @AlexG: You should document that behavior in the asnwer as it was not obvious to me. – Peter Grill Jun 19 '13 at 21:14
  • @Peter: I could improve the code to make the tooltip work as expected/requested. – AlexG Jun 20 '13 at 07:27
  • @Christian: Updating TeXLive is a good idea. TeXLive-2013 is out for 3 days now. – AlexG Jun 20 '13 at 07:56
  • @AlexG: I will test your suggested solution on my notebook and update TeXlive on my workstation as soon as possible ;-) Unfortunately, I have a rather outdated Linux distribution as well, so I should better update the OS too. –  Jun 20 '13 at 11:51
  • @AlexG: I have switched to TeXLive-2012 as an intermediate state and tried to compile your solution code. However, it fails, stating that \tpPdfLink is an unknown control sequence, stopping at the same position as in old TeXLive-2010... –  Jun 21 '13 at 14:45
  • @AlexG: TeXLive-2013 does the job ;-) Thank you very much! –  Jun 21 '13 at 15:35
  • @AlexG: Great, thanks. The version http://user.mendelu.cz/marik/latex/tooltip2.tex ensures, that the tooltips appears inside the page bounds. This solves the problems if the word which activates the tooltip is closee to the right margin. Feel free to use this improvement, if you like it. (For simplicity, the file from my link depends on insdljs.sty, but this dependence can be removed surely) – robert.marik.cz Aug 05 '13 at 21:27
  • Can you please post a solution without clicking and dragging? I do not need such a feature and it makes Foxit Reader crashing. The mouseover works like expected. thx a lot for that – Megachip Nov 17 '13 at 23:48
  • 1
    @Megachip. Done. – AlexG Nov 18 '13 at 12:41
  • @AlexG I can't get this code to work anymore ? The code is processed as normally but the resulting document has no tooltips. I have JS enabled. – 1010011010 May 17 '14 at 10:36
  • 1
    @1010011010: No problem here with (frozen) TL-13. – AlexG May 19 '14 at 06:41
  • @AlexG Just found this interesting code, but didn't compile at all until I added package tikz. Ok... now it hangs with ./tooltip.tex:109: Undefined control sequence. \tpPdfLastXform ->\g_mix_pdflastxform_tl. Unfortunately I don't know how to remedy that. Any thoughts? – K.G. Feuerherm Nov 19 '15 at 23:49
  • 1
    Ok, the fixed the code will compile and work again, hopefully. – AlexG Nov 23 '15 at 11:30
  • I cannot compile this code, currently using pdflatex. – Peter Ebelsberger Mar 23 '16 at 23:30
  • @Peter No problem here with up-to-date TeXLive. Which error do you get? – AlexG Mar 24 '16 at 07:25
  • After another update it works perfect, on MiKTeX, sorry for this warning of noncompilalble code... – Peter Ebelsberger Mar 24 '16 at 09:41
  • I had the same problem as Peter's and had the same solution : update MikTeX. – user1771398 Mar 28 '16 at 18:14
  • A question : is there a mean to copy the comment (or the text with its comment) on another pdf, especially a non Latex pdf, a scanned pdf. An example of this could be the pdfcomments that get easily copied from the Latex pdf to a scanned pdf. – user1771398 Mar 28 '16 at 18:14
  • Is there a hope that someday, the different versions of this macro works with Evince? – Saroupille Jul 13 '19 at 06:55