TeX, 216 byte (mỗi dòng 4 ký tự)
Bởi vì nó không phải là về số byte, mà là về chất lượng của đầu ra sắp chữ :-)
{\let~\catcode~`A13 \defA#1{~`#113\gdef}AGG#1{~`#1 13%
\global\let}GFF\elseGHH\fiAQQ{Q}AII{\ifxQ}AEE#1#2#3|{%
I#3#2#1FE{#1#2}#3|H}ADD#1#2|{I#1FE{}#1#2|H}ACC#1#2|{D%
#2Q|#1 }ABBH#1 {HI#1FC#1|BH}\gdef\S#1{\iftrueBH#1 Q }}
Hãy thử trực tuyến! (Overleaf; không chắc nó hoạt động như thế nào)
Tập tin kiểm tra đầy đủ:
{\let~\catcode~`A13 \defA#1{~`#113\gdef}AGG#1{~`#1 13%
\global\let}GFF\elseGHH\fiAQQ{Q}AII{\ifxQ}AEE#1#2#3|{%
I#3#2#1FE{#1#2}#3|H}ADD#1#2|{I#1FE{}#1#2|H}ACC#1#2|{D%
#2Q|#1 }ABBH#1 {HI#1FC#1|BH}\gdef\S#1{\iftrueBH#1 Q }}
\S{swap the a first and last letters of each word}
pwas eht a tirsf dna tasl setterl fo hace dorw
\S{SWAP THE A FIRST AND LAST LETTERS OF EACH WORD}
\bye
Đầu ra:
Đối với LaTeX, bạn chỉ cần bản tóm tắt:
\documentclass{article}
\begin{document}
{\let~\catcode~`A13 \defA#1{~`#113\gdef}AGG#1{~`#1 13%
\global\let}GFF\elseGHH\fiAQQ{Q}AII{\ifxQ}AEE#1#2#3|{%
I#3#2#1FE{#1#2}#3|H}ADD#1#2|{I#1FE{}#1#2|H}ACC#1#2|{D%
#2Q|#1 }ABBH#1 {HI#1FC#1|BH}\gdef\S#1{\iftrueBH#1 Q }}
\S{swap the a first and last letters of each word}
pwas eht a tirsf dna tasl setterl fo hace dorw
\S{SWAP THE A FIRST AND LAST LETTERS OF EACH WORD}
\end{document}
Giải trình
TeX là một con thú kỳ lạ. Đọc mã bình thường và hiểu nó là một kỳ công của chính nó. Hiểu mã TeX bị xáo trộn đi thêm một vài bước. Tôi sẽ cố gắng làm cho điều này trở nên dễ hiểu đối với những người không biết TeX, vì vậy trước khi chúng tôi bắt đầu đây là một vài khái niệm về TeX để làm cho mọi thứ dễ theo dõi hơn:
Dành cho người mới bắt đầu TeX tuyệt đối
Đầu tiên và là mục quan trọng nhất trong danh sách này: mã không phải ở dạng hình chữ nhật, mặc dù văn hóa nhạc pop có thể khiến bạn nghĩ như vậy .
TeX là một ngôn ngữ mở rộng vĩ mô. Bạn có thể, ví dụ, xác định \def\sayhello#1{Hello, #1!}
và sau đó viết \sayhello{Code Golfists}
để có được TeX để in Hello, Code Golfists!
. Đây được gọi là một macro macro không giới hạn, và để cung cấp cho nó tham số đầu tiên (và duy nhất, trong trường hợp này), bạn đặt nó trong dấu ngoặc nhọn. TeX loại bỏ các dấu ngoặc nhọn khi macro lấy đối số. Bạn có thể sử dụng tối đa 9 tham số: \def\say#1#2{#1, #2!}
sau đó \say{Good news}{everyone}
.
Bản sao của các macro không được phân tách là, không có gì đáng ngạc nhiên, các macro được phân tách :) Bạn có thể làm cho định nghĩa trước đó trở nên khó hiểu hơn về ngữ nghĩa : \def\say #1 to #2.{#1, #2!}
. Trong trường hợp này, các tham số được theo sau bởi cái gọi là văn bản tham số . Văn bản tham số như vậy phân định đối số của macro ( #1
được phân định bởi ␣to␣
, khoảng trắng được bao gồm và #2
được phân định bởi .
). Sau định nghĩa đó bạn có thể viết \say Good news to everyone.
, nó sẽ mở rộng ra Good news, everyone!
. Đẹp phải không? :) Tuy nhiên, một đối số được phân tách là (trích dẫn TeXbook ) là chuỗi các mã thông báo ngắn nhất (có thể trống) với các {...}
nhóm được lồng đúng cách được theo sau trong danh sách cụ thể của các mã thông báo không tham số cụ thể này. Điều này có nghĩa là việc mở rộng\say Let's go to the mall to Martin
sẽ tạo ra một câu kỳ lạ. Trong trường hợp này, bạn cần phải ẩn giấu đầu tiên ␣to␣
với {...}
: \say {Let's go to the mall} to Martin
.
Càng xa càng tốt. Bây giờ mọi thứ bắt đầu trở nên kỳ lạ. Khi TeX đọc một ký tự (được xác định bởi mã ký tự của người dùng), nó sẽ gán cho nhân vật đó một mã thể loại Mã số (mã hóa, cho bạn bè :) xác định nghĩa của ký tự đó. Sự kết hợp giữa mã ký tự và mã danh mục này tạo ra một mã thông báo ( ví dụ thêm về điều đó ở đây ). Những người quan tâm đến chúng tôi ở đây về cơ bản là:
catcode 11 , xác định mã thông báo có thể tạo thành chuỗi điều khiển (tên posh cho macro). Theo mặc định, tất cả các chữ cái [a-zA-Z] là catcode 11, vì vậy tôi có thể viết \hello
, đó là một chuỗi điều khiển duy nhất, trong khi đó \he11o
là chuỗi điều khiển \he
theo sau bởi hai ký tự 1
, theo sau là chữ cái o
, vì 1
không phải là catcode 11. Nếu tôi đã làm \catcode`1=11
, từ thời điểm đó trở đi \he11o
sẽ là một chuỗi điều khiển. Một điều quan trọng là mã hóa được thiết lập khi TeX lần đầu tiên nhìn thấy nhân vật trong tay và mã số như vậy bị đóng băng ... TUYỆT VỜI ! (điều khoản và điều kiện có thể áp dụng)
catcode 12 , hầu hết các ký tự khác, chẳng hạn như 0"!@*(?,.-+/
vv. Chúng là loại catcode ít đặc biệt nhất vì chúng chỉ phục vụ cho việc viết nội dung trên giấy. Nhưng này, ai dùng TeX để viết?!? (một lần nữa, các điều khoản và điều kiện có thể được áp dụng)
catcode 13 , đó là địa ngục :) Thật vậy. Ngừng đọc và đi làm một cái gì đó ra khỏi cuộc sống của bạn. Bạn không muốn biết catcode 13 là gì. Bạn đã bao giờ nghe đến thứ Sáu ngày 13 chưa? Đoán xem nó có tên từ đâu! Tiếp tục có nguy cơ của riêng bạn! Một ký tự 13 mã catcode, còn được gọi là một nhân vật hoạt động của người dùng, không chỉ là một nhân vật nữa, nó là một macro! Bạn có thể định nghĩa nó để có các tham số và mở rộng thành một cái gì đó như chúng ta đã thấy ở trên. Sau khi bạn làm \catcode`e=13
bạn nghĩ rằng bạn có thể làm \def e{I am the letter e!}
, NHƯNG. BẠN. KHÔNG THỂ! e
không phải là một bức thư nữa, vì vậy \def
không phải là \def
bạn biết, nó là \d e f
! Oh, chọn một chữ cái bạn nói? Đuợc! \catcode`R=13 \def R{I am an ARRR!}
. Rất tốt, Jimmy, hãy thử nó! Tôi dám bạn làm điều đó và viết một R
mã số của bạn! Đó là những gì một catcode 13 là. TÔI BÌNH TĨNH! Tiếp tục nào.
Được rồi, bây giờ để nhóm. Điều này khá đơn giản. Bất kỳ nhiệm vụ nào ( \def
là một hoạt động chuyển nhượng, \let
(chúng tôi sẽ thực hiện) là một nhiệm vụ khác) được thực hiện trong một nhóm được khôi phục lại trước khi nhóm đó bắt đầu trừ khi nhiệm vụ đó là toàn cầu. Có một số cách để bắt đầu các nhóm, một trong số đó là với catcode 1 và 2 ký tự (oh, lại mã hóa). Theo mặc định {
là catcode 1, hoặc nhóm bắt đầu và }
là catcode 2 hoặc nhóm cuối. Một ví dụ: \def\a{1} \a{\def\a{2} \a} \a
Bản in này 1 2 1
. Bên ngoài nhóm \a
là 1
, sau đó bên trong nó được xác định lại 2
và khi nhóm kết thúc, nó được khôi phục lại 1
.
Các \let
hoạt động là một hoạt động phân công như thế \def
, nhưng khá khác nhau. Với \def
bạn xác định các macro sẽ mở rộng thành công cụ, với \let
bạn tạo các bản sao của những thứ đã tồn tại. Sau \let\blub=\def
( =
tùy chọn), bạn có thể thay đổi bắt đầu e
ví dụ từ mục catcode 13 ở trên sang \blub e{...
và vui chơi với mục đó. Hoặc tốt hơn, thay vì phá vỡ những thứ bạn có thể sửa chữa (bạn sẽ xem xét điều đó!) R
Ví dụ : \let\newr=R \catcode`R=13 \def R{I am an A\newr\newr\newr!}
. Câu hỏi nhanh: bạn có thể đổi tên thành \newR
?
Cuối cùng, cái gọi là không gian giả mạo tinh vi. Đây là một chủ đề cấm kỵ bởi vì có những người cho rằng danh tiếng kiếm được trong Sàn giao dịch TeX - LaTeX bằng cách trả lời các không gian giả mạo của Wikipedia không nên xem xét các câu hỏi, trong khi những người khác hết lòng không đồng ý. Bạn đồng ý với ai? Đặt cược! Trong khi đó: TeX hiểu một ngắt dòng là một khoảng trắng. Cố gắng viết một vài từ có ngắt dòng (không phải là một dòng trống ) giữa chúng. Bây giờ thêm một %
ở cuối của những dòng này. Có vẻ như bạn đã bình luận về những không gian cuối dòng này. Đó là nó :)
(Sắp xếp) không mã hóa mã
Chúng ta hãy làm cho hình chữ nhật đó thành một cái gì đó (có thể nói là) dễ theo dõi hơn:
{
\let~\catcode
~`A13
\defA#1{~`#113\gdef}
AGG#1{~`#113\global\let}
GFF\else
GHH\fi
AQQ{Q}
AII{\ifxQ}
AEE#1#2#3|{I#3#2#1FE{#1#2}#3|H}
ADD#1#2#3|{I#2FE{#1}#2#3|H}
ACC#1#2|{D{}#2Q|#1 }
ABBH#1 {HI#1FC#1|BH}
\gdef\S#1{\iftrueBH#1 Q }
}
Giải thích từng bước
mỗi dòng chứa một lệnh duy nhất. Chúng ta hãy đi từng người một, mổ xẻ chúng:
{
Trước tiên, chúng tôi bắt đầu một nhóm để giữ một số thay đổi (cụ thể là thay đổi catcode) cục bộ để chúng không làm rối văn bản đầu vào.
\let~\catcode
Về cơ bản tất cả các mã mã hóa TeX bắt đầu với hướng dẫn này. Theo mặc định, cả trong TeX và LaTeX đơn giản, ~
ký tự là một ký tự hoạt động có thể được tạo thành macro để sử dụng tiếp. Và công cụ tốt nhất để làm lạ mã TeX là thay đổi catcode, vì vậy đây thường là sự lựa chọn tốt nhất. Bây giờ thay vì \catcode`A=13
chúng ta có thể viết ~`A13
( =
là tùy chọn):
~`A13
Bây giờ bức thư A
là một nhân vật hoạt động và chúng ta có thể định nghĩa nó để làm một cái gì đó:
\defA#1{~`#113\gdef}
A
bây giờ là một macro có một đối số (nên là một ký tự khác). Đầu tiên, catcode của đối số được thay đổi thành 13 để kích hoạt nó: ~`#113
(thay thế ~
bằng \catcode
và thêm một =
và bạn có \catcode`#1=13
:). Cuối cùng, nó để lại một \gdef
(toàn cầu \def
) trong luồng đầu vào. Nói tóm lại, A
làm cho một nhân vật khác hoạt động và bắt đầu định nghĩa của nó. Hãy thử nó:
AGG#1{~`#113\global\let}
AG
Đầu tiên, kích hoạt G
và kích hoạt \gdef
, và tiếp theo là G
bắt đầu định nghĩa. Định nghĩa của G
nó rất giống với định nghĩa của A
, ngoại trừ thay vì \gdef
nó làm một \global\let
(không \glet
giống như \gdef
). Nói tóm lại, G
kích hoạt một nhân vật và biến nó thành một thứ khác. Hãy tạo lối tắt cho hai lệnh chúng ta sẽ sử dụng sau:
GFF\else
GHH\fi
Bây giờ thay vì \else
và \fi
chúng ta chỉ có thể sử dụng F
và H
. Ngắn hơn nhiều :)
AQQ{Q}
Bây giờ chúng tôi sử dụng A
một lần nữa để xác định một macro khác , Q
. Các tuyên bố trên về cơ bản là (trong một ngôn ngữ ít bị xáo trộn) \def\Q{\Q}
. Đây không phải là một định nghĩa thú vị khủng khiếp, nhưng nó có một tính năng thú vị. Trừ khi bạn muốn phá vỡ một số mã, macro duy nhất mà mở rộng để Q
là Q
chính, vì vậy nó hoạt động như một dấu hiệu duy nhất (nó được gọi là một quark ). Bạn có thể sử dụng \ifx
điều kiện để kiểm tra nếu đối số của macro là quark như vậy với \ifx Q#1
:
AII{\ifxQ}
vì vậy bạn có thể khá chắc chắn rằng bạn đã tìm thấy một điểm đánh dấu như vậy. Lưu ý rằng trong định nghĩa này, tôi đã loại bỏ khoảng trắng giữa \ifx
và Q
. Thông thường, điều này sẽ dẫn đến một lỗi (lưu ý rằng phần tô sáng cú pháp cho rằng đó \ifxQ
là một điều), nhưng vì bây giờ Q
là catcode 13 nên nó không thể tạo thành một chuỗi điều khiển. Tuy nhiên, hãy cẩn thận, không mở rộng quark này hoặc bạn sẽ bị mắc kẹt trong một vòng lặp vô hạn vì Q
mở rộng tới Q
đó mở rộng tới Q
...
Bây giờ việc sơ bộ đã xong, chúng ta có thể đi đến thuật toán thích hợp để pwas eht setterl. Do mã thông báo của TeX, thuật toán phải được viết ngược. Điều này là do tại thời điểm bạn thực hiện một định nghĩa, TeX sẽ mã hóa (gán mã số) cho các ký tự trong định nghĩa bằng cách sử dụng các cài đặt hiện tại, ví dụ, nếu tôi làm:
\def\one{E}
\catcode`E=13\def E{1}
\one E
đầu ra là E1
, trong khi nếu tôi thay đổi thứ tự của các định nghĩa:
\catcode`E=13\def E{1}
\def\one{E}
\one E
đầu ra là 11
. Điều này là do trong ví dụ đầu tiên, E
trong định nghĩa đã được mã hóa thành một chữ cái (catcode 11) trước khi thay đổi catcode, vì vậy nó sẽ luôn là một chữ cái E
. Tuy nhiên, trong ví dụ thứ hai, E
lần đầu tiên được kích hoạt và chỉ sau đó \one
được xác định và bây giờ định nghĩa chứa mã số 13 E
mở rộng 1
.
Tuy nhiên, tôi sẽ bỏ qua thực tế này và sắp xếp lại các định nghĩa để có thứ tự hợp lý (nhưng không hoạt động). Trong đoạn văn sau đây bạn có thể giả định rằng các chữ cái B
, C
, D
, và E
đang hoạt động.
\gdef\S#1{\iftrueBH#1 Q }
. )
Trước tiên, chúng tôi xác định macro cấp độ người dùng , \S
. Đây không phải là một nhân vật hoạt động để có cú pháp thân thiện (?), Vì vậy macro cho gwappins eht setterl là \S
. Macro bắt đầu với một điều kiện luôn luôn đúng \iftrue
(nó sẽ sớm rõ ràng tại sao), và sau đó gọi B
macro theo sau H
(mà chúng ta đã xác định trước đó là \fi
) để khớp với \iftrue
. Sau đó, chúng ta để lại đối số của macro #1
theo sau là khoảng trắng và quark Q
. Giả sử chúng ta sử dụng \S{hello world}
, sau đó là luồng đầu vàosẽ giống như thế này: \iftrue BHhello world Q␣
(Tôi đã thay thế không gian cuối cùng bằng cách ␣
để kết xuất của trang web không ăn nó, giống như tôi đã làm trong phiên bản mã trước đó). \iftrue
là đúng, vì vậy nó mở rộng và chúng tôi còn lại với BHhello world Q␣
. TeX không không loại bỏ các \fi
( H
) sau khi có điều kiện được đánh giá, thay vào đó nó để lại nó ở đó cho đến khi \fi
được thực sự mở rộng. Bây giờ B
macro được mở rộng:
ABBH#1 {HI#1FC#1|BH}
B
là một macro được phân tách có văn bản tham số H#1␣
, vì vậy đối số là bất cứ thứ gì nằm giữa H
và một khoảng trắng. Tiếp tục ví dụ trên luồng đầu vào trước khi mở rộng B
là BHhello world Q␣
. B
được theo sau bởi H
vì nếu không (nếu không TeX sẽ phát sinh lỗi), thì khoảng trắng tiếp theo nằm giữa hello
và world
, từ đó #1
cũng vậy hello
. Và ở đây chúng tôi phải phân chia văn bản đầu vào tại các khoảng trắng. Yay: D Việc mở rộng B
để loại bỏ việc tất cả mọi thứ lên đến không gian đầu tiên từ input stream và thay thế bằng HI#1FC#1|BH
với #1
là hello
: HIhelloFChello|BHworld Q␣
. Lưu ý rằng có một BH
luồng mới sau trong luồng đầu vào, để thực hiện đệ quy đuôiB
và xử lý các từ sau. Sau khi từ này được xử lý xử B
lý từ tiếp theo cho đến khi từ được xử lý là quark Q
. Không gian cuối cùng sau Q
là cần thiết vì macro được phân tách B
yêu cầu một ở cuối đối số. Với phiên bản trước (xem lịch sử chỉnh sửa), mã sẽ hoạt động sai nếu bạn sử dụng \S{hello world}abc abc
(khoảng trắng giữa các abc
s sẽ biến mất).
OK, quay lại luồng đầu vào : HIhelloFChello|BHworld Q␣
. Đầu tiên có H
( \fi
) hoàn thành ban đầu \iftrue
. Bây giờ chúng ta có cái này (pseudocoding):
I
hello
F
Chello|B
H
world Q␣
Các I...F...H
suy nghĩ thực sự là một \ifx Q...\else...\fi
cấu trúc. Các \ifx
kiểm tra thử nghiệm nếu (đầu tiên dấu chỉ về sự) từ nắm lấy là Q
quark. Nếu không có gì khác để thực hiện và việc thực thi chấm dứt, nếu không thì còn lại là : Chello|BHworld Q␣
. Bây giờ C
được mở rộng:
ACC#1#2|{D#2Q|#1 }
Đối số đầu tiên C
là không bị giới hạn, vì vậy trừ khi được kết hợp, nó sẽ là một mã thông báo duy nhất, Đối số thứ hai được phân định bởi |
, do đó, sau khi mở rộng C
(với #1=h
và #2=ello
) luồng đầu vào là : DelloQ|h BHworld Q␣
. Chú ý rằng khác |
được đặt ở đó, và h
của hello
được đặt sau đó. Một nửa trao đổi được thực hiện; chữ cái đầu tiên ở cuối Trong TeX, thật dễ dàng để lấy mã thông báo đầu tiên của danh sách mã thông báo. Một macro đơn giản \def\first#1#2|{#1}
nhận được chữ cái đầu tiên khi bạn sử dụng \first hello|
. Vấn đề cuối cùng là một vấn đề vì TeX luôn lấy danh sách mã thông báo nhỏ nhất, có thể trống rỗng, làm đối số, vì vậy chúng tôi cần một vài cách giải quyết. Mục tiếp theo trong danh sách mã thông báo là D
:
ADD#1#2|{I#1FE{}#1#2|H}
Đây D
vĩ mô là một trong những công việc ở quanh và nó rất hữu ích trong trường hợp duy nhất mà từ có một chữ cái. Giả sử thay vì hello
chúng ta đã có x
. Trong trường hợp này, luồng đầu vào sẽ là DQ|x
, sau đó D
sẽ mở rộng (có #1=Q
và #2
trống) thành : IQFE{}Q|Hx
. Điều này tương tự với khối I...F...H
( \ifx Q...\else...\fi
) B
, sẽ thấy rằng đối số là quark và sẽ làm gián đoạn việc thực hiện chỉ để lại x
cho việc sắp chữ. Trong các trường hợp khác (trở lại hello
ví dụ), D
sẽ mở rộng (có #1=e
và #2=lloQ
) thành : IeFE{}elloQ|Hh BHworld Q␣
. Một lần nữa, I...F...H
sẽ kiểm tra Q
nhưng sẽ thất bại và lấy \else
chi nhánh : E{}elloQ|Hh BHworld Q␣
. Bây giờ là phần cuối cùng của điều này,E
vĩ mô sẽ mở rộng:
AEE#1#2#3|{I#3#2#1FE{#1#2}#3|H}
Văn bản tham số ở đây khá giống với C
và D
; đối số thứ nhất và thứ hai không bị giới hạn và đối số cuối cùng được phân định bởi |
. Luồng đầu vào trông như thế này : E{}elloQ|Hh BHworld Q␣
, sau đó E
mở rộng (với #1
khoảng trống #2=e
, và #3=lloQ
) : IlloQeFE{e}lloQ|HHh BHworld Q␣
. Một I...F...H
khối khác kiểm tra quark (nhìn thấy l
và trả về false
) : E{e}lloQ|HHh BHworld Q␣
. Bây giờ E
mở rộng lại (với #1=e
trống #2=l
, và #3=loQ
) : IloQleFE{el}loQ|HHHh BHworld Q␣
. Và một lần nữa I...F...H
. Macro thực hiện thêm một vài lần lặp cho đến khi Q
cuối cùng được tìm thấy và true
nhánh được thực hiện: E{el}loQ|HHHh BHworld Q␣
-> IoQlelFE{ell}oQ|HHHHh BHworld Q␣
-> E{ell}oQ|HHHHh BHworld Q␣
-> IQoellFE{ello}Q|HHHHHh BHworld Q␣
. Bây giờ quark được tìm thấy và điều kiện mở rộng thành : oellHHHHh BHworld Q␣
. Phù.
Oh, đợi đã, đây là những gì? THƯ VIỆN BÌNH THƯỜNG? Oh Boy! Các chữ cái cuối cùng được tìm thấy và TeX ghi lại oell
, sau đó một bó H
( \fi
) được tìm thấy và mở rộng (thành không có gì) để lại luồng đầu vào với : oellh BHworld Q␣
. Bây giờ từ đầu tiên có các chữ cái đầu tiên và cuối cùng được hoán đổi và những gì TeX tìm thấy tiếp theo là từ còn B
lại để lặp lại toàn bộ quá trình cho từ tiếp theo.
}
Cuối cùng, chúng tôi kết thúc nhóm bắt đầu trở lại đó để tất cả các bài tập địa phương được hoàn tác. Các bài tập địa phương là những thay đổi catcode của các chữ cái A
, B
, C
, ... mà đã được thực hiện macro để họ quay trở lại ý nghĩa bức thư bình thường của họ và có thể được sử dụng an toàn trong văn bản. Và đó là nó. Bây giờ \S
macro được xác định trở lại ở đó sẽ kích hoạt xử lý văn bản như trên.
Một điều thú vị về mã này là nó có thể mở rộng hoàn toàn. Đó là, bạn có thể sử dụng nó một cách an toàn trong việc di chuyển các đối số mà không lo rằng nó sẽ phát nổ. Bạn thậm chí có thể sử dụng mã để kiểm tra xem chữ cái cuối cùng của từ có giống với từ thứ hai không (vì bất kỳ lý do gì bạn sẽ cần điều đó) trong một \if
bài kiểm tra:
\if\S{here} true\else false\fi % prints true (plus junk, which you would need to handle)
\if\S{test} true\else false\fi % prints false
Xin lỗi vì lời giải thích (có lẽ quá xa). Tôi cũng đã cố gắng làm cho nó rõ ràng nhất có thể đối với những người không phải TeXies :)
Tóm tắt cho người thiếu kiên nhẫn
Macro \S
chuẩn bị đầu vào với một ký tự hoạt động B
, lấy danh sách các mã thông báo được phân tách bằng khoảng trắng cuối cùng và chuyển chúng đến C
. C
lấy mã thông báo đầu tiên trong danh sách đó và di chuyển nó đến cuối danh sách mã thông báo và mở rộng D
với những gì còn lại. D
kiểm tra xem những gì còn lại là trống rỗng, trong trường hợp đó, một từ đơn lẻ được tìm thấy, sau đó không làm gì cả; nếu không thì mở rộng E
. E
các vòng lặp thông qua danh sách mã thông báo cho đến khi tìm thấy chữ cái cuối cùng trong từ, khi tìm thấy nó để lại chữ cái cuối cùng, theo sau là từ giữa, sau đó là chữ cái đầu tiên ở cuối dòng mã thông báo C
.
Hello, world!
trở thành,elloH !orldw
(hoán đổi dấu câu như một chữ cái) hoặcoellH, dorlw!
(giữ dấu câu đúng chỗ)?