> 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/overleaf-learn-latex-pt/mais-topicos/24-how-tex-macros-actually-work-part-6.md).

# Como é que as macros TeX funcionam realmente: Parte 6

[Parte 1](/latex/overleaf-learn-latex-pt/mais-topicos/19-how-tex-macros-actually-work-part-1.md) [Parte 2](/latex/overleaf-learn-latex-pt/mais-topicos/20-how-tex-macros-actually-work-part-2.md) [Parte 3](/latex/overleaf-learn-latex-pt/mais-topicos/21-how-tex-macros-actually-work-part-3.md) [Parte 4](/latex/overleaf-learn-latex-pt/mais-topicos/22-how-tex-macros-actually-work-part-4.md) [Parte 5](/latex/overleaf-learn-latex-pt/mais-topicos/23-how-tex-macros-actually-work-part-5.md) [Parte 6](/latex/overleaf-learn-latex-pt/mais-topicos/24-how-tex-macros-actually-work-part-6.md)

## Introdução e visão geral: A história até agora

Ao longo das 5 partes anteriores desta série, vimos:

* como o TeX lê os caracteres num ficheiro de entrada e usa códigos de categoria para reconhecer diferentes “classes” de caracteres e, subsequentemente, convertê-los em tokens de caracteres e tokens de comando;
* que uma macro é, na prática, composta por quatro secções:

```
<primitiva de macro do TeX><nome da macro><texto de parâmetros>{<texto de substituição>}
```

onde:

* `<primitiva de macro do TeX>` = uma das `\def`, `\edef`, `\gdef` ou `\xdef`;
* `<nome da macro>`= o nome da sua macro, como por exemplo `\foo`;
* `<texto de parâmetros>` pode ser “nulo” (não presente) ou pode ser uma cadeia de tokens delimitadores e tokens de parâmetros da macro;
* `<texto de substituição>` é o corpo real da sua macro: a secção que é “executada” (expandida) quando chama a macro.
* como a `<texto de parâmetros>` secção pode conter uma vasta gama de tokens e que o TeX usa esta secção como um “modelo de tokens” para corresponder uma chamada de macro à sua definição original e determinar os argumentos usados com a macro — e como o TeX espera que o uso que faz de uma macro corresponda à sua definição original;
* que, no interior do TeX, uma definição de macro é armazenada como uma sequência contínua de tokens que representam as `<texto de parâmetros>` e `<texto de substituição>` secções.

Quando usa um comando de macro, o TeX verifica primeiro se este aceita parâmetros. Se sim, o TeX tem então de identificar os *argumentos* que estão a ser usados na sua chamada de macro. O TeX tem de testar a sua chamada de macro em relação à definição de “modelo de tokens” que guardou na memória. Especificamente, o TeX usa a definição interna (armazenada) da `<texto de parâmetros>` secção como o modelo através do qual pode identificar *tokens* que são os argumentos reais, e que *tokens* estão apenas ali para atuar como delimitadores.

## O significado da expansão de macros

Agora, finalmente, estamos prontos para avançar para o tema mais importante: como o TeX processa argumentos de macros e executa realmente a macro: um processo a que o TeX chama *expansão de macros*.

### Mas primeiro, um breve exemplo: algo estranho?

Para “enquadrar” a explicação do mecanismo pelo qual o TeX processa macros e os respetivos argumentos, vamos usar um breve exemplo para indicar as questões que precisamos de considerar.

#### Os argumentos são primeiro convertidos em tokens

