> For the complete documentation index, see [llms.txt](https://overleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://overleaf-pro.ayaka.space/latex/pl/wiecej-tematow/22-how-tex-macros-actually-work-part-4.md).

# Jak naprawdę działają makra TeX-a: Część 4

[Część 1](/latex/pl/wiecej-tematow/19-how-tex-macros-actually-work-part-1.md) [Część 2](/latex/pl/wiecej-tematow/20-how-tex-macros-actually-work-part-2.md) [Część 3](/latex/pl/wiecej-tematow/21-how-tex-macros-actually-work-part-3.md) [Część 4](/latex/pl/wiecej-tematow/22-how-tex-macros-actually-work-part-4.md) [Część 5](/latex/pl/wiecej-tematow/23-how-tex-macros-actually-work-part-5.md) [Część 6](/latex/pl/wiecej-tematow/24-how-tex-macros-actually-work-part-6.md)

## Wprowadzenie i omówienie

W częściach 1–3 zagłębiliśmy się w pewne niskopoziomowe szczegóły tła, aby przygotować się do zrozumienia, jak działają makra TeX-a. W tym artykule „wynurzymy się na chwilę”, aby omówić podstawowe praktyczne zasady działania makr TeX-a przed kolejnym zagłębieniem się w częściach 5 i 6. W całym tym artykule będziemy pokazywać przykładowe makra zdefiniowane za pomocą pierwotnej komendy TeX-a `\def`: nie będziemy używać być może bardziej znanej komendy LaTeX-a `\newcommand`. Jest ku temu bardzo dobry powód: naszym celem jest zrozumienie fundamentalnych zasad leżących u podstaw zachowania makr TeX-a, ale aby to zrobić, musimy używać podstawowych komend *wbudowanych w* oprogramowanie TeX-a. Komendy LaTeX-a, takie jak `\newcommand`, same są makrami: komendami o określonym zaprogramowanym zachowaniu, które ostatecznie są zbudowane z warstw niższopoziomowych pierwotnych komend TeX-a. Aby lepiej zrozumieć fundamentalne zachowanie TeX-a, musimy używać prymitywów TeX-a, a nie makr LaTeX-a.

### Dokąd zmierzamy?

W istocie zmierzamy do wyjaśnienia makr jako wyspecjalizowanej formy listy tokenów: gdy polecasz TeX-owi zdefiniować makro, tworzy on sekwencję tokenów (listę tokenów) i zapisuje ją w swojej pamięci, powiązaną z nazwą, którą zdefiniujesz. W częściach 5 i 6 przyjrzymy się dość szczegółowo listom tokenów makr, ale jeśli wolisz przejść z tego artykułu do przeczytania informacji wprowadzających, znajdziesz je w [Czym jest lista tokenów TeX-a?](/latex/pl/artykuly-szczegolowe/54-what-is-a-tex-token-list.md)

Listy tokenów makr i ich parametry zawierają kilka dodatkowych zawiłości, które omówimy szczegółowo — i użyjemy wielu przykładów. Aby lepiej zrozumieć zachowania przetwarzania makr w TeX-u, naprawdę trzeba pamiętać o jednym kluczowym fakcie: TeX myśli o znakach tylko na najwcześniejszym etapie przetwarzania wejścia: od tego momentu wszystko to już tokeny! W tym i w pozostałych artykułach z tej serii będziemy badać rolę, jaką tokeny odgrywają w makrach TeX-a.

## Cztery części makra

### Przypomnienie: parametry makra i argumenty makra

Zanim zaczniemy, warto przypomnieć sobie różnicę między *parametrami* i *argumenty*, ponieważ będziemy używać obu tych terminów w całym tym artykule. Załóżmy, że definiujesz makro \foo

```
\def\foo#1#2{To jest #1, to jest #2}
```

Konstrukty (tokeny) `#1`, `#2` (aż do `#9`) nazywane są *parametrami*: traktuj je jako „miejsca zastępcze” dla rzeczywistych danych, których użyjesz przy wywołaniu makra:

```
\foo{alpha}{beta}
```

Tutaj, `alpha` i `beta` są *argumenty* użyte przy tym wywołaniu \foo: argumenty makra to rzeczywiste wartości przekazywane do miejsc zastępczych parametrów (`#1`, `#2`... `#9`) użytych przy definiowaniu makra.

### Definicja makra: ma 4 elementy

Zaczniemy od czegoś, co może wyglądać na nieco formalną definicję makra, ale zapewnia ona użyteczne ramy do dalszej dyskusji.

Każda definicja makra składa się z 4 części:

```
<prymityw makra TeX><nazwa makra><tekst parametrów>{<tekst podstawienia>}
```

gdzie:

* `<prymityw makra TeX>`: jedna z `\def`, `\edef`, `\gdef` lub `\xdef`;
* `<nazwa makra>`: nazwa nadana twojej komendzie makra, na przykład `\foo`;
* `<tekst parametrów>`: może go nie być, ale jeśli jest obecny, stanowi ciąg *tokeny* które pojawiają się przed `<tekst zastępczy>` makra.  `<tekst parametrów>` może zawierać parametry makra (`#1`, `#2`... `#9`) oraz inne typy tokenów. W istocie, jak zobaczymy szczegółowo,  `<tekst parametrów>` zapewnia pewnego rodzaju *szablon tokenów* którego TeX używa do ustalenia, które tokeny użytkownik chce wykorzystać jako argumenty makra: gdy wywołujesz makro, TeX przekazuje *argumentu* tokeny do `<tekst zastępczy>` (który także jest listą tokenów);
* `{<replacement text>}`: to jest właściwe ciało twojego makra: jest to ciąg tokenów, do którego *argumenty* są „wstrzykiwane” podczas przetwarzania (rozwijania) makra. Argumenty są wprowadzane do pozycji wskazanych przez parametry makra użyte w oryginalnej definicji.

**UWAGA**: W całej dyskusji zakładamy, że `<nazwa makra>` będzie po nim zastępował znak spacji o kodzie kategorii 10, pełniący rolę ogranicznika kończącego `<nazwa makra>`. My *nie* pokazaliśmy wyraźnie tego znaku spacji w naszym tekście/dyskusji, ale zakładamy, że tam jest. Ściśle mówiąc, powinniśmy zapisać to mniej więcej tak:

```
<TeX macro primitive><macro name><space><parameter text>{<replacement text>}
```

Jednak pominiemy wyraźne uwzględnienie `<space>` znaku i domyślnie założymy jego obecność.

#### Uwagi o {}

Pokazaliśmy użycie dwóch nawiasów klamrowych: `{` i `}` które otaczają (wyznaczają granice) właściwe ciało `<tekst zastępczy>`. `{` i `}` to tylko przyjęta konwencja, ponieważ TeX faktycznie oczekuje, że tekst twojego makra `<tekst zastępczy>` zaczyna się znakiem o kodzie kategorii 1 („Rozpocznij grupę”) i kończy znakiem o kodzie kategorii 2 („Zakończ grupę”). Zgodnie z konwencją są to `{` i `}` odpowiednio znaki. Możesz jednak, jeśli chcesz, przypisać do tego dowolną parę znaków. Na przykład

```
\catcode`\(=1
\catcode`\)=2
```

Teraz możesz definiować i używać makr w ten sposób:

```
\def\foo #1(Witaj, #1)
\foo(World!)
```

I nadal możesz używać `{` i `}` ponieważ nie zmieniliśmy ich kodów kategorii — wiele znaków może mieć i ma ten sam kod kategorii, więc możesz nadal definiować makra w zwykły sposób:

```
\def\foo #1{Witaj, #1}
\foo{World!}
```

### i {}

Składniki definicji makra najbardziej istotne dla naszej dyskusji to `<tekst parametrów>` i `{<replacement text>}`. Gdy definiujesz makro,  `<tekst parametrów>` jest w istocie ścisłym szablonem tokenów, który określa, jak ma być używane makro. Jak wspomniano, `<tekst parametrów>` może być puste, np. `\def\foo{Jakiś tekst}` gdzie między nazwą naszej komendy (`\foo`) `{` który tutaj sygnalizuje początek `<tekst zastępczy>`.

**Uwaga**: Niektórzy czytelnicy mogą znać mechanizm „hashquote” TeX-a (`#{`) ale nie będziemy go tu omawiać.

### i delimitery makr

Ten konkretny artykuł nie ma być wyczerpującym omówieniem pisania makr, ale warto zrobić krótkie powtórzenie z kilkoma przykładami, pokazujące, że `<tekst parametrów>` mogą stać się złożone, ponieważ TeX pozwala `<tekst parametrów>` zawierać:

* **parametry makra**: (`#1`, `#2`,... `#9`) które działają jako „miejsca zastępcze” dla wartości, które użytkownik poda podczas uruchamiania makra — *argumenty*;
* **tokeny delimitujące**: dowolne tokeny, wstawione pomiędzy tokeny parametrów i wokół nich, używane do określenia granicy między parametrami makra. Możesz myśleć o tych delimiterach jako o pewnego rodzaju „interpunkcji”, która tworzy `<tekst parametrów>` „szablon tokenów”, który będziesz musiał/musiała stosować, gdy używasz makra. Tokeny delimitujące nie są składuowane.

Co to właściwie oznacza — spójrzmy na kilka przykładów.  `<tekst parametrów>` znajduje się między nazwą makra a lewym nawiasem klamrowym `{` definicji makra.

#### Delimitery: przykład 1

Załóżmy, że zdefiniujemy podstawowe makro `\foo` w następujący sposób:

```
\def\foo ABC{witaj, tam}
```

* `<tekst parametrów>` = `ABC`
* Nie ma tokenów parametrów (`#1`, `#2`,... `#9`)
* Delimiterami są *trzy tokeny znakowe* `ABC` ale w tym przykładzie są nieco zbędne i służą jedynie jako przykład.

Trzy tokeny znakowe `ABC` są traktowane jako delimitery: nie jako coś do składu, lecz jako „interpunkcja”, której oczekuje się przy wywołaniu makra — gdy używasz makra `\foo` musisz podać te same delimitery, które były obecne przy jego definiowaniu.

Jeśli wpiszesz `\foo ABC` w swoim tekście, to zostanie złożone `witaj, tam`—tokeny znakowe `ABC` nie są składane, ale TeX bardzo dokładnie sprawdził, czy były obecne w twoim wywołaniu (call)  `\foo`. TeX szuka tych delimiterów („interpunkcji”) i usuwa (absorbuje) je, jak widać na poniższym zrzucie ekranu z Overleaf: `ABC` nie jest składane:

![Overleaf uruchamiający makro TeX-a](/files/d268d7f011bccbddefe1cffe8e725d5589794d0f)

Jeśli spróbujesz użyć `\foo` bez `ABC` delimiterów, TeX zgłosi błąd `Użycie \foo nie zgadza się z jego definicją.`:

![Wyświetlanie błędu TeX-a w Overleaf](/files/ea7455a9abe435ff9abf1bd6126e1f7a47a3498d)

W powyższym przykładzie, po wykryciu `\foo` TeX oczekuje, że zobaczy trzy tokeny znakowe `ABC` ale tak się nie dzieje: widzi token znakowy dla `w` i natychmiast wykrywa, że coś jest nie tak.

#### Delimitery: przykład 2

Interesującym, a może zaskakującym faktem jest to, że delimiterami mogą być dowolne tokeny komend — w tym komendy, które *nawet nie zostały zdefiniowane*. Na przykład moglibyśmy zdefiniować `\foo` w następujący sposób:

```
\def\foo A\bob B\anne{Witaj \TeX{}}
```

* `<tekst parametrów>` = `A\bob B\anne`
* Nie ma tokenów parametrów (`#1`, `#2`,... `#9`)
* Delimiterami są tokeny `A\bob B\anne` ale ponownie, w tym przykładzie są zbędne i służą tylko do celów dyskusji. Zauważ, że `\bob` i `\anne` to fikcyjne komendy, które *nie zostały zdefiniowane*—i nie muszą być.

Gdy wywołujesz makro, TeX sprawdza (skanuje) `<tekst parametrów>` który jest obecny *w twoim wywołaniu makra* i porównuje go token po tokenie z wersją „szablonu tokenów” *zapisaną w pamięci*—tą utworzoną w momencie definiowania makra. TeX skanuje *użyte w twoim wywołaniu makra* i po prostu konwertuje wszystkie znalezione tam komendy na ich numeryczne wartości tokenów: nie próbuje ich wykonywać, dlatego nie ma znaczenia, że `\bob` i `\anne` nigdy nie zostały zdefiniowane. TeX po prostu używa szablonu tokenów zapisanego w pamięci jako wskazówki, która pozwala mu ustalić, które tokeny w `<tekst parametrów>` twojego wywołania makra są rzeczywistymi argumentami do przekazania do `<tekst zastępczy>`.

Jak widać na poniższym fragmencie zrzutu ekranu Overleaf, żaden z tokenów znakowych (`Skopiowany` i `B`) w obrębie `A\bob B\anne` nie został złożony, a nasze niezdefiniowane komendy `\bob` i `\anne` nie spowodowały żadnych problemów. Wszystkie te tokeny zostały *wchłonięte* przez TeX-a podczas dopasowywania twojego użycia `\foo` z definicją (szablonem tokenów)  `\foo` (listą tokenów) zapisaną w pamięci.

![Overleaf uruchamiający makro TeX-a](/files/28212836bdb9f5d82ce4c6e61d30b3f023f619b5)

#### Delimitery: przykład 3

Możesz przeplatać różne delimitery (tokeny znakowe, tokeny komend) z parametrami makra, jak w tym przykładzie:

```
\def\foo A\bob#1B\anne#2\jane#3bye!{Witaj od \TeX{} do \#1=#1, \#2=#2 i \#3=#3}
```

* `<tekst parametrów>` = `A\bob#1B\anne#2\jane#3bye!`
* Są 3 tokeny parametrów makra: `#1`, `#2`, `#3`
* Tym razem parametry (`#1`, `#2`, `#3`) są wyznaczone przez kombinację tokenów:

  `A\bob#1B\anne#2\jane#3bye!`

W praktyce dostarczyłeś TeX-owi szablon, który będzie bardzo starannie próbował dopasować i którego będzie oczekiwał przy wywołaniu `\foo`: przejdzie przez twoje wywołanie makra, *token po tokenie*, i będzie oczekiwał dopasowania (znalezienia):

* dwóch tokenów `Skopiowany` i `\bob` zanim `#1`
* dwóch tokenów `B` i `\anne` zanim `#2`
* tokenu `\jane` przed parametrem `#3` oraz *czterech tokenów znakowych* `b`, `y`,`e` i `!` po `#3`.

**Pamiętaj**: TeX myśli w tokenach, więc `pa!` to *czterech tokenów znakowych*.

Są dwa sposoby użycia tego makra — możemy umieścić dowolne argumenty wielotokenowe w nawiasach klamrowych, aby utworzyć grupę:

```
\foo A\bob{To}B\anne{Tamto}\jane{Inne}bye!
```

Jednak to *nie jest konieczne* ponieważ nasza definicja makra ma delimitery, które zapewniają szablon tokenów. TeX może użyć tego szablonu, aby wyodrębnić tokeny dla każdego argumentu spośród tokenów będących wyłącznie delimiterami. Możemy użyć naszego makra tak:

```
\foo A\bob ThisB\anne That\jane Otherbye!
```

a TeX może wyłuskać argumenty, uzyskując taki sam rezultat jak przy użyciu grup `{...}`:

![Overleaf uruchamiający makro TeX-a z użyciem delimiterów](/files/23fe9f09dd28797292e157486ce7ccc8aca82ab6)

Zwróć uwagę, jak TeX zdołał precyzyjnie wykryć, które tokeny odpowiadały parametrom `#1` i `#3`:

![Overleaf uruchamiający makro TeX-a z użyciem delimiterów](/files/231e705c489bba06368d5c96494dea92c9605ff8)

#### Delimitery: przykład 4 (chodzi o tokeny, nie o znaki!)

Oto krótki przykład pokazujący, że podczas pracy z makrami ważne jest pamiętać, iż naprawdę jesteśmy w świecie *tokeny* i **nie** *znaki*…

Zdefiniujemy następujące krótkie makro, w którym A i B są znakami pełniącymi rolę delimiterów i oba mają kod kategorii 11. To działa bez problemów:

```
\documentclass{article}
\begin{document}
\def\foo A#1B{Witaj, #1}
\foo AGrahamB
\end{document}
```

i składa `Witaj, Graham`.

Jednak jeśli zmienisz kod kategorii A lub B na coś innego niż 11, wywołanie makra się nie powiedzie. Załóżmy, że zmienimy kod kategorii B na 12, używając ``\catcode`B=12`` i spróbujmy ponownie wywołać makro, tak jak wcześniej:

```
\documentclass{article}
\begin{document}
\def\foo A#1B{Witaj, #1}
\foo AGrahamB % To działa
\catcode`\B=12\relax
\foo AGrahamB
\end{document}
```

To kończy się dość zagadkowym błędem:

```
Argument wymknął się spod kontroli?
GrahamB \end {document}
! Plik zakończył się podczas skanowania użycia \foo.
<wstawiony tekst>
                \par
<*> main.tex

Podejrzewam, że zapomniałeś o `}', co zmusza mnie
do czytania dalej niż chciałeś, żebym się zatrzymał.
Spróbuję się odzyskać; ale jeśli błąd jest poważny,
lepiej teraz wpisz `E' lub `X' i popraw swój plik.

! Zatrzymanie awaryjne.
<*> main.tex

*** (zadanie przerwane, nie znaleziono poprawnego \end)
```

![Overleaf wyświetlający błąd makra TeX-a](/files/f5f351400ad007ff4776b263087a2fdbf213271d)

Niestety domyślna sugestia TeX-a: ``Podejrzewam, że zapomniałeś o `}'`` to **błędna**, nie jest spowodowany brakiem nawiasu klamrowego (`}`).

