I'm making a document where I want the definitions of entries in the glossary to appear as tooltips.
The tooltip code itself is from the answer: Can't embed hyperlink references in a tooltip
My function takes 3 arguments, the first being the name for defining function for the tooltip, the second being the name to appear in the glossary - which may be more than 1 word, and the 3rd to be the definition.
\newcommand{\defTerm}[3]{%
\expandafter\newcommand\csname #1\endcsname[1]{%
{\textbf{\tooltip{##1}{\begin{varwidth}{10cm}#3\end{varwidth}}}}%
}%
\newglossaryentry{#1}{name=#2,description={#3}}%
}
Ideally the tooltips with the defintions would also work for terms in the glossary itself. This would mean that in some cases in the body text, the 3rd argument would contain a command for creating a tooltip.
For example:
\defTerm{GP}{GP}{The ground plane.}
\defTerm{Transverse}{Transverse}{This is orthogonal to the \GP{GP}.}
Then in the text
The \Transverse{transverse} plane is ...
Which fails as it tries to create a tooltip with the contents
This is orthogonal to the \GP{GP}.
however \GP{GP}
tries to make a tooltip within this.
What I'd like to achieve is to modify my \defTerm
command so that when the tooltip command is used, regex replaces any commands within the definition (argument #3
) with \textbf
. In normal regex searching for: (\\[A-Z]\w+{)([a-zA-Z\s]*)(})
and replacing with \textbf{$2}
Here I have 2 issues. I have the regex somewhat working in a test environment however I can't find how to search for the backslash character. Possibly this has something to do with the compiling order. My second issue is to do with how/were to use \ExplSyntaxOn
and \ExplSyntaxOff
. My working non-working command is
% Command to add items to glossary and create the command for using tooltips
\newcommand{\defTerm}[3]{%
\expandafter\newcommand\csname #1\endcsname[1]{%
\ExplSyntaxOn
\tl_set:Nn \l_tmpa_tl { #3 }
\regex_replace_all:nnN {([A-Z]\w+{)([a-zA-Z\s]*)(})} {textbf{\2}} \l_tmpa_tl %Also should have backslash
\tl_use:N \l_tmpa_tl
\ExplSyntaxOff
{\textbf{\tooltip{##1}{\begin{varwidth}{10cm}#3\end{varwidth}}}}%
}%
\newglossaryentry{#1}{name=#2,description={#3}}%
}
Below is complete working code. I have the changes I'd like to make commented out.
\documentclass{article}
\usepackage{varwidth} % To allow maximum width boxes in tooltips
\usepackage{tooltips}
\begin{document}
\defTerm{GP}{GP}{The ground plane.}
\defTerm{Transverse}{Transverse}{This is orthogonal to the GP.}
%\defTerm{Transverse}{Transverse}{This is orthogonal to the \GP{GP}.} % What I would like to use instead of the line above
The \Transverse{transverse} plane is ...
\end{document}
And tooltips.sty is below. To be honest I don't understand much within the \tootip command. I only need to option with no asterisks, and don't need to change the font colour so any simplification to this would also be appreciated.
% https://tex.stackexchange.com/questions/397639/cant-embed-hyperlink-references-in-a-tooltip
\ProvidesPackage{tooltips}
% Command to add items to glossary and create the command for using tooltips
\newcommand{\defTerm}[3]{%
\expandafter\newcommand\csname #1\endcsname[1]{%
% \ExplSyntaxOn
% \tl_set:Nn \l_tmpa_tl { #3 }
% \regex_replace_all:nnN {([A-Z]\w+{)([a-zA-Z\s]*)(})} {textbf{\2}} \l_tmpa_tl %Also should have backslash
% \tl_use:N \l_tmpa_tl
% \ExplSyntaxOff
{\textbf{\tooltip{##1}{\begin{varwidth}{10cm}#3\end{varwidth}}}}%
}%
%\newglossaryentry{#1}{name=#2,description={#3}}%
}
\usepackage{pdfbase}[2017/03/16]
\usepackage{xparse,ocgbase}
\usepackage{xcolor,calc}
\usepackage{tikzpagenodes,linegoal}
\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:
\let\cListSet\clist_set:Nn\let\cListItem\clist_item:Nn
\ExplSyntaxOff
\makeatletter
\NewDocumentCommand{\tooltip}{%
ssssO{\ifdefined\@linkcolor\@linkcolor\else black\fi}mO{yellow!20}mO{0pt,0pt}%
}{{%
\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}%
}%
\cListSet\tpOffsets{#9}%
\edef\twd{\the\wd\tiptext}%
\edef\tht{\the\ht\tiptext}%
\edef\tdp{\the\dp\tiptext}%
\tipshift=0pt%
\IfBooleanTF{#2}{%
%OCG-based (that is, all non-draggable) boxes should not extend beyond the
%current column as they may get overlaid by text in the neighbouring column
\setlength\whatsleft{\linegoal}%
}{%
\measureremainder{\whatsleft}%
}%
\ifdim\whatsleft<\dimexpr\twd+\cListItem\tpOffsets{1}\relax%
\setlength\tipshift{\whatsleft-\twd-\cListItem\tpOffsets{1}}\fi%
\IfBooleanF{#2}{\tpPdfXform{\tiptext}}%
\raisebox{\heightof{#6}+\tdp+\cListItem\tpOffsets{2}}[0pt][0pt]{%
\makebox[0pt][l]{\hspace{\dimexpr\tipshift+\cListItem\tpOffsets{1}\relax}%
\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}%
}