3

So imagine you have a certain code which looks like this:

ABC, some text , LaLaLa
\tooltip*{A}{\includegraphics[scale=2]{images/A}}\tooltip*{B}{\includegraphics[scale=2]{images/B}}\tooltip*{C}{\includegraphics[scale=2]{images/C}}

Now note that the contents of the first {argument} of \tooltip re-appears in the {argument} of \includegraphics.

Now, in this case I manually input the A and B and C of the \includegraphics, to match with the A and B and C of \tooltip. But what if we would like to find a way for Tex to do this automatically?

Or even better, what if you would like to find a way to create an environment in which the end-user only has to type:

ABC

to automatically reproduce the first code?

I guess this could be done using regex, so how could you do it in a LaTeX way?


==DEFINITIONS==

What is meant by Tooltip here, can be found explained in this answer.

6
  • What do you mean by the "first code"? Just the three\tooltip lines?
    – Alan Munn
    Sep 19, 2017 at 5:30
  • Why a regex? If you are okay with the input form A,B,C,D use a comma-separated list (l3clist) and just use a map function to give you tooltip and image...
    – TeXnician
    Sep 19, 2017 at 5:32
  • But please post a full minimal working example (MWE), which is compilable.
    – TeXnician
    Sep 19, 2017 at 5:32
  • @TeXnician Actually I am not OK with a comma-seperated list. I would like the symbols to be right next to each-other, as such: ABCD
    – O0123
    Sep 19, 2017 at 6:27
  • Is there only one letter per tooltip? Then you can do this also in a very simple way.
    – TeXnician
    Sep 19, 2017 at 6:31

4 Answers 4

2

Not sure of what you're trying to do, but here's a fairly general approach, based on the code in https://tex.stackexchange.com/a/164186/4427

This doesn't support \tooltips**, but it would be easy to extend it.

The first optional argument is for \includegraphics options to be passed to every picture; the trailing optional argument is for setting a separation between the items (default nothing).

