Mẹo chơi gôn trong TeX / LaTeX


28

Mọi người có lời khuyên gì khi chơi golf trong TeX / LaTeX? Vui lòng gửi một mẹo cho mỗi câu trả lời, mỗi câu ít nhất là phần nào cụ thể cho TeX / LaTeX.


Bối cảnh: Tôi nhận thấy câu trả lời này và rằng không có câu hỏi mẹo nào cho TeX / LaTeX, vì vậy tôi đang tạo câu hỏi này. Có một số trùng lặp với các mẹo câu hỏi hẹp hơn để chơi gôn trong TikZ (vì TikZ là gói macro cụ thể trên đầu TeX / LaTeX): câu trả lời cho câu hỏi này có thể cũng sẽ được áp dụng ở đó, nhưng không phải là cách khác.


Làm thế nào bạn có thể chơi golf một ngôn ngữ không lập trình?
Vịt lớn

1
@TheGreatDuck Rất kém :-)
ShreevatsaR

@TheGreatDuck Trên thực tế, TeX một ngôn ngữ lập trình, ngay cả khi thông thường nó chỉ được sử dụng như một ngôn ngữ đánh máy.
gvgramazio

Câu trả lời:


15

Xem xét các macro LaTeX nội bộ thay vì các macro được ghi lại

Ví dụ, \romanlà một macro LaTeX được ghi lại, hoạt động trên các bộ đếm LaTeX. Để biến 42thành XLIVbạn phải sử dụng một cái gì đó như

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

Thay vào đó, bằng cách tìm kiếm cách \romantriển khai (sử dụng \show\romanđể có được điều này một cách tương tác, thay vì đọc các tệp nguồn), người ta có thể thấy rằng nó được triển khai theo thuật ngữ macro hữu ích được gọi \@romanvà thay vào đó sử dụng trực tiếp:

\catcode`@11
\@roman{42}

\catcode`@11là cách viết golf \makeatletter(cách sạch trong LaTeX) hoặc \catcode`\@=11(cách sạch trong TeX đơn giản). Lúc đầu chỉ cần một lần, sau này bạn có thể sử dụng tên macro chứa @.


13

~có thể được sử dụng như một macro (cũng như các ký tự hoạt động khác)

Thí dụ

Trước:

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

Sau:

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

Giải thích : Thông thường các macro trong TeX là các chuỗi điều khiển của Viking: bạn có thể định nghĩa \somethinghoặc \a. Nhưng bạn có thể đi thậm chí ngắn hơn, bằng cách sử dụng một nhân vật hoạt động. Ký tự hoạt động duy nhất có mặt theo mặc định (trong TeX / LaTeX đơn giản) là ~(được sử dụng cho các mối quan hệ, có nghĩa là \penalty \@M \trong TeX đơn giản (một hình phạt 10000 theo sau là khoảng trắng) và như \nobreakspace {}trong LaTeX). Nhưng không có gì ngăn bạn xác định lại nó cho bất kỳ mục đích nào bạn cần.

Hơn nữa : bạn có thể làm tương tự với bất kỳ nhân vật nào khác bằng cách đặt catcode của nó thành \active(13). Ví dụ: tạo Zmột ký tự hoạt động có "chi phí" là 12 byte : \catcode`Z13. Sau đó, bạn có thể sử dụng đơn giản Zở mọi nơi thay vì một macro như \z. Đối với một số ký tự bắt đầu có ý nghĩa đặc biệt, phương pháp backtick trực tiếp không hoạt động và bạn cần thêm một ký tự: \catcode`\Z13hoặc \catcode90=13.


9

\def có thể phù hợp với các mẫu cố định

Hãy nói rằng bạn đã có \def\a #1 #2 {...some definition here...}. Sau đó, khi bạn gọi nó trên một chuỗi như \a Act42, Scene26, bên trong macro, các đối số có thể được chỉ định như # 1 <- Act42,, # 2 <- Scene26và sau đó bạn sẽ phải thực hiện một số công việc tiếp theo để trích xuất các phần có liên quan. Thay vào đó, người ta có thể viết trực tiếp

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

và sau đó gọi nó là \a Act42, Scene26sẽ trực tiếp đặt # 1 <- 42và # 2 <- 26.

(Về cơ bản, đây là định nghĩa của \def, nhưng thật dễ để quên vì người ta thường không làm điều này trong LaTeX, thích truyền các đối số vào {}như thể chúng là các lệnh gọi hàm.)


8

Lựa chọn giữa TeX và LaTeX đơn giản

Rất nhiều điều có thể nói về điều này, nhưng tóm lại, hãy so sánh một tài liệu TeX đơn giản điển hình in "Xin chào" với một tài liệu LaTeX điển hình cho cùng một:

Hello
\bye

đấu với

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

"Chi phí" của LaTeX (wrt code golf) là rõ ràng; "lợi ích" tất nhiên là LaTeX đi kèm với một thư viện gồm nhiều macro và gói được viết sẵn, một số trong đó có thể hữu ích cho nhiệm vụ trong tay.


Tôi đã bị mắc kẹt khi sử dụng LaTeX vì \@Roman(để chữ hoa hoạt động đơn giản sẽ tốn rất nhiều byte) - nhưng TeX đơn giản thường sẽ ngắn hơn.
Chris H

8

\input ... ngắn hơn \usepackage{...}

Ví dụ, bạn có thể viết

\input color

thay vì

\usepackage{color}

đó là 6 byte ít hơn.


8
Tuy nhiên, rất hữu ích khi chỉ ra rằng điều đó \usepackagesẽ trở nên hiệu quả hơn khi số lượng gói bạn bao gồm tăng lên. Vì bạn có thể sử dụng nhiều gói chỉ với một \usepackagecâu lệnh, nhưng yêu cầu một \inputgói cho mỗi gói, Nếu bạn đang sử dụng 3 gói \usepackagetrở lên , sẽ trở thành tùy chọn tốt hơn.
Thuật sĩ lúa mì

7

Nếu sử dụng LaTeX, hãy sử dụng một đoạn ngắndocumentclass (ý tưởng của Chris H )

Thay vì bắt đầu với điển hình

\documentclass{article}

người ta có thể chọn các lớp tài liệu ngắn hơn như bookhoặc thậm chí

\documentclass{ecv}

hoặc là

\documentclass{tui}

Bạn nên nhớ ở trong thông số kỹ thuật của câu hỏi, articletheo mặc định số trang của nó, điều này có thể được coi là đầu ra thêm. Có lẽ một câu hỏi meta là để xác định những lớp tài liệu nào sẽ được cho phép.
Thuật sĩ lúa mì

@WheatWizard Điểm tốt. Tôi nghĩ có thể tùy thuộc vào câu hỏi cá nhân liệu số trang có được coi là đầu ra thêm hay không.
ShreevatsaR

Tôi nghĩ rằng một lớp học tối thiểu sẽ là một ý tưởng tốt - một tên chữ cái duy nhất và không đánh số trang
Chris H

Tôi đã kết hợp một g.clsthứ chỉ article.clsvới \pagenumbering{gobble}nhưng khi github ngừng hoạt động, tôi không thể đặt nó lên bây giờ
Chris H


7

Tạo một môi trường được gọi là myenvironmenttạo các lệnh \myenvironment\endmyenvironment. Chúng được sử dụng nội bộ để bắt đầu và kết thúc môi trường. Trong một số trường hợp, chúng có thể được sử dụng như các phím tắt. Ví dụ, thay vì

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

người ta có thể làm

\itemize
\item abc
\enditemize

Không được hỗ trợ, không đáng tin cậy, không hoạt động trong mọi trường hợp, sử dụng trong tình trạng nguy hiểm của riêng bạn, v.v.


Chào mừng đến với trang web!
DJMcMayhem

3
Bạn thường có thể làm \itemize{...}để tiết kiệm hơn nữa.
Thuật sĩ lúa mì

4

\usepackage{packagea,packageb,packagec} hoạt động, miễn là bạn không chuyển các tùy chọn cho các gói.


4

Chạy các dòng với nhau. Ngắt dòng hiếm khi cần trong LaTeX / TeX, so với nhiều ngôn ngữ dài.


3

Một số macro mà bạn có thể cần phải niềng răng làm tròn các đối số của chúng thực sự không, đặc biệt là khi được sử dụng bên trong một macro khác với các #1đối số kiểu.

Hầu hết các macro chỉ cần dấu ngoặc nếu có nhiều hơn một mã thông báo (ký tự hoặc chuỗi điều khiển) trong đối số.

\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

Nếu bạn cần sử dụng cùng một macro với một tên dài nhiều lần, bạn có thể sử dụng \letđể xác định bí danh ngắn hơn.

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

Điều này tiết kiệm hai byte trên \def\a{\mymacrowithalongname} , nếu bạn không cần nhiều mã thông báo trong định nghĩa.

Thay vì tên macro, bạn có thể có một ký tự hoạt động để lưu lại dấu gạch chéo ngược.

Lưu ý rằng \letkhông chỉ hoạt động với tên macro mà còn với các nguyên hàm tích hợp. Ví dụ: nếu bạn sử dụng nhiều \ifnum ... \ficấu trúc trong mã của mình, việc xác định \let\i\ifnumvà thay vào đó sử dụng \i ... \ficó thể giúp bạn tiết kiệm một vài byte. Điều này thậm chí hoạt động cho \letchính nó : \let\l\let.


3

Sử dụng địa phương {... }các nhóm một cách khôn ngoan

Như đã chỉ ra trong câu trả lời này , các ký tự hoạt động như ~có thể được sử dụng làm tên macro. Thật không may, ~là ký tự hoạt động duy nhất theo mặc định và việc thay đổi catcode cho một ký tự khác rất tốn kém: \catcode`!13mất 12 byte. Nếu định nghĩa macro mới chỉ cần trong một vùng nhỏ trong mã của bạn, các nhóm cục bộ có thể là một giải pháp.

