Wskazówki dotyczące gry w golfa w TeX / LaTeX

28

Jakie wskazówki mają ludzie w golfa w TeX / LaTeX? Proszę zamieścić jedną wskazówkę na odpowiedź, każda przynajmniej nieco specyficzna dla TeX / LaTeX.


Kontekst: Zauważyłem tę odpowiedź i nie ma pytania dotyczącego wskazówek dla TeX / LaTeX, więc tworzę tę. Węższe wskazówki dotyczące gry w golfa w TikZ pokrywają się (ponieważ TikZ jest specjalnym pakietem makr na TeX / LaTeX): odpowiedzi na to pytanie prawdopodobnie również będą tam obowiązywać, ale nie na odwrót.

ShreevatsaR
źródło
Jak grać w golfa w języku nieprogramowym?
The Great Duck
1
@TheGreatDuck Bardzo słabo :-)
ShreevatsaR
@TheGreatDuck W rzeczywistości TeX jest językiem programowania, nawet jeśli zwykle jest używany tylko jako typograficzny.
gvgramazio

Odpowiedzi:

15

Rozważ wewnętrzne makra LaTeX zamiast tych udokumentowanych

Na przykład \romanjest udokumentowanym makrem LaTeX, które działa na licznikach LaTeX. Aby włączyć 42się do XLIVciebie, że trzeba użyć czegoś podobnego

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

Zamiast tego, patrząc na \romanto, jak jest zaimplementowany (użyj go, \show\romanaby uzyskać to interaktywnie, zamiast czytać pliki źródłowe), możesz zobaczyć, że jest on zaimplementowany pod względem użytecznego makra o nazwie \@roman, i zamiast tego użyj go bezpośrednio:

