Suggerimenti per giocare a golf in TeX / LaTeX


28

Quali consigli hanno le persone per giocare a golf in TeX / LaTeX? Si prega di inviare un suggerimento per risposta, ciascuno almeno in qualche modo specifico per TeX / LaTeX.


Contesto: ho notato questa risposta e non esiste una domanda di suggerimenti per TeX / LaTeX, quindi sto creando questa. C'è qualche sovrapposizione con i suggerimenti per le domande più ristretti per giocare a golf in TikZ (poiché TikZ è un pacchetto macro specifico in cima a TeX / LaTeX): le risposte a questa domanda probabilmente si applicheranno anche lì, ma non viceversa.


Come si può giocare a golf un linguaggio non di programmazione?
The Great Duck,

1
@TheGreatDuck Molto male :-)
ShreevatsaR,

@TheGreatDuck In realtà, TeX è un linguaggio di programmazione, anche se di solito è usato solo come un tipo tipografico.
gvgramazio,

Risposte:


15

Considera le macro interne di LaTeX piuttosto che quelle documentate

Ad esempio, \romanè una macro LaTeX documentata che funziona sui contatori LaTeX. Per trasformare 42in XLIVdovreste usare qualcosa di simile

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

Invece, osservando come \romanviene implementato (utilizzare \show\romanper ottenerlo in modo interattivo, invece di leggere i file di origine), si può vedere che è implementato in termini di una macro utile chiamata\@roman , e invece utilizzare direttamente questo:

\catcode`@11
\@roman{42}

\catcode`@11è il modo golfoso di scrivere \makeatletter(modo pulito in LaTeX) o \catcode`\@=11(modo pulito in semplice TeX). È necessario solo una volta all'inizio, dopodiché è possibile utilizzare i nomi macro contenenti @.


13

~può essere usato come una macro (così come altri caratteri attivi)

Esempio

Prima:

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

Dopo:

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

Spiegazione : Generalmente le macro in TeX sono "sequenze di controllo": è possibile definire \somethingo \a. Ma puoi andare ancora più breve, usando un personaggio attivo. L'unico carattere attivo presente di default (in chiaro TeX / LaTeX) è ~(usato per "legami", cioè definito come \penalty \@M \in semplice TeX (una penalità di 10000 seguita da uno spazio), e come \nobreakspace {}in LaTeX). Ma nulla ti impedisce di ridefinirlo per qualsiasi scopo tu abbia bisogno.

Inoltre : puoi fare lo stesso con qualsiasi altro personaggio impostando il suo codice cat su \active(13). Ad esempio, facendo Zun personaggio attivo ha un "costo" di 12 byte: \catcode`Z13. Quindi puoi usare semplicemente Zovunque invece di una macro come \z. Per alcuni personaggi che iniziano con un significato speciale, l'approccio diretto di backtick non funziona e hai bisogno di un altro personaggio: \catcode`\Z13o \catcode90=13.


9

\def può abbinare schemi fissi

Diciamo che hai avuto \def\a #1 #2 {...some definition here...}. Quindi quando lo chiami su una stringa come \a Act42, Scene26, all'interno della macro gli argomenti possono essere assegnati come # 1 <- Act42,, # 2 <- Scene26e quindi dovresti fare qualche ulteriore lavoro per estrarre le parti rilevanti. Invece, si potrebbe scrivere direttamente

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

e poi chiamandolo come \a Act42, Scene26impostare direttamente # 1 <- 42e # 2 <- 26.

(Questa è fondamentalmente la definizione di \def, ma è facile dimenticare che non si fa normalmente in LaTeX, preferendo passare argomenti {}come se fossero chiamate di funzione.)


8

Scegli tra TeX e LaTeX semplici

Si può dire molto su questo, ma in breve, confrontare un tipico documento TeX normale che stampa "Hello" con un tipico documento LaTeX per lo stesso:

Hello
\bye

contro

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

Il "costo" di LaTeX (wrt code golf) è ovvio; il "vantaggio" ovviamente è che LaTeX viene fornito con una libreria di molte macro e pacchetti pre-scritti, alcuni dei quali possono essere utili per l'attività da svolgere.


Ero bloccato nell'uso di LaTeX a causa di \@Roman(far funzionare le maiuscole in chiaro costerebbe molti byte) - ma TeX normale sarebbe spesso più breve.
Chris H,

8

\input ... è più corto di \usepackage{...}

Ad esempio, puoi scrivere

\input color

invece di

\usepackage{color}

che è 6 byte in meno.


8
È utile sottolineare, tuttavia, che \usepackagediventa più efficiente con l'aumentare del numero di pacchetti inclusi. Dal momento che è possibile utilizzare più di un pacchetto con una sola \usepackageistruzione, ma è necessario un \inputper ogni pacchetto, se si utilizzano 3 o più pacchetti, \usepackagediventa l'opzione migliore.
Wheat Wizard

7

Se si utilizza LaTeX, utilizzare un brevedocumentclass (idea di Chris H )

Invece di iniziare con il tipico

\documentclass{article}

si può scegliere classi di documenti più brevi come booko anche

\documentclass{ecv}

o

\documentclass{tui}

