TeX / LaTeXでゴルフをするためのヒントは何ですか?回答ごとに1つのヒントを投稿してください。各ヒントは、少なくともTeX / LaTeXにある程度固有のものです。
コンテキスト:この答えに気づき、TeX / LaTeXにヒントの質問はないので、これを作成しています。TikZでゴルフをするための狭い質問のヒントと重複しています(TikZはTeX / LaTeX上の特定のマクロパッケージであるため):この質問への回答はおそらくそこにも当てはまりますが、逆には当てはまりません。
TeX / LaTeXでゴルフをするためのヒントは何ですか?回答ごとに1つのヒントを投稿してください。各ヒントは、少なくともTeX / LaTeXにある程度固有のものです。
コンテキスト:この答えに気づき、TeX / LaTeXにヒントの質問はないので、これを作成しています。TikZでゴルフをするための狭い質問のヒントと重複しています(TikZはTeX / LaTeX上の特定のマクロパッケージであるため):この質問への回答はおそらくそこにも当てはまりますが、逆には当てはまりません。
回答:
文書化されたマクロではなく、内部のLaTeXマクロを検討する
たとえば、\roman
LaTeXカウンターで動作する文書化されたLaTeXマクロです。あなたに変わる42
にXLIV
は、次のようなものを使用する必要があります
\newcounter{z}
\setcounter{z}{42}
\roman{z}
代わりに、\roman
実装方法を調べることで(\show\roman
ソースファイルを読み取る代わりにこれをインタラクティブに取得するために使用します)、と呼ばれる便利なマクロの観点から実装されていることがわかり\@roman
、代わりに直接使用します:
\catcode`@11
\@roman{42}
\catcode`@11
ゴルフのように書く\makeatletter
方法(LaTeXのクリーンな方法)または\catcode`\@=11
(プレーンなTeXのクリーンな方法)です。最初に必要なのは一度だけです。その後、を含むマクロ名を使用できます@
。
~
マクロとして使用できます(他のアクティブなキャラクターと同様)
例
前:
\def\a{...some definition...} ... use \a...
後:
\def~{...some definition...} ... use ~...
説明:通常、TeXのマクロは「制御シーケンス」です。定義\something
またはできます\a
。しかし、アクティブなキャラクターを使用することで、さらに短くすることができます。(プレーンTeX / LaTeXで)デフォルトで存在する唯一のアクティブな文字は~
(「タイ」に使用されます。つまり\penalty \@M \
、プレーンTeX(10000の後にスペースが続くペナルティ)、および\nobreakspace {}
LaTeXで定義されます)。しかし、必要な目的に合わせて再定義することを妨げるものは何もありません。
さらに:catcodeを\active
(13)に設定することで、他のキャラクターでも同じことができます。たとえばZ
、アクティブキャラクターを作成すると、「コスト」は12バイトになります\catcode`Z13
。そうするとZ
、のようなマクロの代わりにどこでも簡単に使用できます\z
。特別な意味で始まる一部のキャラクターでは、直接のバックティックアプローチは機能せず、もう1つのキャラクターが必要です:\catcode`\Z13
または\catcode90=13
。
\def
固定パターンに一致できます
あなたが持ってい\def\a #1 #2 {...some definition here...}
たとしましょう。次に、などの文字列で呼び出すと\a Act42, Scene26
、マクロ内で引数が#1 <- Act42,
、#2 <-のように割り当てられScene26
、関連する部分を抽出するためにさらに作業を行う必要があります。代わりに、直接書くことができます
\def\a Act#1, Scene#2 {...some definition here...}
\a Act42, Scene26
#1 <- 42
および#2 <- を直接設定するように呼び出し26
ます。
(これは基本的にの定義です\def
が、LaTeXでは通常これを行わないため、{}
関数呼び出しであるかのように引数を渡すことを好むため、忘れがちです。)
プレーンTeXとLaTeXの選択
これについては多くのことを言うことができますが、要するに、「Hello」を印刷する典型的なプレーンTeX文書を、同じもののための典型的なLaTeX文書と比較してください。
Hello
\bye
対
\documentclass{article}
\begin{document}
Hello
\end{document}
LaTeX(wrt code golf)の「コスト」は明らかです。もちろん、「利点」は、LaTeXには多くの事前に記述されたマクロとパッケージのライブラリが付属していることです。これらのいくつかは、当面のタスクに役立つ可能性があります。
\@Roman
(大文字をプレーンで動作させるには多くのバイトがかかる)-プレーンなTeXの方が短いことが多いためです。
LaTeXを使用している場合は、短いものを使用してくださいdocumentclass
(Chris Hのアイデア)
典型的なものから始めるのではなく
\documentclass{article}
book
またはのような短いドキュメントクラスを選択することもできます
\documentclass{ecv}
または
\documentclass{tui}
article
デフォルトではページに番号が付けられますが、これは追加の出力とみなすことができます。メタ質問は、おそらくどのドキュメントクラスを許可するかを決定するためのものです。
g.cls
だけであるarticle.cls
と\pagenumbering{gobble}
githubのがダウンしているとしてではなく、私は今のためにそれを我慢できない
という環境を作成するとmyenvironment
、コマンド\myenvironment
とが生成されます\endmyenvironment
。これらは、環境を開始および終了するために内部的に使用されます。場合によっては、ショートカットとして使用できます。たとえば、代わりに
\begin{itemize}
\item abc
\end{itemize}
できること
\itemize
\item abc
\enditemize
サポートされていない、信頼できない、すべての場合に機能しない、自分の責任で使用するなど
\itemize{...}
、さらに節約することができます。
特に#1
-style引数を指定して別のマクロ内で使用する場合、引数を丸括弧で囲む必要があると予想される一部のマクロは実際には必要ありません。
ほとんどのマクロは、引数に複数のトークン(文字または制御シーケンス)がある場合にのみ中括弧が必要です。
\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}
同じマクロを長い名前で数回使用\let
する必要がある場合は、短いエイリアスを定義するために使用できます。
\let\a\mymacrowithalongname
\a{foo}\a{bar}\a{qux}
\def\a{\mymacrowithalongname}
定義で複数のトークンを必要としない場合、これによりで2バイトが節約されます。
マクロ名の代わりに、バックスラッシュを保存するアクティブな文字を使用できます。
\let
マクロ名だけでなく、組み込みのプリミティブでも機能することに注意してください。たとえば\ifnum ... \fi
、コードで多くの構造を使用する場合、定義\let\i\ifnum
して代わりに使用すると\i ... \fi
、数バイト節約できます。これ\let
自体でも機能します:\let\l\let
。
ローカル{
... }
グループを賢く使用する
この回答で指摘したように、などのアクティブな文字~
はマクロ名として使用できます。残念ながら、~
デフォルトで唯一のアクティブな文字であり、別の文字のcatcodeを変更するのは高価です。12 \catcode`!13
バイトかかります。新しいマクロ定義がコードの小さな領域でのみ必要な場合は、ローカルグループが解決策になります。
TeXは、によって開かれた新しいローカルグループに入る{
と、内部保存スタックに新しいグループ化レベルを作成します。これは、現在のすべてのマクロとレジスタが保存されることを意味します。(明示的にとしてマークされていない限り\global
)それらへの変更は、グループがによって閉じられるまでアクティブになり}
ます。これは~
、グループ内で再定義し、そこで新しい定義で使用できることを意味します。グループが終了すると、古い定義が自動的に復元されます。
以下に例を示します。
\def~{abc}
~ -- {\def~{123}~} -- ~
この出力
abc-123-abc
このグループ化メカニズムの興味深い副作用は、変更されるまでグループ内で古い値が引き続き使用できることです。それを説明するために、カウンターの値に基づいていくつかの文字を印刷し、それらを固定長までスペースで埋めて、元のカウンター値に進みたいと想像してください。これは次の方法で実現できます。
\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.
どの出力
文字を3回印刷し、7つのスペースで埋め込み、x = 3で続行します。
\loop ... \repeat
ネストされたループにTeXの標準マクロを使用する場合、このグループ化の動作は特に重要です。これらのマクロは内部コマンドを定義し、それらを使用して処理方法を決定します。内部ループを中括弧に入れずにネストすると、内部コマンドが混乱し、予期しない動作が発生します。
などのカウンターの進歩
\advance\u by 1
\multiply\u by 3
\divide\u by 2
としても働く
\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
同じ原則が初期化にも機能します。
\newcount\u\u1
カウンター\ uを1に設定します。
これらの後には空白文字(改行またはスペース)が必要であることに注意してください(または\relax
、しかし、空白は同じです)。次のコマンドは無視されません。例えば、
\u1\the\u
\ uを出力しませんが、\the
コマンドを無視します。