#### Co się stało?

TeX próbuje dopasować `\foo` makra *wywołanie* z `\foo` makra *definicją* zapisaną w pamięci. Gdy wywołujesz makro, które potrzebuje jednego lub więcej argumentów, TeX musi zbadać (zeskanować) użycie makra, aby ustalić *argumenty* które przekazujesz temu makru. Tutaj TeX oczekuje, że argument będzie umieszczony między A (kod kategorii 11) a B (kod kategorii 11). Pamiętaj: TeX myśli w *tokeny*, **nie** *znaki*.

Wartości tokenów dla A i B, $$\mathrm{T\_A}$$ i $$\mathrm{T\_B}$$ odpowiednio, to:

$$\mathrm{T\_A = 256 \times 11 + 65 = 2881}$$ $$\mathrm{T\_B = 256 \times 11 + 66 =2882}$$

Jednak gdy TeX kontynuuje poszukiwania, widzi B *ale* teraz ma kod kategorii 12, a to daje inną wartość tokenu:

$$\mathrm{T'\_B= 256 \times 12 + 66 =3138}$$

W `\foo` definicji makra wartość tokenu B (używanego jako delimiter) wynosiła 2882, ale TeX teraz widzi wartość tokenu 3138: myśli, że to po prostu kolejny token przeznaczony do użycia w *argumentu* przekazanym do `\foo`. Jeśli chodzi o TeX-a, nie znaleziono jeszcze końcowego tokenu argumentu, więc pobiera kolejny token w poszukiwaniu B z kodem kategorii 11. To właśnie wtedy i dlatego makro się nie udaje: próbując znaleźć argument, TeX „przestrzeliwuje” i zaczyna czytać tokeny, których nie zamierzałeś włączyć do argumentu `\foo` wywołania makra. To, co stanie się dalej, zależy od `Argument wymknął się spod kontroli?` błędy.

W naszym przykładzie TeX przestrzeliwuje i pochłania strumień tokenów `\end {document}` i szybko dochodzi do końca pliku, stąd komunikat o błędzie:

```
! Plik zakończył się podczas skanowania użycia \foo
```

## Część 5

Jak widzieliśmy powyżej,  `<tekst parametrów>` sekcja naszej definicji makra może być od niezwykle prostej po złożoną mieszankę parametrów makra przeplatanych tokenami znakowymi i tokenami komend pełniącymi rolę delimiterów. TeX potrafi przetworzyć różne kombinacje tokenów obecne w `<tekst parametrów>` aby wyodrębnić argumenty przekazane makru — i wykryć, gdy próbujemy użyć makra niepoprawnie. Jak to robi, będzie tematem następnego artykułu z tej serii.

[Część 1](/latex/pl/wiecej-tematow/19-how-tex-macros-actually-work-part-1.md) [Część 2](/latex/pl/wiecej-tematow/20-how-tex-macros-actually-work-part-2.md) [Część 3](/latex/pl/wiecej-tematow/21-how-tex-macros-actually-work-part-3.md) [Część 4](/latex/pl/wiecej-tematow/22-how-tex-macros-actually-work-part-4.md) [Część 5](/latex/pl/wiecej-tematow/23-how-tex-macros-actually-work-part-5.md) [Część 6](/latex/pl/wiecej-tematow/24-how-tex-macros-actually-work-part-6.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://overleaf-pro.ayaka.space/latex/pl/wiecej-tematow/22-how-tex-macros-actually-work-part-4.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
