Consejos para jugar golf en TeX / LaTeX

28

¿Qué consejos tienen las personas para jugar al golf en TeX / LaTeX? Publique un consejo por respuesta, cada uno al menos algo específico para TeX / LaTeX.


Contexto: me di cuenta de esta respuesta y de que no hay preguntas sobre consejos para TeX / LaTeX, así que estoy creando esta. Hay cierta superposición con los consejos de preguntas más estrictas para jugar al golf en TikZ (ya que TikZ es un paquete macro específico sobre TeX / LaTeX): las respuestas a esta pregunta probablemente también se apliquen allí, pero no al revés.

ShreevatsaR
fuente
¿Cómo puedes jugar al golf en un lenguaje que no es de programación?
The Great Duck
1
@TheGreatDuck Muy mal :-)
ShreevatsaR
@TheGreatDuck En realidad, TeX es un lenguaje de programación, incluso si generalmente se usa solo como tipográfico.
gvgramazio

Respuestas:

15

Considere las macros internas de LaTeX en lugar de las documentadas

Por ejemplo, \romanes una macro de LaTeX documentada que funciona en contadores de LaTeX. Para convertirse 42en XLIVtendrías que usar algo como

\newcounter{z}
\setcounter{z}{42}
\roman{z}

En cambio, al buscar cómo \romanse implementa (se usa \show\romanpara obtener esto de forma interactiva, en lugar de leer los archivos fuente), se puede ver que se implementa en términos de una macro útil llamada \@roman, y en su lugar se usa directamente:

\catcode`@11
\@roman{42}

\catcode`@11es la forma de escribir de golf \makeatletter(forma limpia en LaTeX) o \catcode`\@=11(forma limpia en TeX simple). Se necesita solo una vez al principio, después de esto puede usar nombres de macro que contengan @.

ShreevatsaR
fuente
13

~se puede usar como macro (al igual que otros caracteres activos)

Ejemplo

Antes de:

\def\a{...some definition...} ... use \a...

Después:

\def~{...some definition...} ... use ~...

Explicación : Generalmente las macros en TeX son "secuencias de control": puede definir \somethingo \a. Pero puedes ir aún más corto, usando un personaje activo. El único carácter activo que está presente de forma predeterminada (en TeX / LaTeX simple) es ~(usado para "empates", es decir, definido como \penalty \@M \en TeX simple (una penalización de 10000 seguido de un espacio), y como \nobreakspace {}en LaTeX). Pero nada le impide redefinirlo para cualquier propósito que necesite.

Además : puede hacer lo mismo con cualquier otro personaje estableciendo su código de gato en \active(13). Por ejemplo, hacer Zun carácter activo tiene un "costo" de 12 bytes: \catcode`Z13. Luego puede usar simplemente en Ztodas partes en lugar de una macro como \z. Para algunos caracteres que comienzan con un significado especial, el enfoque de retroceso directo no funciona y necesita un carácter más: \catcode`\Z13o \catcode90=13.

ShreevatsaR
fuente
9

\def puede coincidir con patrones fijos

Digamos que tuviste \def\a #1 #2 {...some definition here...}. Luego, cuando lo llame en una cadena como \a Act42, Scene26, dentro de la macro, los argumentos pueden asignarse como # 1 <- Act42,, # 2 <- Scene26y luego tendrá que hacer un trabajo adicional para extraer las partes relevantes. En cambio, uno podría escribir directamente

\def\a Act#1, Scene#2 {...some definition here...}

y luego llamarlo como \a Act42, Scene26establecería directamente # 1 <- 42y # 2 <- 26.

(Esta es básicamente la definición de \def, pero es fácil de olvidar ya que uno no suele hacer esto en LaTeX, prefiriendo pasar argumentos {}como si fueran llamadas a funciones).

ShreevatsaR
fuente
8

Elegir entre TeX simple y LaTeX

Se puede decir mucho sobre esto, pero en resumen, compare un documento normal típico de TeX que imprima "Hola" con un documento típico de LaTeX para lo mismo:

Hello
\bye

versus

\documentclass{article}
\begin{document}
Hello
\end{document}

El "costo" de LaTeX (wrt code golf) es obvio; El "beneficio", por supuesto, es que LaTeX viene con una biblioteca de muchas macros y paquetes escritos previamente, algunos de los cuales pueden ser útiles para la tarea en cuestión.

ShreevatsaR
fuente
Estaba atrapado en el uso de LaTeX debido a que \@Roman(hacer que las mayúsculas funcionen en plano costaría muchos bytes), pero el TeX simple a menudo sería más corto.
Chris H
8

\input ... es más corto que \usepackage{...}

Por ejemplo, puedes escribir

\input color

en lugar de

\usepackage{color}

que es 6 bytes menos.

Fatalizar
fuente
8
Sin embargo, es útil señalar que se \usepackagevuelve más eficiente a medida que aumenta la cantidad de paquetes que incluye. Como puede usar más de un paquete con una sola \usepackagedeclaración, pero requiere una \inputpara cada paquete, si está usando 3 o más paquetes, se \usepackageconvierte en la mejor opción.
Wheat Wizard
7

Si usa LaTeX, use un brevedocumentclass (idea de Chris H )

En lugar de comenzar con lo típico

\documentclass{article}

uno puede elegir clases de documentos más cortas como booko incluso

\documentclass{ecv}

o

\documentclass{tui}
ShreevatsaR
fuente
Debe recordar mantenerse dentro de las especificaciones de la pregunta, articlepor defecto numera sus páginas, esto puede considerarse una salida adicional. Quizás una meta pregunta es para determinar qué clases de documentos deberían permitirse.
Wheat Wizard
@WheatWizard Buen punto. Creo que puede depender de la pregunta individual si los números de página se consideran resultados adicionales.
ShreevatsaR
Creo que una clase mínima sería una buena idea: un solo nombre de letra y sin numeración de página
Chris H
He reunido uno g.clsque está justo article.clscon, \pagenumbering{gobble}pero como github está caído, no puedo ponerlo por ahora
Chris H
g.cls
Chris H
7

Crear un entorno llamado myenvironmentgenera los comandos \myenvironmenty \endmyenvironment. Estos se utilizan internamente para comenzar y finalizar el entorno. En algunos casos pueden usarse como atajos. Por ejemplo, en lugar de

\begin{itemize}
\item abc
\end{itemize}

uno puede hacer

\itemize
\item abc
\enditemize

No es compatible, no es confiable, no funciona en todos los casos, use bajo su propio riesgo, etc., etc.

Ian Thompson
fuente
Bienvenido al sitio!
DJMcMayhem
3
A menudo puede hacerlo \itemize{...}para ahorrar aún más.
Wheat Wizard
4

\usepackage{packagea,packageb,packagec} funciona, siempre y cuando no pase opciones a los paquetes.

Chris H
fuente
4

Corre líneas juntas. Los saltos de línea rara vez se necesitan en LaTeX / TeX, en comparación con muchos lenguajes de formato largo.

Chris H
fuente
3

Algunas macros que podría esperar necesitar llaves alrededor de sus argumentos en realidad no lo hacen, especialmente cuando se usan dentro de otra macro con #1argumentos de estilo.

La mayoría de las macros solo necesitan llaves si hay más de un token (carácter o secuencia de control) en el argumento.

\mymacro1          % equivalent to \mymacro{1}
\mymacro{12}       % equivalent to \mymacro{12}
\mymacro a         % equivalent to \mymacro{a}
\mymacro{ab}       % equivalent to \mymacro{ab}
\mymacro\foo       % equivalent to \mymacro{\foo}
\mymacro{\foo x}   % equivalent to \mymacro{\foo x}
Chris H
fuente
3

Si necesita usar la misma macro con un nombre largo varias veces, puede usarla \letpara definir un alias más corto.

\let\a\mymacrowithalongname
\a{foo}\a{bar}\a{qux}

Esto ahorra dos bytes \def\a{\mymacrowithalongname}, si no necesita múltiples tokens en la definición.

En lugar de un nombre de macro, puede tener un carácter activo para guardar en barras invertidas.

Tenga en cuenta que \letno solo funciona con nombres de macro sino también con primitivas integradas. Por ejemplo, si usa muchas \ifnum ... \ficonstrucciones en su código, definirlas \let\i\ifnumy usarlas \i ... \fipodría ahorrarle unos pocos bytes. Esto funciona incluso para \letsí mismo: \let\l\let.

Gilles 'SO- deja de ser malvado'
fuente
3

Use los grupos locales {... }sabiamente

Como se señaló en esta respuesta , los caracteres activos como ~pueden usarse como un nombre de macro. Desafortunadamente, ~es el único carácter activo de forma predeterminada, y cambiar el código cat por otro carácter es costoso: \catcode`!13toma 12 bytes. Si la nueva definición de macro solo es necesaria en una pequeña región de su código, los grupos locales pueden ser una solución.

