5

While working on curating my lecture notes with LaTeX, I've come across a dilemma:

            readability and aesthetics VS. rigor and comprehensiveness

I find myself e.g. working on a proof, and boiling it down to a few, slick arguments, but then recognize that I might have trouble following it later on. Not willing to sacrifice elegance or overwhelm my future self with huge chunks of explanatory texts, I thought, let's comment the proof. The idea would be to show comments if they were needed, but, by default, have them be hidden.

Some options include fancytooltips and pdfcomment, but their intended purposes differ from what I'm aiming to do.

What I'm aiming to do

Something like this:

                     illustrative example

The idea is simply that, while pressing a key (e.g. S, but might as well be a custom command, just preferably not a button in the PDF itself) on the keyboard, some additional elements (pre-rendered in LaTeX) show in the PDF, and, once the S key is no longer pressed, they hide (a toggling option might also be interesting). The difficulty is that this interaction would have to be able to:

  1. Show/hide TikZ pictures (esp. overlays),
  2. Change the color / highlighting / etc. of regular text shown in the document,
  3. Be reasonably efficient (when viewing the PDF in e.g. Acrobat) and not make the LaTeX source code completely unreadable.

Possible approaches

Now, I know that there are animation packages with similar functionalities (e.g. animate, see this question I've asked for an MWE on switching between TikZ pictures by clicking on a button).

Another possibility might be directly embedding JavaScript code into the PDF file via LaTeX code (see AlexG's wonderful answer to this question). This should be possible (hopefully? See p. 651 table 8.46 of the PDF-1.7 reference, and p. 709), and might even be the best way of doing so in terms of efficiency and compact code, but I must say I'd be very grateful for a couple tips on how to do it, since I can already see myself spending hours on end troubleshooting).

Working with booleans in LaTeX probably doesn't serve this purpose too well, as I suspect that one can't just toggle them in the rendered output (or then expect anything to change). But I'd be very happy if I'm mistaken.

I hope this question is not too broad; if I could narrow it down any further, I would, but which direction I should go in is, of course, actually part of the question. In any case, thank you so much for reading this or taking time to comment or answer, and all the best!

Below is a minimal non-working example:

\documentclass[12pt]{report}

\usepackage{tikz}
\usepackage{xcolor}

\newif\ifshowcomments

\begin{document}
    \showcommentsfalse

    \ifshowcomments 
        \tikz[overlay]{\draw[green!50!black](0,-.1) -- (1,-.1); \draw[green!50!black,->](.7,-.6) node[xshift=5, yshift=5]{\tiny interesting} -- (.1,-.6) -- (0.1,-.1)}%
        \textcolor{green!50!black}{lorem}
        \tikz[overlay]{\draw[blue!75!black](0,.4) -- (1,.4); \draw[blue!75!black,->] (0.1,1) node[xshift=12, yshift=-3]{\tiny $math$} -- (0.1,.4)}%
        \textcolor{blue!75!black}{ipsum}
    \else lorem ipsum \fi
    %
    \showcommentstrue\hspace{1cm}
    %
    \ifshowcomments 
        \tikz[overlay]{\draw[green!50!black](0,-.1) -- (1,-.1); \draw[green!50!black,->](.7,-.6) node[xshift=5, yshift=5]{\tiny interesting} -- (.1,-.6) -- (0.1,-.1)}%
        \textcolor{green!50!black}{lorem}
        \tikz[overlay]{\draw[blue!75!black](0,.4) -- (1,.4); \draw[blue!75!black,->] (0.1,1) node[xshift=12, yshift=-3]{\tiny $math$} -- (0.1,.4)}%
        \textcolor{blue!75!black}{ipsum}
    \else lorem ipsum \fi
\end{document}

Output (cropped):

enter image description here

steve
  • 2,154

1 Answers1

7

How about using ocgx? Here is an example. It requires Acrobat reader, or viewers with equivalent capabilities. If you compile this (twice, because this is how remember picture works)

\documentclass{article}
\renewcommand*\familydefault{\sfdefault}
\usepackage[tikz]{ocgx2}
\usetikzlibrary{positioning,tikzmark}

\begin{document}
\tikzmarknode{lorem}{lorem} \tikzmarknode{ipsum}{ipsum} \hfill\switchocg{ocg1}{illuminate}

\begin{ocg}{OCG 2}{ocg1}{0}
\begin{tikzpicture}[overlay,remember picture]
\begin{scope}[green!60!black]
\node at (lorem) {lorem};
\draw ([yshift=-2pt]lorem.south west) coordinate (aux) -- ([yshift=-2pt]lorem.south east)
 node[pos=0,below right=1ex,font=\tiny] (int) {interesting};
 \draw[-stealth] ([yshift=-1pt]int.south east) -| 
 ([xshift=-1pt]int.west|-aux);
\end{scope}
\begin{scope}[blue]
\node at (ipsum) {ipsum};
\draw ([yshift=2pt]ipsum.north west) coordinate (aux) --
 ([yshift=2pt]ipsum.north east) node[midway,above=1ex,font=\tiny] (math) {$math$};
 \draw[-stealth] ([xshift=-1pt]math.north west)  -- 
 ([xshift=-1pt]math.west|-aux);
\end{scope}
\end{tikzpicture}
\end{ocg}
\end{document}

you get

enter image description here

If you click on iluminate, this becomes

enter image description here

If you click again, you are back at the first output.

I am sure AlexG can make this more elegant, but this may be a start.

ADDENDUM: Indeed, AlexG can make this way more elegant.

\documentclass{article}
\renewcommand*\familydefault{\sfdefault}
\usepackage[tikz]{ocgx2}
\usetikzlibrary{positioning,tikzmark}

\begin{document}
\tikzmarknode{lorem}{lorem} \tikzmarknode{ipsum}{ipsum} \hfill\actionsocg[onmouseall]{}{,,ocg1,}{,,,ocg1}{illuminate}

\begin{ocg}{OCG 2}{ocg1}{0}
\begin{tikzpicture}[overlay,remember picture]
\begin{scope}[green!60!black]
\node at (lorem) {lorem};
\draw ([yshift=-2pt]lorem.south west) coordinate (aux) -- ([yshift=-2pt]lorem.south east)
 node[pos=0,below right=1ex,font=\tiny] (int) {interesting};
 \draw[-stealth] ([yshift=-1pt]int.south east) -| 
 ([xshift=-1pt]int.west|-aux);
\end{scope}
\begin{scope}[blue]
\node at (ipsum) {ipsum};
\draw ([yshift=2pt]ipsum.north west) coordinate (aux) --
 ([yshift=2pt]ipsum.north east) node[midway,above=1ex,font=\tiny] (math) {$math$};
 \draw[-stealth] ([xshift=-1pt]math.north west)  -- 
 ([xshift=-1pt]math.west|-aux);
\end{scope}
\end{tikzpicture}
\end{ocg}
\end{document}

Seems that there is a lot of things curious cats can still learn.

  • This does indeed look exactly like what I'm looking for, except that the ocgx2 documentation doesn't list key listeners as an option to toggle the layer visibilities (it asks to choose one of onmousenter, onmouseexit, onmousedown, onmouseup, onmouseall). Maybe I could make a small change in the package's source code? Or are key listeners just not a good idea for this (even after defining its scope of action and other details)? (Or, if the change is easily implemented, maybe it could even become part of the official package?) – steve Mar 19 '20 at 20:47
  • @ABlueChameleon This request is beyond my pay grade. All I can offer are basic things as in the answer. I feel that you may want to try to talk to AlexG directly (there is a link to GitHub). All I can say is that I like your question very much, especially in view of the current coronavirus nightmare, where all of us have to explore new ways of communicating. I am very grateful to Alex for what he has given to us, and I could imagine that his contributions are now more relevant than ever, so he may be busy. –  Mar 19 '20 at 21:04
  • 3
    In order to listen to mouse-down and mouse-up, replace \switchocg... with \actionsocg[onmouseall]{}{,,ocg1,}{,,,ocg1}{illuminate} – AlexG Mar 19 '20 at 21:11
  • 2
    @AlexG That's truly amazing! –  Mar 19 '20 at 21:12
  • Thank you, @Schrödinger'scat for your kind words! – AlexG Mar 19 '20 at 21:12
  • @Schrödinger's cat: that's very fair. I'll try to contact AlexG then, but, to be honest, this is me nitpicking; the functionality is essentially all there already. Thank you so much for your answer! – steve Mar 19 '20 at 21:12
  • 1
    @ABlueChameleon See Alex' comment above. It is all included (but obviously I did not know). –  Mar 19 '20 at 21:14
  • @AlexG Yes, it is truly amazing! Thank you so much! (If you want to write an answer, I will be happy to retract mine.) –  Mar 19 '20 at 21:16
  • 1
    Adding another one is not necessary. Just edit yours! – AlexG Mar 19 '20 at 21:17
  • Wait, I just tested the change with the answer's MWE, but I don't see any changes in the output? Also, is this not different from key listeners (keyboard input) anyways? – steve Mar 19 '20 at 21:18
  • Nevermind, I see the change now (sorry for not noticing). Still though, doing this with keystrokes isn't possible right now, right? – steve Mar 19 '20 at 21:19
  • Apart from form fields for text input, PDF doesn't listen to keypress events on the keyboard. – AlexG Mar 19 '20 at 21:20
  • @AlexG I see, so there's nothing one can really do in that regard. Well, then this is pretty much perfect! Thank you two so much! – steve Mar 19 '20 at 21:20
  • I must admit that the documentation (Readme.md) is a bit too compact. Examples are missing. – AlexG Mar 19 '20 at 21:30
  • 2
    @AlexG I think it is already very good: it works and basic things one can find, so thanks a lot for all you have done! Probably in the near future there will be more and more questions regarding this, so one can also learn from examples. Writing a manual requires some knowledge on what others would like to know, and where they struggle. I guess these questions will help determining the needs. –  Mar 19 '20 at 21:32