\catcode`@11
\@roman{42}

\catcode`@11jest golfowym sposobem pisania \makeatletter(czysty sposób w LaTeX) lub \catcode`\@=11(czysty sposób w zwykłym TeX). Jest potrzebny tylko raz na początku, po czym możesz użyć nazw makr zawierających @.

ShreevatsaR
źródło
13

~może być użyty jako makro (podobnie jak inne aktywne postacie)

Przykład

Przed:

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

Po:

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

Objaśnienie : Zasadniczo makra w TeX to „sekwencje kontrolne”: możesz zdefiniować \somethinglub \a. Ale możesz iść jeszcze krócej, używając aktywnej postaci. Jedynym aktywnym znakiem, który jest domyślnie obecny (w zwykłym TeX / LaTeX) jest ~(używany do „remisów”, tj. Zdefiniowany jak \penalty \@M \w zwykłym TeX (kara 10000, po której następuje spacja), i jak \nobreakspace {}w LaTeX). Ale nic nie stoi na przeszkodzie, aby zdefiniować go na nowo w jakimkolwiek celu.

Ponadto : możesz zrobić to samo z dowolnym innym znakiem, ustawiając jego kod kota na \active(13). Na przykład, co Zaktywną postać ma „koszt” 12 bajtów: \catcode`Z13. Następnie możesz użyć po prostu Zwszędzie zamiast makra takiego jak \z. W przypadku niektórych postaci, które zaczynają się od specjalnego znaczenia, bezpośrednie podejście wstecz nie działa i potrzebujesz jeszcze jednej postaci: \catcode`\Z13lub \catcode90=13.

ShreevatsaR
źródło
9

\def może pasować do ustalonych wzorów

Powiedzmy, że miałeś \def\a #1 #2 {...some definition here...}. Następnie, gdy wywołasz go na ciąg znaków, np. \a Act42, Scene26Wewnątrz makra, argumenty mogą być przypisane jak # 1 <- Act42,, # 2 <-Scene26 i wtedy będziesz musiał wykonać dalsze prace, aby wyodrębnić odpowiednie części. Zamiast tego można bezpośrednio pisać

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

a następnie wywołanie go tak, jak \a Act42, Scene26by bezpośrednio ustawić # 1 <-42 i # 2 <- 26.

(Jest to w zasadzie definicja \def, ale łatwo ją zapomnieć, ponieważ zwykle nie robi się tego w LaTeX, woląc przekazywać argumenty {}tak, jakby były wywołaniami funkcji).

ShreevatsaR
źródło
8

Wybieranie między zwykłym TeX a LaTeX

Wiele można o tym powiedzieć, ale w skrócie porównaj typowy zwykły dokument TeX, który drukuje „Cześć” z typowym dokumentem LaTeX dla tego samego:

Hello
\bye

przeciw

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

„Koszt” LaTeX (golf wrt code) jest oczywisty; „zaletą” jest oczywiście to, że LaTeX zawiera bibliotekę wielu wstępnie napisanych makr i pakietów, z których niektóre mogą być przydatne do danego zadania.

ShreevatsaR
źródło
Utknąłem w używaniu LaTeXa z powodu \@Roman(uruchomienie wielkich liter w trybie zwykłym kosztowałoby dużo bajtów) - ale zwykły TeX byłby często krótszy.
Chris H
8

\input ... jest krótszy niż \usepackage{...}

Na przykład możesz pisać

\input color

zamiast

\usepackage{color}

czyli o 6 mniej bajtów.

Fatalizować
źródło
8
Warto jednak \usepackagezauważyć, że staje się to bardziej wydajne, gdy liczba dołączanych pakietów rośnie. Ponieważ możesz użyć więcej niż jednego pakietu z tylko jedną \usepackageinstrukcją, ale wymagać \inputdla każdego pakietu, jeśli używasz 3 lub więcej pakietów, \usepackagestaje się lepszą opcją.
Wheat Wizard
7

Jeśli używasz LaTeX, użyj krótkiegodocumentclass (pomysł Chris H )

Zamiast zaczynać od typowego

\documentclass{article}

można wybrać krótsze klasy dokumentów, takie jak booklub nawet

\documentclass{ecv}

lub

\documentclass{tui}
ShreevatsaR
źródło
Należy pamiętać, aby pozostać w ramach specyfikacji pytania, articledomyślnie numeruje strony, można to uznać za dodatkowe wyniki. Być może meta pytanie ma na celu określenie, które klasy dokumentów powinny być dozwolone.
Wheat Wizard
@WheatWizard Dobry punkt. Myślę, że może zależeć od indywidualnego pytania, czy numery stron są uważane za dodatkowe wyniki.
ShreevatsaR
Myślę, że minimalna klasa byłaby dobrym pomysłem - nazwa
Chris H
Złożyłem taki, g.clsktóry jest właśnie article.clsz, \pagenumbering{gobble}ale ponieważ github jest w dół, nie mogę tego teraz nałożyć
Chris H
g.cls
Chris H.
7

Utworzenie środowiska o nazwie myenvironmentgeneruje polecenia \myenvironmenti \endmyenvironment. Są one używane wewnętrznie do rozpoczynania i kończenia środowiska. W niektórych przypadkach mogą być używane jako skróty. Na przykład zamiast

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

można zrobić

\itemize
\item abc
\enditemize

Nieobsługiwany, niewiarygodny, nie działa we wszystkich przypadkach, należy używać na własne ryzyko itp. Itp.

Ian Thompson
źródło
Witamy na stronie!
DJMcMayhem
3
Często możesz zrobić, \itemize{...}aby uzyskać jeszcze więcej oszczędności.
Wheat Wizard
4

\usepackage{packagea,packageb,packagec} działa, o ile nie przekazujesz opcji do pakietów.

Chris H.
źródło
4

Poprowadź linie razem. Podziały wiersza są rzadko potrzebne w LaTeX / TeX, w porównaniu do wielu długich języków.

Chris H.
źródło
3

Niektóre makra, które mogą wymagać nawiasów klamrowych wokół ich argumentów, faktycznie tego nie robią, zwłaszcza gdy są używane w innym makrze z #1 argumentami -style.

Większość makr potrzebuje tylko nawiasów, jeśli w argumencie jest więcej niż jeden token (sekwencja znaków lub kontroli).

\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.
źródło
3

Jeśli potrzebujesz kilka razy używać tego samego makra o długiej nazwie, możesz użyć \letdo zdefiniowania krótszego aliasu.

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

To oszczędza dwa bajty \def\a{\mymacrowithalongname} , jeśli nie potrzebujesz wielu tokenów w definicji.

Zamiast nazwy makra możesz mieć aktywną postać do zapisania na odwrotnych ukośnikach.

Zauważ, że \letnie działa tylko z nazwami makr, ale także z wbudowanymi operacjami podstawowymi. Na przykład, jeśli używasz wielu \ifnum ... \fikonstrukcji w swoim kodzie, zdefiniowanie \let\i\ifnumi użycie \i ... \fimoże zaoszczędzić kilka bajtów. Działa to nawet dla \letsiebie: \let\l\let.

Gilles „SO- przestań być zły”
źródło
3

Mądrze używaj lokalnych {... }grup

Jak wskazano w tej odpowiedzi , aktywne znaki, takie jak, ~mogą być użyte jako nazwa makra. Niestety,~ jest to domyślnie jedyny aktywny znak, a zmiana kodu cat dla innego znaku jest kosztowna:\catcode`!13 zajmuje 12 bajtów. Jeśli nowa definicja makra jest potrzebna tylko w małym regionie kodu, lokalne grupy mogą być rozwiązaniem.