Dovresti ricordare di rimanere all'interno delle specifiche della domanda, articleper impostazione predefinita numeri le sue pagine, questo può essere considerato un output aggiuntivo. Forse una meta domanda è al fine di determinare quali classi di documenti dovrebbero essere consentite.
Wheat Wizard

@WheatWizard Ottimo punto. Penso che spetti alla singola domanda se i numeri di pagina siano considerati output extra.
ShreevatsaR,

Immagino che una lezione minima sarebbe una buona idea - un nome con una sola lettera e nessuna numerazione delle pagine
Chris H

Ho messo insieme un g.clsche è solo article.clscon, \pagenumbering{gobble}ma dato che github è inattivo non posso metterlo per ora
Chris H


7

La creazione di un ambiente chiamato myenvironmentgenera i comandi \myenvironmente \endmyenvironment. Questi vengono utilizzati internamente per iniziare e terminare l'ambiente. In alcuni casi possono essere usati come scorciatoie. Ad esempio, invece di

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

si può fare

\itemize
\item abc
\enditemize

Non supportato, non affidabile, non funziona in tutti i casi, utilizzare a proprio rischio e pericolo, ecc. Ecc.


Benvenuti nel sito!
DJMcMayhem

3
Spesso puoi fare \itemize{...}per ulteriori risparmi.
Wheat Wizard

4

\usepackage{packagea,packageb,packagec} funziona, purché non si passino opzioni ai pacchetti.


4

Esegui le linee insieme. Le interruzioni di riga sono raramente necessarie in LaTeX / TeX, rispetto a molte lingue di lunga durata.


3

Alcune macro che potresti aspettarti che necessitino di parentesi graffe attorno ai loro argomenti in realtà non lo fanno, specialmente se utilizzate all'interno di un'altra macro con #1argomenti in stile.

La maggior parte delle macro necessita di parentesi graffe solo se nell'argomento è presente più di un token (sequenza di caratteri o di controllo).

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

3

Se è necessario utilizzare più volte la stessa macro con un nome lungo, è possibile utilizzare \letper definire un alias più breve.

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

Ciò consente di risparmiare due byte \def\a{\mymacrowithalongname}, se non sono necessari più token nella definizione.

Invece di un nome di macro, puoi avere un carattere attivo da salvare sulle barre rovesciate.

Nota che \letnon funziona solo con i nomi delle macro ma anche con le primitive integrate. Ad esempio, se usi molti \ifnum ... \ficostrutti nel tuo codice, la definizione \let\i\ifnume invece l'utilizzo \i ... \fipotrebbe farti risparmiare qualche byte. Questo funziona anche per \letsé: \let\l\let.


3

Utilizzare locali {... }gruppi con saggezza

Come sottolineato in questa risposta , caratteri attivi come ~possono essere usati come nome macro. Sfortunatamente, ~è l'unico carattere attivo di default e cambiare il codice cat per un altro personaggio è costoso: \catcode`!13richiede 12 byte. Se la nuova definizione di macro è necessaria solo in una piccola area del codice, i gruppi locali possono essere una soluzione.

Quando TeX entra in un nuovo gruppo locale aperto da {, crea un nuovo livello di raggruppamento nello stack di salvataggio interno. Ciò significa che tutte le macro e i registri correnti vengono salvati. Qualsiasi modifica apportata (se non esplicitamente contrassegnata come \global) ora è attiva solo fino alla chiusura del gruppo }. Ciò significa che ~può essere ridefinito all'interno di un gruppo, utilizzato lì con la nuova definizione e la vecchia definizione verrà automaticamente ripristinata al termine del gruppo.

Ecco un esempio:

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

Questo produce

abc - 123 - abc

Un interessante effetto collaterale di questo meccanismo di raggruppamento è che i vecchi valori sono ancora disponibili all'interno del gruppo fino a quando non vengono modificati lì. Per illustrarlo, immagina di voler stampare un numero di caratteri in base al valore di un contatore, riempirli con spazi fino a una lunghezza fissa e continuare con il valore del contatore originale. Ciò potrebbe essere ottenuto mediante:

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

quali uscite

Stampa un carattere 3 volte, pad con 7 spazi e continua con x = 3.

Questo comportamento di raggruppamento è particolarmente importante se si desidera utilizzare le macro standard di TeX per il looping \loop ... \repeatnidificato. Queste macro definiscono i comandi interni e li usano per determinare come procedere. Annidarli senza mettere l'anello interno tra parentesi graffe confonderà i comandi interni e porterà a comportamenti imprevisti.


1

L'avanzamento dei contatori, come ad esempio

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

funziona anche come

\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

Lo stesso principio funziona anche per l'inizializzazione:

\newcount\u\u1

imposta il contatore \ u su 1.

Nota che questi hanno bisogno di un carattere di spazi bianchi (interruzione di riga o spazio) dopo di loro (o a \relax, ma gli spazi bianchi fanno lo stesso) in modo che il comando successivo non venga ignorato. Per esempio,

\u1\the\u

NON stampa \ u, ma ignora il \thecomando.


1

\enddocumentinvece di \end{document}salvare due personaggi


Non sembra funzionare per \begin{document}=> \documentcomunque
sheß
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.