> 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/fi/syvalliset-artikkelit/18-how-does-expandafter-work-a-detailed-study-of-consecutive-expandafter-commands.md).

# Miten \expandafter toimii: yksityiskohtainen tutkimus peräkkäisistä \expandafter-komennosta

&#x20;[Osa 1](/latex/fi/syvalliset-artikkelit/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md)   [Osa 2](/latex/fi/syvalliset-artikkelit/22-how-does-expandafter-work-the-meaning-of-expansion.md)   [Osa 3](/latex/fi/syvalliset-artikkelit/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md)   [Osa 4](/latex/fi/syvalliset-artikkelit/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md)   [Osa 5](/latex/fi/syvalliset-artikkelit/17-how-does-expandafter-work-a-detailed-macro-case-study.md)   [Osa 6](/latex/fi/syvalliset-artikkelit/18-how-does-expandafter-work-a-detailed-study-of-consecutive-expandafter-commands.md)&#x20;

## Tapaustutkimus: \expandafter\expandafter\expandafter...n ymmärtäminen

Edistyneet makrot, kuten LaTeX-paketeissa olevat, käyttävät usein laajasti useita peräkkäisiä `\expandafter` komentoja toteuttaakseen monimutkaista tokenien “jongleerausta”. Useimmille meistä tällaisia makroja voi olla vaikea ymmärtää tai pelottavaa kirjoittaa. Tässä osiossa tarkastelemme mekaniikkaa, joka on TeXin peräkkäisten `\expandafter` komentojen käsittelyn taustalla:

```
\expandafter\expandafter\expandafter...
```

Selitystämme helpottaaksemme lisäämme alaindeksit jokaiseen `\expandafter`—osoittamaan, mihin niistä viittaamme:

```
        \expandafter1\expandafter2\expandafter3...
```

Lisäksi laajennamme kunkin `\expandafter` käsittelemien tokenien merkintää käyttämään $$\mathrm{T^i\_1}$$ ja $$\mathrm{T^i\_2}$$ edustamaan tokeneita $$\mathrm{T\_1}$$ ja $$\mathrm{T\_2}$$ joita lukee `\expandafter` alaindeksillä `i`: `\expandafter`<sub>i</sub> $$\mathrm{T^i\_1T^i\_2}$$. Oletamme myös, että kaksi tokenia $$\mathrm{T\_X}$$ ja $$\mathrm{T\_Y}$$ seuraa jälkeen `\expandafter<sub>3</sub>` jotta syötteemme näyttää tältä: `\expandafter<sub>1</sub>\expandafter<sub>2</sub>\expandafter<sub>3</sub>` $$\mathrm{T\_{X}T\_{Y}}$$.

Kun TeX alkaa käsitellä tätä syötettä, kohdassa `\expandafter<sub>1</sub>` se näkee

* $$\mathrm{T^1\_1} =$$`\expandafter<sub>2</sub>` joka tallennetaan myöhempää *uudelleensijoitusta* varten takaisin syötteeseen
* $$\mathrm{T^1\_2} =$$`\expandafter<sub>3</sub>`, joka laajennetaan

Jos palaamme aiempaan keskusteluumme [TeXin sisällä olevasta koodista](/latex/fi/syvalliset-artikkelit/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md) joka toteuttaa `\expandafter`, juuri laajennuksessa `\expandafter<sub>3</sub>` näemme rekursion tapahtuvan. Käsitelläkseen `\expandafter<sub>1</sub>` TeX on jo kutsunut sisäistä funktiotaan `expand()`, joten käsitelläkseen (laajentaakseen) `\expandafter<sub>3</sub>` TeX tekee *toisen* kutsun funktiolle `expand()`—funktion sisältä `expand()` itse funktiosta.

Tiedostoissa `\expandafter<sub>3</sub>` meillä on

* $$\mathrm{T^3\_1 = T\_X}$$, joka tallennetaan myöhempää *uudelleensijoitusta* varten takaisin syötteeseen
* $$\mathrm{T^3\_2 = T\_Y}$$, jonka oletamme olevan laajennettavissa