O exemplo seguinte baseia-se num discutido nas páginas 114–5 de [The Advanced TeXbook](https://www.amazon.co.uk/Advanced-Texbook-David-Salomon/dp/0387945563) escrito por David Salomon. Foi escolhido porque encapsula muito bem as ideias centrais numa macro TeX muito curta.

Durante as operações normais do TeX/LaTeX, o `$` sinal tem o código de categoria 3 (“math shift”), que coloca o TeX dentro/fora do modo matemático em linha (`$...$`) ou do modo matemático em destaque (`$$...$$`) — claro, o LaTeX usa `\(..\)` e `\[..\]` para os mesmos fins.

Suponha que queremos uma macro que altera o código de categoria de um `$` sinal para, por exemplo, 11, para que o possamos compor como qualquer carácter normal. Podemos usar o comando primitivo do TeX `\catcode` e a nossa primeira tentativa de uma macro dessas, `\docat`, poderia ser

```
\def\docat #1{\catcode`\$=11 #1}
```

No entanto, quando tentamos usá-la, assim

```
\begin{document}
\def\docat #1{\catcode`\$=11 #1}
I paid \docat{$90} for that book.
\end{document}
```

esperamos que o TeX componha `I paid $90 for that book.` mas falha com uma mensagem de erro:

```
! Missing $ inserted.
<inserted text>
                $
<para ser lido de novo>
                   \par
l.7
```

Pelo erro, parece que o `$` usado no argumento da nossa macro ainda está a fazer o TeX compor matemática; claramente, o TeX *não* alterou o código de categoria do `$` usado no argumento da nossa macro (`$90`). A questão é *porquê* porque é que o TeX não alterou o código de categoria de `$` para 11 e o compôs como um carácter normal? A resposta curta é que o TeX primeiro converte os argumentos da macro em tokens **antes de** e depois alimenta a lista de tokens da `<texto de substituição>`— mas veremos os mecanismos subjacentes com muito mais detalhe.

O que precisamos de recordar é que a nossa noção de o TeX usar texto/caracteres só é relevante para o conteúdo do ficheiro que o TeX está a ler: assim que o TeX tiver lido quaisquer caracteres, estamos no mundo dos *tokens*. As chamadas de macro do TeX trabalham com *tokens*, e não com a *representação escrita/em texto* dos comandos TeX/LaTeX — isto ficará mais claro à medida que avançarmos no exemplo.

Inicialmente, poderíamos pensar que o nosso uso da `\docat` macro em `I paid \docat{$90} for that book.` é o mesmo que escrever diretamente o código TeX (ou LaTeX) equivalente — como o seguinte, que *não* funciona:

```
\begin{document}
I paid \catcode`\$=11 $90 for that book.
\end{document}
```

![Algum código TeX a correr no Overleaf](/files/f182dd553954844af1da30c8aeefe7582a4bfb8e)

No entanto, como vimos acima, a forma como o TeX processa argumentos de macros produz um resultado (`! Missing $ inserted.`) que é bastante diferente de escrever o código TeX: agora vamos explorar *porquê* o que acontece.

### Macros e argumentos como listas de tokens

Para compreender totalmente o comportamento da `\docat` macro, e do seu argumento (`$90`), e por que falha, precisamos novamente de visualizar a definição da `\docat` macro e quaisquer argumentos usados (quando \docat é chamada) como *listas de tokens*, e não como uma sequência de caracteres.

À medida que o TeX percorre o seu texto de entrada, reconheceria `\docat` como um comando de macro; depois disso, verifica se aceita parâmetros — a forma como o TeX faz isso é explicada na secção seguinte para leitores interessados nos pormenores.

#### Para quem gosta dos pormenores...

Depois de a macro ser chamada, o TeX verifica se o primeiro token (na lista de tokens da definição armazenada da macro) é o **correspondência final** token: se assim for, o TeX pode ter a certeza de que a macro não aceita quaisquer parâmetros.

**Um exemplo**

Os diagramas de listas de nós seguintes comparam as listas de tokens de duas macros:

* `\def\foo A#1B{#1}`: esta tem `<texto de parâmetros>` de `A#1B`, consequentemente o **correspondência final** token é **contém** o primeiro token, por isso o TeX avançaria para procurar parâmetros;
* `\def\foo{X}`: esta não tem uma `<texto de parâmetros>` secção, consequentemente o **correspondência final** token é o primeiro na lista de tokens e o TeX sabe que não deve procurar quaisquer parâmetros.

![Como o TeX verifica se uma macro aceita parâmetros](/files/7af3bf61021dfa0cefbadd69a455784330617a74)

## Rumo ao “Grande Final”: expansão

Recordemo-nos da questão: porque é que a seguinte macro não funcionou; ou seja, porque é que o TeX não altera o código de categoria de quaisquer `$` sinais usados no argumento da `\docat` macro, como por exemplo `\docat{$90}`?

```
\begin{document}
\def\docat #1{\catcode`\$=11 #1}
I paid \docat{$90} for that book.
\end{document}
```

Como explicado acima, quando o TeX percorre a sua entrada e reconhece um comando de macro — num momento em que o TeX se vai preparar para o executar — o TeX verifica primeiro se essa macro aceita quaisquer parâmetros. Se sim, o TeX terá de continuar a analisar o ficheiro de entrada para identificar os *argumentos* que o utilizador forneceu para esta chamada específica de macro: o TeX tem de fazer isto **antes de** antes de poder chamar o código real da macro. Claramente, o TeX precisa de determinar os dados que o utilizador pretende fornecer à macro.

Para identificar os argumentos presentes na entrada (a chamada de macro do utilizador), o TeX será guiado pela definição dessa macro armazenada internamente: especificamente, a `<texto de parâmetros>` secção da definição armazenada da macro (lista de tokens) — que fornece uma espécie de “modelo de tokens”. Usando esse “modelo de tokens”, o TeX tem de determinar quais *tokens* na chamada de macro do utilizador são apenas *delimitadores* (essencialmente “pontuação”) e quais *tokens* fazem parte de um *argumento*. É quando o TeX encontra um **parâmetro de correspondência** token na definição armazenada da macro `<texto de parâmetros>` secção (“modelo de tokens”) que sabe começar a formar uma *lista de tokens* para esse argumento em particular.

Assim que o TeX reconhece a necessidade de identificar o argumento do utilizador, o TeX analisa a entrada para gerar tokens e verifica-os cuidadosamente, token a token, em relação à definição armazenada da macro. O TeX continua a reunir tokens para um argumento até detetar um token que seja realmente um delimitador, ou se detetar o **correspondência final** token: em qualquer dos casos, o TeX sabe então que é hora de parar de procurar tokens que fazem parte desse argumento.

### Porque a macro \docat falhou

Como foi referido, *antes de* O TeX, para chamar efetivamente uma macro, tem de identificar e preparar quaisquer argumentos que vão ser usados com essa macro. No entanto, para identificar o(s) argumento(s), pronto(s) a serem introduzido(s) na macro, o TeX tem de gerar cada argumento como uma *lista de tokens*: e essa é a razão do `\docat`falhanço de

No nosso exemplo, fornecemos `\docat` a com um argumento de `$90` mas esse argumento é primeiro *convertido numa lista de tokens* à medida que o TeX analisa a chamada da macro — o argumento é convertido em tokens *antes de* antes de a macro ser realmente chamada. Aqui, para o argumento `$90`, o TeX vai gerar três tokens de carácter: um token para cada um de `$`, `9` e `0`.

O gráfico seguinte mostra a lista de tokens gerada para o argumento `$90`, antes de ser introduzida no corpo da `\docat` macro:

![Lista de tokens do TeX gerada para um argumento de macro](/files/54582172a8c5fce72103efe39393e756ec8db9c5)

No gráfico acima podemos ver claramente que a lista de tokens do argumento contém o `$` como um token de carácter baseado num código de categoria 3.

Como vimos nas Partes 1 a 3, os tokens de carácter são criados usando os valores do código de categoria *em vigor no momento em que o carácter é*lido — ou seja, no momento em que a lista de tokens do argumento é criada (transformada em tokens). No momento em que os argumentos estão a ser tokenizados, a `\docat` macro ainda não foi executada, pelo que a alteração do código de categoria que colocámos na chamada da macro (``\catcode`\$=11``) *não* não afeta os códigos de categoria usados para gerar os tokens do argumento.

