(La) TeX - Ký tự '%' làm gì?

Oct 13 2020

các %nhân vật dường như có rất nhiều công dụng. Cho đến nay, tôi đã gặp nó ở những nơi sau:

  1. Để viết bình luận
% Schrodinger wave equation
$$\nabla^2\psi + \frac{8\pi^2m}{h^2}(E-V) = 0$$
  1. (Tôi có thể sai ở đây) Đối với các lệnh tách thành nhiều dòng (tham khảo tại đây )
\newcounter{bull}
\newcommand{\showbullcntr}[1]{%
\setcounter{bull}{#1}%
\bullcntr{bull}%
}
  1. Cùng với minipage, để loại bỏ khoảng trống ở đầu được chèn (phỏng theo câu hỏi này )
\noindent
\begin{minipage}{0.5\linewidth}
   ...
\end{minipage}%
\begin{minipage}{0.5\linewidth}
   ...
\end{minipage}

Ai đó có thể vui lòng giải thích chi tiết các cách sử dụng khác nhau của %ký tự trong LaTeX không? Đặc biệt, tại sao nó được sử dụng sau phiên sơ thẩm của \end{minipage}?

Trả lời

92 Mico Oct 13 2020 at 07:14

Ba trường hợp sử dụng cho %ký tự bạn đã liệt kê có thể được hợp nhất trong một trường hợp sử dụng duy nhất, bao quát: Để loại trừ mọi thứ nằm ở phần còn lại của dòng nhập hiện tại khỏi quá trình xử lý tiếp theo .

Đây tất cả mọi thứ bao gồm không chỉ bình luận (trường hợp sử dụng đầu tiên mà bạn đề cập) mà còn là nhân vật end-of-ranh giới vô hình vào cuối dòng đầu vào. Trên thực tế, sau khi gặp một %ký tự, TeX cũng sẽ bỏ qua bất kỳ khoảng trắng nào có thể có ở đầu dòng tiếp theo. Trên thực tế, khoảng trắng ở đầu dòng nhập luôn bị bỏ qua, cho dù dòng trước đó có được kết thúc bằng hay không %. Chà, chế độ nguyên văn là một ngoại lệ, nhưng đó là một chủ đề cho một cuộc thảo luận khác.

Vì vậy,

Hello %
World

và

Hello % 
    World

cuối cùng được xử lý theo cùng một cách: TeX đọc Hello từ dòng đầu tiên (với khoảng trắng sau "Hello" được bao gồm) và Worldtừ dòng thứ hai và sẽ xuất ra "Hello World". Quan sát rằng ký tự cuối dòng ở cuối dòng đầu tiên và bốn ký tự khoảng trắng ở đầu dòng thứ hai đã bị loại bỏ.

Điều gì sẽ xảy ra nếu đầu vào là

Hello% 
    World

Đầu ra bây giờ sẽ là "HelloWorld". Tại sao? Vâng, như trước đây, ký tự cuối dòng ở cuối dòng đầu tiên và bốn ký tự khoảng trắng ở đầu dòng thứ hai sẽ bị loại bỏ và những gì còn lại là "Xin chào" từ dòng đầu tiên và "Thế giới" từ thứ hai.


Thêm một mẩu thông tin: Một đơn nhân vật end-of-line được chuyển đổi trong giai đoạn xử lý đầu tiên TeX để khoảng trắng. (Ngược lại, hai hoặc nhiều ký tự cuối dòng liên tiếp được chuyển đổi thành \parmã thông báo.)

Hello 
World

và

Hello World

tạo ra cùng một đầu ra.


Được trang bị với những thông tin này, chúng tôi có thể tìm ra mục đích của %nhân vật trong đoạn mã sau là gì:

\noindent
\begin{minipage}{0.5\textwidth}
...
\end{minipage}%
\begin{minipage}{0.5\textwidth}
...
\end{minipage}

Tổng chiều rộng của cấu trúc này là 0.5\textwidth+0.5\textwidth=1\textwidth. Nếu %ký tự bị bỏ qua, ký tự cuối dòng sau phiên bản đầu tiên của \end{minipage}sẽ được chuyển thành khoảng trắng và tổng chiều rộng sẽ 1\textwidth cộng với chiều rộng của ký tự khoảng trắng . Đó gần như chắc chắn không phải là điều mong muốn. Cũng quan sát rằng điều quan trọng là phải đặt %ký tự ngay sau đó \end{minipage}; viết \end{minipage} %sẽ không phục vụ mục đích dự định.


Tiếp theo, hãy xem xét hai định nghĩa macro sau:

\newcommand\cmdA[1]{
        #1}
\newcommand\cmdB[1]{%
        #1}

Cả hai định nghĩa đều hợp pháp. Đặc biệt, theo quan điểm cú pháp thuần túy, không nhất thiết phải cung cấp một %ký tự sau \newcommand\cmdA[1]{để có được macro để biên dịch. Nhưng điều này không có nghĩa là hai macro tạo ra cùng một đầu ra. Bạn có thể đoán những gì \cmdA{abc}\cmdA{abc}và \cmdB{abc}\cmdB{abc}sẽ xuất ra? Để đơn giản, hãy giả sử rằng cả hai chuỗi lệnh đều xảy ra ở đầu dòng nhập.

Chắc chắn, \cmdB{abc}\cmdB{abc}xuất ra "abcabc", không có khoảng trắng giữa các chuỗi con "abc".

Ngược lại, \cmdA{abc}\cmdA{abc}đầu ra "abc abc". Tại sao? Hai phiên bản của \cmdA{abc}mỗi đầu ra abc; khoảng trắng trước abcở đó vì ký tự cuối dòng đơn sau \newcommand\cmdA[1]{được chuyển thành khoảng trắng. Khoảng trắng do phiên bản đầu tiên đóng góp \cmdA{abc}bị TeX bỏ qua vì nó xuất hiện, theo giả định, ở đầu dòng; tuy nhiên, khoảng trắng được đóng góp bởi phiên bản thứ hai của \cmdA{abc}thì không. Đó là cách bạn kết thúc abc abc.


Phụ lục , được gợi ý bởi một nhận xét của @PhelypeOleinik: Một số độc giả có thể có ấn tượng khi tiếp thu cuộc thảo luận trước đó rằng trong khi việc không kết thúc một số dòng nằm trong định nghĩa macro, có %thể là một sai lầm, chắc chắn sẽ chấm dứt mọi dòng trong macro đó định nghĩa với %không thể làm tổn thương. Thật không may, đó cũng sẽ là một sai lầm.

Hãy xem xét ví dụ sau đây, được thừa nhận là có phần giả tạo. Nó có 5 trường hợp %, chỉ một trong số đó quan trọng:

\ifnum1=0%
   1%
   a%
\else%
   b%
\fi

Dưới đây, \ifnum<u>=<v>là một điều kiện rằng séc liệu <u>và <v>là số lượng bằng nhau. (Nếu một trong hai <u>hoặc <v>không phải là số, một thông báo lỗi sẽ được đưa ra. Và, chỉ để sửa các ý tưởng: 1và 01là số bằng nhau.)

Bạn sẽ đoán gì (La) TeX chí đầu ra: 1, 1a, a, hay b? Nếu bạn đoán b- sau tất cả, 1 chắc chắn không bằng 0! - bạn sẽ đoán sai. Câu trả lời chính xác là a. Tại sao?

Sự hiện diện của %nhân vật ngay sau khi \ifnum1=0ngấu nghiến ký tự vô hình cuối dòng; do đó, TeX tiếp tục quét trước cho đến khi nó gặp ký tự không phải số đầu tiên để thiết lập kiểm tra điều kiện. Do đó, điều kiện thực sự được đánh giá bởi TeX là \ifnum1=01- hãy nhớ: khoảng trắng ở đầu dòng bị bỏ qua - điều này đúng . Đó là lý do tại sao ađược sắp chữ.

Tuy nhiên, nếu một trong hai đã viết

\ifnum1=0
   1%
   a%
\else%
   b%
\fi

hoặc, vẫn tốt hơn,

\ifnum1=0
   1
   a
\else
   b
\fi

câu trả lời đúng sẽ là b, vì TeX sẽ "nhìn thấy" ký tự cuối dòng sau đó \ifnum1=0, chuyển nó thành ký tự khoảng trắng, nhận ra rằng nó sẽ bắt đầu đánh giá xem \ifnum1=0có đúng không và chọn nhánh thích hợp của cấu trúc "cây" có điều kiện .