Oletetaan lisäksi, että $$\mathrm{T\_Y}$$ laajennus tuottaa seuraavan tokenijonon: $$\mathrm{{T^1\_Y}{T^2\_Y}{T^3\_Y}}\cdots\mathrm{T^N\_Y}$$. Olemme nyt saavuttaneet sen laajennusprosessin lopun, jonka komentosarja `\expandafter<sub>1</sub>\expandafter<sub>2</sub>\expandafter<sub>3</sub>` $$\mathrm{T\_{X}T\_{Y}}$$ ja TeX alkaa “purkaa” rekursion prosessia, joka alkoi kohdasta `\expandafter<sub>1</sub>`.

Käsittelyn jälkeen `\expandafter<sub>3</sub>` TeXin muistissa on tokenilista, joka sisältää tokenit laajennuksesta $$\mathrm{T\_Y\text{: }{T^1\_Y}{T^2\_Y}{T^3\_Y}}\cdots\mathrm{T^N\_Y}$$. TeX alkaa nyt sijoittaa takaisin tokenit, jotka se tallensi käsitellessään `\expandafter` komentojen käsittelyn taustalla:

1. TeX aloittaa sijoittamalla takaisin tokenin $$\mathrm{T\_X}$$ jonka tallensi `\expandafter<sub>3</sub>`. $$\mathrm{T\_X}$$ sijoitetaan takaisin *eteen* laajennuksen $$\mathrm{T\_Y}$$, mikä johtaa tokenijonoon: $$\mathrm{{{T\_X}T^1\_Y}{T^2\_Y}{T^3\_Y}}\cdots\mathrm{T^N\_Y}$$.
2. Meidän on kuitenkin vielä saatettava päätökseen prosessi, jonka aloitti `\expandafter<sub>1</sub>` joka tallensi tokenin, joka edustaa `\expandafter<sub>2</sub>`
3. TeXin kokoama lopullinen tokenijono, joka on valmis luettavaksi TeXin käsittelyn seuraavassa vaiheessa, on `\expandafter<sub>2 (token)</sub>` $$\mathrm{T\_{X}T^1\_{Y}T^2\_{Y}T^3\_{Y}\cdots T^N\_Y}$$
4. TeX on nyt saanut päätökseen käsittelyn “ensimmäisen kierroksen” ja siirtyy lukemaan luomansa tokenilistojen jonon—se jono alkaa `\expandafter<sub>2 (token)</sub>` jota TeX alkaa käsitellä. Kohdassa `\expandafter<sub>2</sub>` meillä on
   * $$\mathrm{T^2\_1} =\ \mathrm{T\_X}$$ joka tallennetaan myöhempää *uudelleensijoitusta* varten takaisin syötteeseen
   * $$\mathrm{T^2\_2} = \mathrm{T^1\_Y}$$ joka on ensimmäinen token, joka syntyy laajennuksesta $$\mathrm{T\_Y}$$; jos se on laajennettavissa, se laajennetaan
5. Jos oletamme tokenin $$\mathrm{T^1\_Y}$$, ensimmäisen tokenin laajennuksesta $$\mathrm{T\_Y}$$, laajenee $$\mathrm{{T^A\_{Y1}}{T^B\_{Y1}}{T^C\_{Y1}}}$$ niin, kun TeX on sijoittanut takaisin $$\mathrm{T\_X}$$, tuloksena oleva TeXin uudelleenkäsiteltävä tokenijono olisi: $$\mathrm{{T\_X}{T^A\_{Y1}}{T^B\_{Y1}}{T^C\_{Y1}}{T^2\_Y}{T^3\_Y}\cdots{T^N\_Y}}$$

   jonka voimme ilmaista uudelleen muodossa

   $$\mathrm{T\_X}\text{\<expansion of the first token in }\mathrm{T\_Y}\text{>\<remaining tokens in }\mathrm{T\_Y}\text{>}$$

