¿Preguntas de broma/trolling de códigos para TeX.SX?

¿Preguntas de broma/trolling de códigos para TeX.SX?

Tengo un amigo que me utiliza para soporte LaTeX. No es muy experto en tecnología, pero le gusta LaTeX, por lo que lo ayudo cuando algo que necesita hacer requiere más que el stock estándar de macros y entornos.

Nos gusta gastarnos bromas unos a otros. Tuve la idea de hacerle una broma la próxima vez que pidiera ayuda de LaTeX haciendo algo relativamente benigno y fácilmente reversible que alteraría notablemente el PDF generado... o hacer algo más notable en el uso normal de (La)TeX, comocompilación prolongada---de una manera no deseada donde la fuente del problema sería difícil de detectar (por lo que sería un caso de trolling de código, supongo). Sin embargo, yo no soy muy bueno con LaTeX, así que pensé en pedir sugerencias creativas a los TeXperts.

¿Cómo puedo hacerle pasar un mal rato a mi amigo relacionado con (La)TeX?

Respuesta1

Agregue a su auxarchivo el siguiente fragmento de código, que es un quine. Cuando el auxarchivo está \inputal comienzo de una ejecución de LaTeX, el código aquí creará una copia de sí mismo y la escribirá en el auxarchivo para la siguiente ejecución. Además, ejecutará el código que se incluye \toks2a continuación. Por ejemplo, el código que elegí aumenta el tamaño de sangría en cada párrafo, pero sólo si TeX se ejecuta en un minuto impar: los resultados dependen de cuándo compila tu amigo.

{%
  \toks@{%
    \ifx\@nodocument\relax\else
      \toks2{% Here you put whatever mean code you want
        \ifodd\time
          \everypar\expandafter{%
            \the\everypar
            \advance\parindent 2pt\relax
          }%
        \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@
}

Después de una ejecución, el auxarchivo contendrá la siguiente versión condensada (en una sola línea)

{\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@ }

y las ejecuciones posteriores dejarán la misma versión condensada (nuevamente en una línea).

Veamos qué sucede en detalle: dentro de un grupo (simple), el registro del token \toks@se establece en algún valor y luego se utiliza su contenido. ¿Qué hacen esos contenidos? Hay una prueba para comprobar si estamos leyendo el archivo auxiliar al inicio o al final de la ejecución: \@nodocumentes \relaxen el segundo caso y no hacemos nada. Luego, el registro de toks \toks2se configura con el código que realmente desea realizar. La siguiente \edef\x{...}\xconstrucción amplía ...el

\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

luego realiza ese código. \AtBeginDocumentejecutará su argumento un poco más tarde, una vez que LaTeX esté nuevamente listo para escribir en el auxarchivo (actualmente lo está leyendo). Entonces, una vez que LaTeX está listo para escribir en el auxarchivo, ejecuta su código (que se almacenó temporalmente en \toks2), luego lo almacena <contents of \toks@>nuevamente \toks@(este registro de token puede haber sido utilizado por otro código intermedio) y escribe lo siguiente en el archivo. auxarchivo (recuerde que \writese expande):

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

Este es precisamente el código original, que por tanto acaba en el auxarchivo para la siguiente ejecución de LaTeX.

Con suerte, el código que elegí ingresar \toks2es bastante fácil de seguir:

\ifodd\time
  \everypar\expandafter{%
    \the\everypar
    \advance\parindent 2pt\relax
  }%
\fi

si el tiempo (en minutos desde el comienzo del día) es un número impar, entonces en cada párrafo, haga lo que ya se hizo en cada párrafo y también avance (aumente) la sangría del párrafo ( \parindent) en 2 puntos. Por ejemplo, supongamos que agrega el primer o segundo fragmento de código anterior al auxarchivo generado al ejecutar pdflatexel documento siguiente. Entonces el documento será normal si se compila en un minuto par y, de lo contrario, tendrá una sangría de párrafo cada vez mayor.

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

Respuesta2

Compilar con 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}

También \randomerroren lugar de \randomuclcpuede ser agradable.

ingrese la descripción de la imagen aquí

Respuesta3

Siga las instrucciones después de cada ejecución, es posible que haya descubierto algo.:)

Para aquellos que no se atrevieron a intentarlo, lo que hace es producir un mensaje de error (aquí desde un buffer de ayuda de emacs tex), donde el número de página es aleatorio:

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.

y además este mensaje aparece después de retrasos cada vez más prolongados al final de cada nueva compilación (el tiempo de compilación es del orden de n^2/2segundos donde nestá el número de ejecuciones anteriores).

La conversión hexadecimal para ofuscar el código es un poco larga, tal vez se podrían usar números hexadecimales solo para ofuscar el \inputlugar donde el archivo contendría el siguiente código.

\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}

El código hexa (con espacios al final de las líneas) no

\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

Respuesta4

Publicado como respuesta en lugar de comentario porque el código es demasiado largo. Basado en la respuesta de Bruno Le Floch, con un pequeño giro insinuado por egreg en el chat.

Añade esto a tu auxiliar:

{%
  \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
                \advance\parindent 2pt\relax
              \else
                \advance\parindent -2pt\relax
              \fi
            \else
              \advance\parindent 2pt\relax
            \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@
}

Si compila esto con pdflatex(o lualatexcon el pdftexcmdspaquete cargado), el cambio \parindentse invierte cada segundo durante la compilación, cualquier otro compilador producirá lo mismo que el código de Bruno.


¿Podrían las cosas empeorar más que esto? ¡Oh, sí, pueden! En lugar de editar el archivo auxiliar directamente (lo que se desharía con una limpieza del directorio de compilación), modifiquemos un poco los ejecutables.

NOTA: Como Daniel mencionó en los comentarios a continuación, trollear a personas no calificadas es realmente malo, así que use un poco de sentido común para juzgar quién podría entender lo que está sucediendo con una mirada más cercana.Además, no asumo responsabilidad alguna por la pérdida de amigos o la desconfianza permanente hacia los scripts que envías ;)

La próxima vez que tu amigo te pida ayuda, envíale este archivo como 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

Desafortunadamente, esto solo funciona en Linux y probablemente se solucione fácilmente agregando rutas completas o argumentos adicionales a pdflatex, pero la idea general es la siguiente:

  • Obtener la ubicación de los ejecutables originales.
  • crear un directorio para almacenar los ejecutables 'actualizados'
  • crear una cantidad de archivos, con los permisos adecuados para ejecutar
  • en cada archivo verifique si el archivo auxiliar ya existe y, si no, créelo con el código anterior
  • luego deje que el nuevo script llame al antiguo ejecutable para generar la salida, con el archivo auxiliar potencialmente alterado
  • finalmente agregue este nuevo directorio a la variable de entorno $PATH

Algunos datos curiosos:

  • esto solo funciona si bashse usa, de lo contrario ~/.bashrcno se usa
  • el código solo se agrega si el archivo auxiliar aún no existe
  • solo funciona después de ~/.bashrcobtener la fuente, por lo que después de un nuevo inicio de sesión o se abre una nueva ventana de terminal

EDITARAún más datos divertidos:

  • ejecutar which pdflatexdevuelve el original pdflatex, mientras que pdflatex test.texen realidad ejecuta el nuevopdflatex
  • en un sistema multiusuario esto sólo afecta al usuario que ejecuta elupdate-tl.sh
  • nada está roto permanentemente, simplemente eliminar los [pdf|lua|xe]latexscripts ~/.tex-updatesy los archivos auxiliares hace que todo vuelva a la normalidad :) (a diferencia de mi idea original de cambiar los ejecutables dentro del bindirectorio :P)

información relacionada