Cuando TeX ingresa a un nuevo grupo local abierto por {, crea un nuevo nivel de agrupación en la pila de guardado interna. Esto significa que se guardan todas las macros y registros actuales. Cualquier modificación a ellos (a menos que se marque explícitamente como \global) ahora solo estará activa hasta que se cierre el grupo }. Esto significa que ~puede redefinirse dentro de un grupo, usarse allí con la nueva definición, y la definición anterior se restaurará automáticamente una vez que el grupo haya finalizado.

Aquí hay un ejemplo:

\def~{abc}
~ -- {\def~{123}~} -- ~

Esto salidas

abc - 123 - abc

Un efecto secundario interesante de este mecanismo de agrupación es que los valores antiguos todavía están disponibles dentro del grupo hasta que se cambien allí. Para ilustrar eso, imagine que queremos imprimir varios caracteres en función del valor de un contador, rellenarlos con espacios de una longitud fija y continuar con el valor del contador original. Esto podría lograrse de la siguiente manera:

\newcount\x
\x=3
Print a char \the\x\ times,
{\x=-\x \advance\x 10 pad with \the\x\ spaces,}
and go on with x=\the\x.

que salidas

Imprime un char 3 veces, rellena con 7 espacios y continúa con x = 3.

Este comportamiento de agrupación es especialmente importante si desea utilizar las macros estándar de TeX para bucles \loop ... \repeatanidados. Estas macros definen comandos internos y los usan para determinar cómo proceder. Anidarlos sin poner el lazo interno entre llaves confundirá los comandos internos y conducirá a un comportamiento inesperado.

siracusa
fuente
1

El avance de contadores, como

\advance\u by 1
\multiply\u by 3
\divide\u by 2

también funciona como

\advance\u1        % \u = \u + 1
\advance\u-1       % \u = \u - 1
\multiply\u3       % \u = \u * 3
\multiply\u\u      % \u = \u * \u
\divide\u2         % \u = \u / 2

El mismo principio también funciona para la inicialización:

\newcount\u\u1

establece el contador \ u en 1.

Tenga en cuenta que estos necesitan un carácter de espacio en blanco (salto de línea o espacio) después de ellos (o un \relax, pero el espacio en blanco hace lo mismo) para que no se ignore el siguiente comando. Por ejemplo,

\u1\the\u

NO imprime \ u, pero ignora el \thecomando.

Simon Klaver
fuente
1

\enddocumenten lugar de \end{document}guardar dos personajes

sheß
fuente
No parece funcionar para \begin{document}=> \documentaunque
sheß