Kiedy TeX wchodzi do nowej grupy lokalnej otwartej przez {, tworzy nowy poziom grupowania na wewnętrznym stosie zapisu. Oznacza to, że wszystkie bieżące makra i rejestry są zapisywane. Wszelkie ich modyfikacje (chyba że wyraźnie oznaczone jako \global) są teraz aktywne tylko do momentu zamknięcia grupy przez }. To znaczy że~ można go przedefiniować w grupie, użyć tam z nową definicją, a stara definicja zostanie automatycznie przywrócona po zakończeniu grupy.

Oto przykład:

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

To wychodzi

abc - 123 - abc

Ciekawym efektem ubocznym tego mechanizmu grupowania jest to, że stare wartości są nadal dostępne w grupie, dopóki się tam nie zmienią. Aby to zilustrować, wyobraźmy sobie, że chcemy wydrukować pewną liczbę znaków na podstawie wartości licznika, uzupełnić je spacjami do ustalonej długości i kontynuować z oryginalną wartością licznika. Można to osiągnąć poprzez:

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

które wyjścia

Wydrukuj znak 3 razy, wstaw 7 spacji i kontynuuj z x = 3.

To zachowanie grupowania jest szczególnie ważne, jeśli chcesz używać standardowych makr TeXa do \loop ... \repeatzagnieżdżania w pętli . Te makra definiują wewnętrzne polecenia i używają ich do określania sposobu postępowania. Zagnieżdżenie ich bez wstawiania pętli wewnętrznej w nawiasy klamrowe spowoduje zamieszanie wewnętrznych poleceń i doprowadzi do nieoczekiwanego zachowania.

Siracusa
źródło
1

Postęp liczników, takich jak

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

działa również jako

\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

Ta sama zasada działa również przy inicjalizacji:

\newcount\u\u1

ustawia licznik \ u na 1.

Zauważ, że wymagają one po nich spacji (podział wiersza lub spacja) (lub a \relax, ale spacja robi to samo), więc następne polecenie nie zostanie zignorowane. Na przykład,

\u1\the\u

NIE drukuje \ u, ale ignoruje \thepolecenie.

Simon Klaver
źródło
1

\enddocumentzamiast \end{document}zapisuje dwa znaki

sheß
źródło
Nie wydaje się do pracy \begin{document}=> \documentchociaż
sheß