Depois de o TeX ter gerado uma lista de tokens que representa o argumento de `$90`, esses três tokens de carácter são introduzidos na macro real `<texto de substituição>`. No entanto, isso resulta na `$` a ser introduzido como um *token de carácter* criado usando o código de categoria 3: “math on” e vimos que, uma vez formado um token de carácter, o código de categoria associado é permanente. O `$` é *contém* introduzido na macro *não como um carácter*, mas como um *token de carácter* baseado no `$` que tem código de categoria 3.

### Executar \docat: expansão de macros

O TeX refere-se ao processo de “executar” uma macro como *expansão de macros*; um termo que, na opinião deste autor, é um pouco confuso, mas é a terminologia aceite, por isso continuaremos a usá-la.

#### O verdadeiro significado da expansão de macros

Depois de o TeX detetar o `\docat` comando na entrada do utilizador, analisa os argumentos e gera uma lista de tokens para o seu argumento(`$90`). Para executar (expandir) a macro, o TeX desvia o olhar do ficheiro de entrada do utilizador e começa a ler os tokens contidos `\docat`’s `<texto de substituição>` na lista de tokens armazenada na memória do TeX.

À medida que o TeX processa `\docat`a definição de`**catcode**`, ``**`**``, `**\$**`, `**=**`, `**1**`, `**1**`, `**#1**`).

O gráfico seguinte mostra o processo de expansão da `\docat` macro: o TeX deixa de obter tokens do ficheiro de entrada e começa a ler tokens da `<texto de substituição>` secção da `\docat` definição da macro armazenada na memória. O TeX prossegue para executar esses tokens pré-preparados até ver um **parâmetro de saída** token que instrui o TeX a ler (“injetar”) e a “executar” os tokens do argumento neste ponto. No nosso exemplo, são três tokens de carácter que representam `$90` e isso resulta num erro porque o token de carácter pré-preparado para `$` tem código de categoria 3. Como estamos a lidar com tokens de carácter, e não com caracteres, o `$` não é afetado pela alteração anterior do código de categoria causada pelos tokens em ``\catcode`\$=11``.

![Mostrando o processo de expansão da macro \docat](/files/ae5421b3d7f9fc29f6a2d4d2a973c75a5834f62f)

Depois de o TeX ter processado os tokens que representam ``\catcode`\$=11``, a alteração do código de categoria para `$` estará agora em vigor. O TeX encontra então o “token especial” chamado **parâmetro de saída** que diz ao TeX para **inserem** a lista de tokens do argumento. No entanto, essa lista de tokens é de três caracteres *tokens*, sendo o primeiro um token para um `$` com um código de categoria 3 (“math on”) atribuído: a alteração anterior do código de categoria dentro da macro não pode afetar este token de carácter, pelo que o TeX trata esse token como um sinal para iniciar o processamento matemático, o que faz com que a macro falhe.

