É muito fácil escrever macros que produzam espaço na saída da composição, em locais onde isso não seja desejado nem esperado. Espaços introduzidos por macros são particularmente insidiosos porque eles não se fundem com espaços ao redor da macro (diferentemente de espaços consecutivos que você digita), fazendo com que sua saída possa ter um único espaço inflado, composto de dois ou mais espaços que não se fundiram. E, é claro, sua saída também pode ter um espaço onde nenhum espaço era desejado.
Os espaços são produzidos, dentro de uma macro como em qualquer outro lugar, por caracteres de espaço ou de tabulação, ou por caracteres de final de linha. Há que se lembrar de duas regras básicas ao escrever uma macro: a primeira é que as regras para ignorar espaços ao digitar macros são exatamente as mesmas que se aplicam à digitação de texto comum, e a segunda é que as regras para ignorar espaços não se aplicam aos espaços produzidos enquanto uma macro está sendo obedecida (“expandida”).
Os espaços são ignorados no modo vertical (entre parágrafos), no início de uma linha e depois de um nome de comando. Uma vez que sequências de espaços são colapsadas em um, ‘é como se’ os espaços fossem ignorados se vierem depois de outro espaço. O espaço pode ter significado sintático após certos tipos de argumentos fora de chaves (por exemplo, atribuições de variáveis count e
dimen no Plain TeX) e depois de certas palavras de controle (por exemplo, em \hbox
to
). Assim, temos novamente casos em que ‘é como se’ os espaços estivessem sendo ignorados, quando eles estão meramente trabalhando silenciosamente.
Considere a seguinte macro, adaptada com bastante fidelidade de uma que apareceu no comp.text.tex:
A definição da macro contém cinco espaços:\newcommand{\stline}[1]{ \bigskip \makebox[2cm]{ \textbf{#1} } }
{
do corpo da macro; este espaço será ignorado, não “porque a macro aparece no início de uma linha”, mas sim porque a macro foi criada para operar entre parágrafos
\bigskip
; este espaço será ignorado (enquanto a macro estiver sendo definida) porque vem depois de um nome de comando
{
do argumento obrigatório do \makebox
; mesmo que este espaço apareça inevitavelmente no início de uma linha de saída, ele não será ignorado
}
que fecha o argumento do \textbf
; este espaço não será ignorado, mas pode passar despercebido se o argumento estiver bem dentro dos 2cm
permitidos para ele
}
que fecha o argumento obrigatório do \makebox
;
este espaço não será ignorado
\makebox
e do espaço imediatamente após o mesmo argumento. Ele havia escrito sua macro dessa maneira para enfatizar o significado de suas várias partes; infelizmente, o significado se perdeu bastante no meio dos problemas que a macro causou.
A principal técnica para suprimir espaços é o uso de caracteres %: tudo depois de um % é ignorado, até mesmo o final da linha (para que nem mesmo o final da linha possa contribuir com um espaço indesejado). A técnica secundária é assegurar-se de que o final da linha seja precedido por um nome de comando (como o final da linha se comporta como um espaço, ele será ignorado por vir depois de um nome de comando). Assim, o comando acima seria escrito (por um programador experiente com intenção similar de enfatizar a estrutura):
Foi tomado cuidado para garantir que cada espaço na definição revisada fosse ignorado, para que nenhum aparece na saída. A definição revisada usa um método de precaução, lidando explicitamente com cada final de linha (embora, como descrito acima, um espaço no final da primeira linha da macro seria ignorado no uso real da macro). Esta é a melhor técnica, na verdade — é mais fácil suprimir cegamente os espaços do que analisar ponto a ponto e decidir quais você realmente precisa suprimir. Três técnicas foram usadas para suprimir espaços:\newcommand{\stline}[1]{% \bigskip \makebox[2cm]{% \textbf{#1}\relax }% }
\relax
) é uma instrução nula em muitas circunstâncias (como aqui), mas este uso é desaconselhável — um caractere % teria sido melhor.
Na “vida real”, é claro, os espaços que aparecem nas macros estão muito mais escondidos do que aqueles no exemplo acima. Os espaços mais comuns surgem de finais de linha desprotegidos, e este é um erro que aparece ocasionalmente mesmo em macros escritas pelos programadores mais talentosos.
This question on the Web: http://latex.net.br/faq/FAQ-spinmacro.html
Do you have any question? Ask on: latex.net.br - we love qood questions!