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.

O0123
  • 1,773

4 Answers4

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

Alan Munn
  • 218,180
  • @Ala_Munn Let me specify what is meant by Tooltip in the OP. My apologies. – O0123 Sep 19 '17 at 06: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 '17 at 06: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 '17 at 06:24
  • 1
    @VincentVerheyen that's why questions should always (well almost always) have a complete test file supplied! – David Carlisle Sep 19 '17 at 06: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 '17 at 01: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.

David Carlisle
  • 757,742
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}
egreg
  • 1,121,712
  • 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 '17 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 '17 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 '17 at 01:18
  • @VincentMiaEdieVerheyen I don't understand; what encoding are you referring to? – egreg Sep 20 '17 at 08:35
  • Maybe I shouldn't have used the word encoding. It's all in the new (now already solved) question. – O0123 Sep 21 '17 at 05:15
  • How could I stop the code from jamming if one character doesn't have a corresponding image please? – O0123 Oct 04 '17 at 04:42
  • @VincentMiaEdieVerheyen I don't understand what you're asking. – egreg Oct 04 '17 at 06:20
  • My apologies, I shouldn't have used the word character above, as it does not suit the generic case. Currently, if one includes \tooltips[width=2cm]{example-image-abc} there will be an error File 'example-image-abc' not found. My question is: how to prevent this error from popping up, and just let the document proceed with compiling instead. – O0123 Oct 04 '17 at 06:36
  • @VincentMiaEdieVerheyen I still don't understand: what are you planning to do for missing images? If you type a wrong name, LaTeX warns you, what else? – egreg Oct 04 '17 at 06:59
  • The problem is that I am using this code on a (traditional Chinese) text, which will look for each (traditional Chinese) character's stroke order image (meaning perhaps tens of thousands of characters, and thousands of images). The problem is that my set of images is not complete. Meaning there might be a hundred of such errors, which might be a nuisance. I know one could ignore all errors, but that would still require some sort of user-interaction during compilation on the system I am on (TeXShop). – O0123 Oct 04 '17 at 07:03
  • The problem with skipping all errors at once (which is possible in TeXShop) is that I only want the image-errors of the type File '... not found. If I would skip all compilation-errors for the whole document (perhaps also ones not of the type above), I might thus miss other errors I do want to get notified of. – O0123 Oct 04 '17 at 07:06
  • @VincentMiaEdieVerheyen I seem to remember that this problem has already been discussed. Please, do a search and, if you find nothing, ask a new question. – egreg Oct 04 '17 at 07:23
  • I still very much enjoy your code, but have found there is some sort of incompatibility with including \kern into it (well I also combined it with a separator). I have therefor asked a new OP at "Why is there a conflict between \kern and this customized Tooltips/Separator command". – O0123 Oct 12 '17 at 11:04
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}