Seuraava kaavio havainnollistaa TeX-koodin luomia tokenilistoja

```
    \expandafter1\expandafter2\expandafter3TXTY
```

![Kuva, joka näyttää TeXin käsittelevän useita \expandafter-komentoja](/files/05641e5917981b25ebc1eeabab27503f7977503e)

### Teoriasta käytäntöön

Esimerkiksi määrittelemme seuraavat makrot toimimaan $$\mathrm{T\_X}$$ ja $$\mathrm{T\_Y}$$

* $$\mathrm{T\_X}=$$`\foo` jossa määrittelemme `\foo` muodossa `\def\foo#1{\textbf{#1}}`
* $$\mathrm{T\_Y}=$$`\bar` jossa määrittelemme ensin `\def\abc{Hello}`, `\def\xyz{, World!}` ja sitten `\def\bar{\abc\xyz}`

Käytämme seuraavaa koodinpätkää osoittaaksemme aiemman analyysimme:

\expandafter\expandafter\expandafter\foo\bar

Keskustelumme perusteella tulos `\expandafter<sub>1</sub>\expandafter<sub>2</sub>\expandafter<sub>3</sub>` $$\mathrm{T\_X}\mathrm{T\_Y}$$ tuottaa seuraavan muotoisen tokenijonon:

$$\mathrm{T\_X}\text{\<expansion of the first token in }\mathrm{T\_Y}\text{>\<remaining tokens in }\mathrm{T\_Y}\text{>}$$

jossa tarkka jono riippuu tokenin luonteesta $$\mathrm{T\_Y}$$. Jos sijoitamme esimerkkikomennot käyttäen $$\mathrm{T\_X}=$$`\foo` ja $$\mathrm{T\_Y}=$$`\bar`, joka on määritelty muodossa `\def\bar{\abc\xyz}`, näemme:

* ensimmäinen token kohdassa $$\mathrm{T\_Y}$$ on `\abc` ja sen laajennus on merkkitokenien jono: `Hello`
* loput tokenit kohdassa $$\mathrm{T\_Y}$$ on yksittäinen token, joka edustaa `\xyz`.

Jos syötämme tämän tiedon “analyysiimme”, saamme

$$\begin{align\*} &\mathrm{T\_X}\text{\<expansion of the first token in }\mathrm{T\_Y}\text{>\<remaining tokens in }\mathrm{T\_Y}\text{>}\ &=\text{foo}*{\text{token}}\text{\<expansion of \abc>}*\text{token list (characters)}\text{xyx}*\text{token}\ &=\text{foo}*\text{token}\text{Hello}*\text{token list (characters)}\text{xyx}*\text{token}\\\[10pt] \end{align\*}$$

Huomaa, että alaindeksit <sub>tokenin</sub> ja <sub>tokenilista (merkit)</sub> korostavat (muistuttavat meitä), että TeX lukee *kokonaislukutokenien arvoja*, ei *tekstimerkkejä*, joten välilyöntimerkkejä tai muita erottimia ei tarvitse näyttää jälkeen `\foo`: tällaiset erottimet on jo ajat sitten käsitelty tai hylätty; täällä olemme tiukasti TeXin sisäisessä tokenilistojen ja kokonaislukutokenien maailmassa.

Kun TeX käsittelee meidän tuottamamme tokenilistajonon `\expandafter` komennot, se ladottaa `**H**ello, World!`—vain `H` ladotetaan lihavoituna. Voisimme saavuttaa saman tuloksen kirjoittamalla vastaavan TeX-koodin `\foo Hello\xyz`. Huomaa, että määritelmä `\foo` käytti yhtä parametria; näin ollen, `\foo` imee ainoan `H` merkkitokenin argumentikseen, jättäen jäljelle jäävät merkkitokenit (`ello`) koskemattomiksi.

**Huomautuksia:**