\documentclass[a6paper,12pt]{scrbook}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% tooltips with LaTeX
%
% optimized for Adobe Reader (visible on mouse-over)
%     usage: \tooltip[<link colour>]{<link text>}[<tip box colour>]{<tip text>}
%   non-draggable version:
%     usage: \tooltip*[<link colour>]{<link text>}[<tip box colour>]{<tip text>}
%
% for Evince (visible on click, not draggable)
%   usage: \tooltip**[<link colour>]{<link text>}[<tip box colour>]{<tip text>}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\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}{ssO{blue}mO{yellow!20}m}{{%
  \leavevmode%
  \IfBooleanT{#1}{%
    \ocgbase@new@ocg{tipOCG.\thetcnt}{%
      /Print<</PrintState/OFF>>/Export<</ExportState/OFF>>%
    }{false}%
    \xdef\tpTipOcg{\ocgbase@last@ocg}%
  }%
  \tpPdfLink{%
    \IfBooleanTF{#2}{%
      /Subtype/Link/Border [0 0 0]/A <</S/SetOCGState/State [/Toggle \tpTipOcg]>>
    }{%
      /Subtype/Screen%
      \IfBooleanTF{#1}{%
        /AA<<%
          /E<</S/SetOCGState/State [/ON \tpTipOcg]>>%
          /X<</S/SetOCGState/State [/OFF \tpTipOcg]>>%
        >>%
      }{
        /AA<<%
          /E<</S/JavaScript/JS(%
            var fd=this.getField('tip.\thetcnt');%
            \IfBooleanF{#1}{%
              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{#3}#4}}%
  \sbox\tiptext{\fcolorbox{black}{#5}{#6}}%
  \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%
  \tpPdfXform{\tiptext}%
  \raisebox{\heightof{#4}+\tdp}[0pt][0pt]{\makebox[0pt][l]{\hspace{\tipshift}%
    \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]>>>>%
      \IfBooleanTF{#1}{%
        /Ff 65537/OC \tpTipOcg%
      }{%
        /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}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\ExplSyntaxOn
\NewDocumentCommand{\tooltips}{sO{}m+O{}}
 {
  \clist_map_inline:nn { #3 }
   {
    \IfBooleanTF{#1}{\tooltip*}{\tooltip}{##1}{\includegraphics[#2]{##1}}#4
   }
 }
\ExplSyntaxOff

\begin{document}

\tooltips[width=2cm]{example-image-a,example-image-b,example-image-c}

\bigskip

\tooltips[width=2cm]{example-image-a,example-image-b,example-image-c}[\par]

\end{document}
14
  • Wow @egreg thank you. I am very happy that the interactivity of the \tooltip has been preserved now. There is a problem though. Your code works if I put an images A.png and B.png next to your .tex file, and I change your code to \tooltips[scale=1]{A,B}. But what I would actually like it to do is to work for such images without the comma. Just like \tooltips[scale=1]{ABCD} and so on. Do you think your answer could be adapted to achieve this?
    – O0123
    Sep 19, 2017 at 10:04
  • @VincentVerheyen Yes, of course: change \clist_map_inline:nn into \tl_map_inline:nn. That's one thing I was unsure of: it greatly limits the possibility of naming the images.
    – egreg
    Sep 19, 2017 at 10:50
  • Building on your code I have one final question to ask before my purpose is reached. It's about what to do when the whole image-set using a different encoding. Batch convert either the image filenames (and how?) or use a conversion function within your code?
    – O0123
    Sep 20, 2017 at 1:18
  • @VincentMiaEdieVerheyen I don't understand; what encoding are you referring to?
    – egreg
    Sep 20, 2017 at 8:35
  • Maybe I shouldn't have used the word encoding. It's all in the new (now already solved) question.
    – O0123
    Sep 21, 2017 at 5:15
7

Something like this? You certainly don't need a regex to do this. Here's a solution using etoolbox's \docsvlist. I've given a simple definition of \tooltip, since you don't define it, and I assume it's not directly relevant for the problem.

\documentclass{article}
\usepackage[demo]{graphicx}
\usepackage{etoolbox}
\newcommand{\tooltip}[1]{#1}
\newcommand{\ttips}[1]{%
  \renewcommand\do[1]{\tooltip{##1}\includegraphics[width=1cm]{images/##1}}
  \docsvlist{#1}}
\begin{document}
\ttips{A,B,C}
\end{document}

output of code

5
  • @Ala_Munn Let me specify what is meant by Tooltip in the OP. My apologies.
    – O0123
    Sep 19, 2017 at 6:04
  • 1
    @VincentVerheyen It's unlikely that the actual definition matters. If this syntax for the \ttips macro is useful to you then you can supply your own version of \tooltip.
    – Alan Munn
    Sep 19, 2017 at 6:06
  • @Alan_Munn I see what you mean, but people who don't know what they are doing (like me) might get errors such as: Command \tooltip already defined.
    – O0123
    Sep 19, 2017 at 6:24
  • 1
    @VincentVerheyen that's why questions should always (well almost always) have a complete test file supplied! Sep 19, 2017 at 6:44
  • @DavidCarlisle I hear you. I hope you like my follow-up question, which now shows the complete test file and use-case.
    – O0123
    Sep 20, 2017 at 1:44
6

LaTeX has a suitable loop already defined so you just need

enter image description here

\documentclass{article}

\def\tooltip#1{[ttip-#1]}
\usepackage{graphicx}

\makeatletter
\def\zz#1{%
 \@tfor\tmp:=#1\do{%
 \tooltip{\tmp}%
 \includegraphics[width=1cm]{example-image-\tmp}%
 }}

\begin{document}

\zz{abc}

\end{document}

adjust the definition of \tooltip as required.

1

With the listofitems package. The list delimiter (default ,) can be reset with \setsepchar{<delimiter>}. Reset \tooltip as needed.

\documentclass{article}
\usepackage{listofitems,graphicx}
\def\tooltip#1{[ttip-#1]}
\newcommand\retool[1]{%
  \readlist\mylist{#1}%
  \foreachitem\i\in\mylist{%
    \tooltip{\i}%
    \includegraphics[width=1cm]{example-image-\i}%
  }%
}
\begin{document}
\retool{a,b,c}
\end{document}

enter image description here

To use a list with no delimiters, here is an adaptation:

\documentclass{article}
\usepackage{listofitems,graphicx}
\def\tooltip#1{[ttip-#1]}
\newcommand\retool[1]{%
  \def\tmp{}%
  \ignoreemptyitems%
  \pretool#1\relax%
  \readlist*\mylist{\tmp}%
  \foreachitem\i\in\mylist{%
    \tooltip{\i}%
    \includegraphics[width=1cm]{example-image-\i}%
  }%
}
\makeatletter
\def\pretool#1#2\relax{%
  \g@addto@macro\tmp{#1,}%
  \if\relax#2\relax\else\pretool#2\relax\fi
}
\makeatother
\begin{document}
\retool{abc}
\end{document}
3
  • And if we would want no delimiter please, but instead have an image for every single character?
    – O0123
    Sep 19, 2017 at 10:19
  • @VincentVerheyen The one disallowed case, unfortunately...but I will adapt something. Sep 19, 2017 at 10:20
  • @VincentVerheyen I have revised my answer to provide an adaptation that uses each token of the argument as input. Sep 19, 2017 at 10:27

You must log in to answer this question.

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