### Pode a macro \docat ser corrigida?

Pelas discussões acima, é claro que quaisquer caracteres que apareçam nos argumentos de macro são tokenizados usando os códigos de categoria em vigor no momento em que a tokenização ocorre — que, no nosso exemplo, é *sempre* antes de a `<texto de substituição>` do `\docat` macro ser efetivamente executada. Então, como podemos garantir que os argumentos de uma macro tenham os seus códigos de categoria alterados?

Uma forma é modificar `\docat` para ser uma macro sem parâmetros que apenas faz a alteração do código de categoria — não tem quaisquer argumentos para tokenizar. Em seguida, usamos uma segunda macro, `\getarg`, que aceita um único parâmetro, e fazemos com que essa macro tenha o seu argumento tokenizado quando o código de categoria apropriado para `$` estiver em vigor.

```
\begin{document}
\def\docat{\catcode`\$=11 \getarg} % Sem parâmetros, chama uma segunda macro \getarg
\def\getarg#1{#1} %1 parâmetro cujo argumento será tokenizado
Agora pode executá-la assim e ela funcionará:

I paid \docat{$90} for that book.
\end{document}
```

Quando usamos a nossa nova versão de `\docat` (assim `\docat{$90}`) *parece* como se o `$90` ainda estivesse a ser usado como argumento para a `\docat` macro. No entanto, como discutido acima, quando o TeX deteta `\docat` na entrada, verifica se tem quaisquer argumentos: agora não tem, por isso o TeX prossegue para o executar (expandir). A expansão de `\docat` é a sequência de tokens `**catcode**`, ``**`**``, `**\$**`, `**=**`, `**1**`, `**1**`, `**space**`, `**getarg**` e isto ocorre *antes de* o TeX começa a ler (tokenizar) os caracteres seguintes contidos no ficheiro de entrada — ou seja, o grupo `{$90}`. Lembre-se de que, quando o TeX expande uma macro, obtém a sua próxima entrada lendo os tokens contidos na lista de tokens da definição dessa macro; ou seja, a partir da sua `<texto de substituição>` secção armazenada na memória.

O TeX processará, e executará, a expansão de `\docat` e detetará o *token* **`getarg`**, reconhecendo-o como um token que representa um comando que aceita parâmetros. Neste ponto, o TeX vai analisar o ficheiro de entrada para **`getarg`**&#x6F; argumento de `{$90}`: os caracteres: `\docat`. Como é habitual, estes são tokenizados, mas como o TeX leu e processou a expansão de `$90` , os caracteres `$` são tokenizados quando o código de categoria de`<texto de substituição>`A definição ( `\getarg` ) de `#1` é simplesmente `$` o que significa compor o argumento fornecido, e é isso que acontece, resultando num

## Observações finais: a história em nós

A sequência de eventos resultante de reescrever `\docat` para usar a macro `\getarg` está contida no seguinte diagrama anotado de lista de nós, que mostra o processo de expansão da macro `\docat`. Os leitores que desejem estudar cuidadosamente este diagrama podem descarregar o gráfico como um ficheiro [PDF](https://assets.ctfassets.net/nrgyaltdicpt/7MOBdavza4WxAEQGISEEht/cabe5097d9063a6415bc553cd38237e6/newdocatexpansion.pdf) ou [SVG](https://images.ctfassets.net/nrgyaltdicpt/2FIqqVRXjakdAzTpZsV0m9/10ccc1353741d42d3df18f1692d8aa84/newdocatexpansion--plain.svg) para uso offline.

![Mostrando o processo de expansão da macro \docat modificada e da macro \getarg](/files/f7655df8317035eab76513cff475ca12440d92db)

[Parte 1](/latex/overleaf-learn-latex-pt/mais-topicos/19-how-tex-macros-actually-work-part-1.md) [Parte 2](/latex/overleaf-learn-latex-pt/mais-topicos/20-how-tex-macros-actually-work-part-2.md) [Parte 3](/latex/overleaf-learn-latex-pt/mais-topicos/21-how-tex-macros-actually-work-part-3.md) [Parte 4](/latex/overleaf-learn-latex-pt/mais-topicos/22-how-tex-macros-actually-work-part-4.md) [Parte 5](/latex/overleaf-learn-latex-pt/mais-topicos/23-how-tex-macros-actually-work-part-5.md) [Parte 6](/latex/overleaf-learn-latex-pt/mais-topicos/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/overleaf-learn-latex-pt/mais-topicos/24-how-tex-macros-actually-work-part-6.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.