* kirjoittamalla `\foo\bar` saat hyvin erilaisen tulosteen: token kohdasta `\bar` käytettäisiin argumenttina funktiolle `\foo` mikä johtaa ladontaan **`Hello, World`**—kaikki ladotetaan lihavoituna.
* kirjoittamalla `\expandafter\foo\bar` aiheuttaa `\bar` laajennettavaksi, mikä tuottaa kaksi tokenia: $$\text{abc}*\text{token}\text{xyz}*\text{token}$$. Sitten, kun $$\text{foo}*\text{token}$$ sijoitetaan takaisin toimesta `\expandafter` TeX käsittelee tokenijonon $$\text{foo}*\text{token}\text{abc}*\text{token}\text{xyz}*\text{token}$$ joka ladottaa `**Hello**, World`—vain **`Hello`** ladotetaan lihavoituna. Tässä yksittäinen token $$\text{abc}*\text{token}$$ käsitellään makrotokenin argumenttina $$\text{foo}*\text{token}$$, jättäen tokenin $$\text{xyz}\_\text{token}$$ koskemattomaksi ja sen sisältö ladottavaksi nykyisellä kirjasimella.

## Huomautus \expandafter-komennosta ja argumentteja sisältävistä makroista

voit käyttää `\expandafter` makrojen laajentamisen pakottamisessa on hyvä tietää, miten makron laajennus toimii—erityisesti argumentteja ottavien makrojen kohdalla. Ennen kuin TeX voi suorittaa makron—eli lukea ja käsitellä makron määritelmän sisältämiä tokeneita—TeXin täytyy saada makro “valmiiksi suoritettavaksi” tekemällä alkuperäinen makrolaajennusprosessi. Jos makron määritelmä sisältää parametrien käytön (`#1`, `#2`, ... `#9`), makrolaajennusprosessin osa vaatii TeXiä selaamaan syötettä etsiäkseen käyttäjän antamat argumentin/argumenttien muodostavat tokenit: nuo argumenttitokenit imeytyvät (poistuvat) syötteestä. Makrolaajennuksen aikana TeX lukee ja imee syötteestä tokeneita luodakseen pienet tokenilistat, yhden listan per argumentti; nämä tokenilistat sijoitetaan myöhemmin makron runkoon sopivaan kohtaan—kun TeX suorittaa sen. Makrolaajennuksen viimeinen vaihe sisältää sen, että TeX paikantaa muistiin tallennetun makromääritelmän ja järjestää sen sijainnin lähteeksi, josta TeX lukee seuraavan tokenijoukkonsa. Makron suoritus alkaa, kun TeX alkaa lukea ja käsitellä noita tokeneita, syöttäen sisään aiemmin luodut tokenilistat argumenttien tallentamiseksi.

### Myös erotintokenit imeytyvät

Jos alkuperäinen makromääritelmä käytti myös erotimina toimivia tokeneita, TeXin olisi myös verrattava alkuperäistä makromääritelmää käyttäjän kyseisen makron käyttöön (kutsuun), etsiäkseen ja kohdentaakseen erotintokeneita. Kun ne on kohdistettu/löydetty, erotintokenit jätetään myöhemmin huomiotta, koska niiden ainoa tarkoitus on toimia “välimerkkeinä”, auttaen TeXiä poimimaan ja tunnistamaan varsinaiset tokenit, joista kukin argumentti muodostuu.

&#x20;[Osa 1](/latex/fi/syvalliset-artikkelit/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md)   [Osa 2](/latex/fi/syvalliset-artikkelit/22-how-does-expandafter-work-the-meaning-of-expansion.md)   [Osa 3](/latex/fi/syvalliset-artikkelit/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md)   [Osa 4](/latex/fi/syvalliset-artikkelit/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md)   [Osa 5](/latex/fi/syvalliset-artikkelit/17-how-does-expandafter-work-a-detailed-macro-case-study.md)   [Osa 6](/latex/fi/syvalliset-artikkelit/18-how-does-expandafter-work-a-detailed-study-of-consecutive-expandafter-commands.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/fi/syvalliset-artikkelit/18-how-does-expandafter-work-a-detailed-study-of-consecutive-expandafter-commands.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.