Khi TeX vào một nhóm cục bộ mới được mở bởi {, nó sẽ tạo một cấp độ nhóm mới trên ngăn xếp lưu nội bộ. Điều này có nghĩa là tất cả các macro và thanh ghi hiện tại được lưu. Bất kỳ sửa đổi nào đối với chúng (trừ khi được đánh dấu rõ ràng là \global) hiện chỉ hoạt động cho đến khi nhóm được đóng lại }. Điều này có nghĩa rằng~ có thể được xác định lại trong một nhóm, được sử dụng ở đó với định nghĩa mới và định nghĩa cũ sẽ tự động được khôi phục sau khi nhóm kết thúc.

Đây là một ví dụ:

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

Đầu ra này

abc - 123 - abc

Một tác dụng phụ thú vị của cơ chế nhóm này là các giá trị cũ vẫn có sẵn trong nhóm cho đến khi chúng được thay đổi ở đó. Để minh họa điều đó, hãy tưởng tượng chúng ta muốn in một số ký tự dựa trên giá trị của bộ đếm, đệm chúng với khoảng trắng có độ dài cố định và tiếp tục với giá trị bộ đếm ban đầu. Điều này có thể đạt được bằng cách sau:

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

đầu ra nào

In một char 3 lần, pad với 7 dấu cách và tiếp tục với x = 3.

Hành vi nhóm này đặc biệt quan trọng nếu bạn muốn sử dụng các macro tiêu chuẩn của TeX để lặp \loop ... \repeatlồng nhau. Các macro này xác định các lệnh nội bộ và sử dụng chúng để xác định cách tiến hành. Lồng chúng mà không đặt vòng lặp bên trong vào dấu ngoặc nhọn sẽ gây nhầm lẫn các lệnh nội bộ và dẫn đến hành vi không mong muốn.


1

Sự tiến bộ của quầy, chẳng hạn như

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

cũng làm việc như

\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

Nguyên tắc tương tự cũng hoạt động để khởi tạo:

\newcount\u\u1

đặt bộ đếm \ u thành 1.

Xin lưu ý rằng những thứ này cần một ký tự khoảng trắng (ngắt dòng hoặc dấu cách) sau chúng (hoặc a \relax, nhưng khoảng trắng làm như vậy) để lệnh tiếp theo sẽ không bị bỏ qua. Ví dụ,

\u1\the\u

KHÔNG in \ u, nhưng bỏ qua \the lệnh.


1

\enddocumentthay vì \end{document}lưu hai ký tự


Dường như không hoạt động cho \begin{document}=> \documentmặc dù
sheß
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.