> 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/17-how-does-expandafter-work-a-detailed-macro-case-study.md).

# Miten \expandafter toimii: yksityiskohtainen makrotapaustutkimus

&#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-esimerkki teoksesta The $$\varepsilon\mathrm{\text{-}{\TeX}}$$ Käsikirja

Se $$\varepsilon\mathrm{\text{-}{\TeX}}$$ ladontamoottori johdettiin Knuthin TeX-ohjelmistosta ja sen oli alun perin tarkoitus olla “välivaihe” kohti kehitystä [Uusi ladontajärjestelmä](https://en.wikipedia.org/wiki/New_Typesetting_System) (NTS), kirjoitettu Java-ohjelmointikielellä. $$\varepsilon\mathrm{\text{-}{\TeX}}$$ kehitettiin ensimmäisen kerran 1990-luvun lopulla lisäämään joukko uusia primitiivikomentoja, jotka tarjoavat lisätoiminnallisuutta, jota ei ollut Knuthin alkuperäisessä ohjelmassa. Vaikka $$\varepsilon\mathrm{\text{-}{\TeX}}$$ on saanut säännöllisiä päivityksiä alkuperäisen julkaisunsa jälkeen, sitä ei nykyään käytetä laajalti erillisenä ladontamoottorina, vaikka sen innovaatiot on omaksuttu myöhempiin TeX-sukupolviin: pdfTeXiin, XeTeXiin ja LuaTeXiin.

Se [$$\varepsilon\mathrm{\text{-}{\TeX}}$$ manual](http://mirror.ox.ac.uk/sites/ctan.org/systems/doc/etex/etex_man.pdf) sisältää valaisevan esimerkin makrosta, joka käyttää oivaltavasti `\expandafter`:

```
    \def\foo#1#2{\number#1
    \ifnum#1<#2,
    \expandafter\foo
    \expandafter{\number\numexpr#1+1\expandafter}%
    \expandafter{\number#2\expandafter}%
    \fi}
```

`\foo` toteuttaa silmukointimekanismin siten, että `\foo{7}{13}` tuottaa `7, 8, 9, 10, 11, 12, 13`; kuitenkin, `\foo` ei käytä mitään *muuttujien arvojen asettamista* silmukointiprosessin hallitsemiseksi — mikä tekee siitä mielenkiintoisen makron, jota on syytä tarkastella hieman tarkemmin.

### Taustaa: lausekkeet ja sijoitukset

Tärkeä osa `\foo`’n koodissa on komennon käyttö `\numexpr`, komento neljän toisiinsa liittyvän primitiivin joukosta, jotka esitteli ensimmäisenä $$\varepsilon\mathrm{\text{-}{\TeX}}$$: `\numexpr`, `\dimexpr`, `\glueexpr` ja `\muexpr`. Niiden tarkoituksena on muodostaa niin sanottuja *lausekkeita* joiden avulla voidaan laskea/käsitellä TeX:n arvoja tyypeissä number, dimen, glue tai muglue (tässä järjestyksessä). Kuten The $$\varepsilon\mathrm{\text{-}{\TeX}}$$ Käsikirjassa, tärkeä ominaisuus *lausekkeita* on se, ettei niiden arviointi (laskenta) vaadi TeXiä suorittamaan mitään *sijoituksia*.

Ohjelmointitermein sijoitus on prosessi, jossa muuttujalle asetetaan tietty arvo; esimerkiksi sijoittamalla `\count` rekisteri `99` sisältämään arvon `12345` kautta `\count99=12345`. TeX:n käsittelyn aikana tapahtuu monia muitakin sijoitustyyppejä — esimerkiksi token-rekistereihin sijoitetaan token-sarjoja, boksi-rekistereihin boksi-sisältöä ja niin edelleen.

Sijoituksen suorittamiseksi, kuten `\count99=12345`, TeXin täytyy suorittaa sisäinen koodi, joka toteuttaa `\count` tai minkä tahansa muun primitiivin, joka suorittaa jonkinlaisen sijoituksen. On kuitenkin aikoja, jolloin TeX suorittaa pelkkää *laajennus* ja noina aikoina tällaisia sijoituksia ei suoriteta—*tuossa TeXin käsittelyn vaiheessa*. Tällaisia tilanteita ovat esimerkiksi seuraavat komennot:

* `\edef\command {*token list*}` “laajennetun määritelmän” makronmäärittelykomento, joka laajentaa tokenit *token-luettelossa* ja tallentaa tulokset määritelmäksi `\command`.
* `\write *number* {*token list*}` laajentaa tokenit `*token list*` ja kirjoittaa ne tiedostoon, jota edustaa `*number*`.
* `\directlua {*token list*}` tätä LuaTeXin primitiivikomentoa käytetään Lua-koodin välittämiseen sisäänrakennetulle Lua-tulkille. Kaikki tokenit `*token list*` laajennetaan täysin ennen kuin ne välitetään Lua-tulkille suoritettavaksi.

#### Nopea esimerkki \edef-komennosta

Jos kirjoitamme seuraavat perusmakrot:

```
     \def\mycount{\count99=12345}
     \edef\mymacro{\mycount}
```

`\edef` laajentaa `\mycount` sen osatekijätokeneiksi, mutta ei mene pidemmälle: mikään komento, joka sisältyy `\mymacro` aktivoidaan: eli sijoitus `12345` kohteeseen `\count99` *ei tapahdu tässä vaiheessa*; vasta kun kutsumme `\mymacro` tapahtuu tuo sijoitus, kun TeX suorittaa koodin käsitelläkseen `\count` primitiivin. Kun TeX suorittaa *pelkkiä laajennustoimintoja* kaikki sijoitukset aktivoidaan myöhemmin TeXin käsittelyssä, eivät itse laajennusprosessin aikana.

#### Miksi sijoitukset ovat tässä kiinnostavia?

Kun kirjoitetaan koodia silmukan toteuttamiseksi — missä tahansa ohjelmointikielessä — on tavallista, että on olemassa muuttuja, joka on nimetty toimimaan “silmukkalaskurina”: sitä käytetään ohjaamaan, kuinka monta kertaa silmukka suoritetaan. Silmukointia ohjataan tyypillisesti testaamalla, onko kyseinen silmukkalaskurimuuttuja saavuttanut tietyn arvon — muuttujan arvoa kasvatetaan (tai pienennetään) jokaisella silmukan iteraatiolla. Silmukkalaskurimuuttujan muuttaminen tarkoittaa kuitenkin uuden arvon asettamista sille, mikä TeXissä yleensä vaatii primitiivikomennon `\advance` kasvattamaan (tai pienentämään) arvon, joka on tallennettu `\count` rekisteriin. Kuten olemme nähneet, TeXin puhtaan laajennusprosessin aikana tällaisia sijoituksia (mukaan lukien muuttujien kasvattaminen) ei voi tapahtua: makro `\foo` kiertää tämän rajoituksen oivaltavasti.

### Takaisin \foo-makron selittämiseen

Makro `\foo` pystyy hallitsemaan silmukointiprosessia *ilman* tarvitsematta asettaa arvoja millekään muuttujille: se ohjaa, kuinka usein silmukka tapahtuu, käyttäen laajennuksesta syntyviä tietoja: väliaikaisiin token-luetteloihin tallennettuja arvoja. Käyttämällä tietämystämme TeXin väliaikaisten token-luetteloiden käytöstä (luomisesta) voimme tarkastella tarkemmin, kuinka `\foo` se saavuttaa tuloksensa.

**Muista**: Käymme läpi makron suorittamista sen määritelmän alkuperäisen tekstin jälkeen — joka sisältyy fyysiseen `.tex` tiedostoon — on skannattu (TeX on lukenut sen sisään) ja muunnettu token-luetteloksi, joka edustaa makron määritelmää. Pohjimmiltaan seuraamme TeXin näiden tallennettujen *tokenit* samaan aikaan kun se lukee ja käsittelee tokeneita makron määritelmässä, joka on jossain TeXin muistissa. Kaikki välilyöntimerkit, jotka olivat alun perin läsnä makron määritelmän TeX-koodissa (teksti `.tex` tiedostossa) on joko absorboitu, kun TeX skannasi tuota tekstiä komentojen varalta (välilyönnit päättiminä), tai ne on muunnettu tokeneiksi, kuten pilkun jälkeinen välilyöntimerkki (`,`) kohdassa `\ifnum#1<#2,` joka syntyi rivinvaihtomerkin (`\r`) muuttamisesta välilyönniksi.

Koska TeX-koodi kohdassa `\foo` käyttää useita `\expandafter` komentoja, selvennämme selitystämme lisäämällä alaindeksit jokaiseen `\expandafter`, osoittaen, mihin niistä viittaamme. Lisäksi laajennamme merkintätapaa tokeneille, joita `\expandafter` kohteeseen $$\mathrm{T^i\_1}$$ ja $$\mathrm{T^i\_2}$$, joka esittää tokeneita $$\mathrm{T\_1}$$ ja $$\mathrm{T\_2}$$ kohtaan `\expandafter<sub>i</sub>`: `\expandafter<sub>i</sub>` $$\mathrm{T^i\_1T^i\_2}$$

Tässä on merkintöihin lisätty makrokoodi:

```
    \def\foo#1#2{\number#1
    \ifnum#1<#2,
    \expandafter1\foo
    \expandafter2{\number\numexpr#1+1\expandafter3}%
    \expandafter4{\number#2\expandafter5}%
    \fi}
```

`\foo` alkaa `\number#1` joka käyttää laajenevaa komentoa `\number` muuntaakseen ensimmäisen argumentin arvon ladotuksi esityksekseen. Tämä `\number` komento toimii generoimalla väliaikaisen token-luettelon, joka sisältää merkkitokeneita, jotka edustavat numeerisen arvon yksittäisiä numeroita, jota `\number` se käsittelee. Tuo token-luettelo tulee TeXin seuraavaksi syötekohteeksi. Tässä tuo token-luettelo luetaan ja tokenit tulostetaan ladomaan arvon `#1`.

Seuraavaksi makro suorittaa testin `\ifnum#1<#2` tarkistaakseen, onko argumentin `#1` arvo pienempi kuin argumentiksi annettu arvo kohdassa `#2`. Jos on, pilkku (`,`) -token tulostetaan (ladotaan), ja sitä seuraa jonkin verran väliä, joka syntyy pilkun jälkeisestä rivinvaihtomerkistä luodusta tokenista (`,`). Tuo välilyöntimerkki syntyi alun perin, kun TeX luki tämän rivin tiedostosta `.tex` tiedostossa.

Makro jatkaa käsittelemällä tämän seuraavan koodiosan, joka on sen toiminnan ydin:

```
    \expandafter1\foo
    \expandafter2{\number\numexpr#1+1\expandafter3}%
    \expandafter4{\number#2\expandafter5}%
    \fi}
```

Pohjimmiltaan tämä koodi tuottaa sarjan väliaikaisia token-luetteloita, jotka johtavat useisiin kutsuihin `\foo` makroon, ja päättyy, kun if-testi `\ifnum#1<#2` ei enää ole tosi. Mutta *miten* on silmukointi hallittua, koska mitään sijoituksia ei tehdä: missä on “silmukkalaskuri”?

Aloitetaan tarkastelemalla koodia `\expandafter<sub>1</sub>\foo\expandafter<sub>2</sub>`. Huomaa, että käytämme alaindeksimerkintää `<sub>token</sub>` (tai `<sub>(token)</sub>`) muistuttaaksemme itseämme siitä, että tässä TeX lukee/käsittelee numeerisia (kokonaisluku) token-arvoja.

Tässä meillä on seuraavat tokenit syötteenä `\expandafter<sub>1</sub>`:

* $$\mathrm{T^1\_1} =$$`\foo<sub>token</sub>` joka luetaan sisään ja tallennetaan myöhempää *uudelleensijoitusta* varten takaisin syötteeseen
* $$\mathrm{T^1\_2} =$$`\expandafter<sub>2 (token)</sub>` joka laajennetaan

Tiedostoissa `\expandafter<sub>2</sub>` meillä on:

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

**Huom:**`\number` on laajeneva komento, jonka tarkoitus on “muuntaa tokeneiksi”: eli muuntaa numeerinen määrä sarjaksi merkkitokeneita, jotka edustavat kyseistä määrää. Kun `\number` laajennetaan, ensimmäinen asia, jonka TeX tekee, on skannata syöte etsien kokonaislukuja: prosessi, joka laukaisee lisälaajennuksen.

**Tarinan ydin:** Tässä, `\number` toimii *lausekkeen* `\numexpr#1+1` joka laskee arvon `#1+1`. Tuo laskennan tulos käsitellään `\number` muuntaakseen sen väliaikaiseksi token-luetteloksi, joka sisältää merkkitokeneita ja edustaa arvon `#1 + 1`. Tuo väliaikainen token-luettelo, jonka luo `\number`, luetaan lopulta sisään toisen `\foo`. Sen sijaan, että silmukkalaskuria kasvatettaisiin (kautta `\advance` ja sijoituksen), käytettäessä `\numexpr` luodaan uusi arvo, mutta ilman että sijoitus on tarpeen. Tämän mekanismin avulla silmukkaa hallitseva muuttuja (`\foo`’n parametri `#1`) kasvatetaan, ja silmukan iteraatiota hallitaan ja se päätetään: varsin nerokasta!

Seuraavaksi, `\expandafter<sub>3</sub>` käsitellään, jolloin saadaan:

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

Tiedostoissa `\expandafter<sub>4</sub>` meillä on:

* $$\mathrm{T^4\_1} =$$`{<sub>token</sub>` joka tallennetaan myöhempää *uudelleensijoitusta* varten takaisin syötteeseen
* $$\mathrm{T^4\_2} =$$`\number<sub>token</sub>` joka laajennetaan ja muuntaa `#2` toiseksi väliaikaiseksi token-luetteloksi.

Lopuksi,`\expandafter<sub>5</sub>` laajennetaan:

* $$\mathrm{T^5\_1} =$$`}<sub>token</sub>` joka tallennetaan myöhempää *uudelleensijoitusta* varten takaisin syötteeseen
* $$\mathrm{T^5\_2} =$$`\fi<sub>token</sub>`, joka on laajeneva komento.

  Laajennus `\fi` käytännössä päättää `\ifnum` ja käytännössä sulkee tämän makron iteraation. TeX viimeistelee nyt kaikkien monien `\expandafter` komentojen väliaikaisesti tallentamien tokenien uudelleenlisäyksen: tämä tuottaa sarjan yksitokenisia token-luetteloita, jotka syntyvät kunkin `\expandafter`komennon vaikutuksesta. Lisäksi TeX on myös luonut token-luetteloita toiminnan kautta `\number`.

### Token-luetteloiden kokoaminen

Pohjimmiltaan `\foo` makro tuottaa token-luetteloiden sarjan: voit ajatella `\foo` sitä token-luetteloiden “valmistuslaitoksena”. TeX lukee nuo token-luettelot, ja niistä tulee seuraavat syötelähteet. Oivaltava osa sisältyy yhteen aiemmista `\foo`:

```
    \expandafter1\foo\expandafter2
```

joiden kautta `\foo` järjestää kutsuvansa itseään uudelleen, mutta eri argumenteilla, jotka on tallennettu token-luetteloihin, joita luo `\number`. Jotta nämä token-luettelot käyttäytyisivät yhdessä kuin makrokutsu, aaltosulkeet `{` ja `}` on kaikki tallennettu ja lisätty uudelleen syötteeseen (yksitokenisina luetteloina) toimintojen `\expandafter` komentojen kautta.

![\foo-makron tuottamat token-luettelot](/files/d1e57bff07a5db4f30b58407d3f9cebd7056fb49)

&#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/17-how-does-expandafter-work-a-detailed-macro-case-study.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.
