Na documentação de l3skip
's \dim_eval:n
é avisado
Isto [...] requer terminação adequada se usado em uma atribuição no estilo TeX, pois não é um ⟨dimensão interna⟩.
Avisos análogos podem ser encontrados nas descrições para \skip_eval:n
e \muskip_eval:n
com ⟨cola interna⟩ e ⟨caneca interna⟩ no lugar de ⟨dimensão interna⟩.
Estou bastante familiarizado com o tratamento de saltos e dimensões no TeX, mas nunca antes encontrei a expressãodimensão interna. No TeXbook não consegui encontrar nenhuma explicação para a frase fora da notação gramatical bastante técnica do capítulo 24, que certamente contém todas as informações necessárias, mas não me ajudou muito.
Então, o que exatamente é umdimensão interna? Quais são os outros tipos de dimensões? (Dimensões externas?) Quais são os exemplos de comportamento diferente dos dois (como aquele a que alude o aviso acima)?
Responder1
Abordarei primeiro o conceito geral do TeX e depois por que ele é importante na documentação dessas expl3
funções.
Uma dimensão interna (ou contagem interna ou qualquer outra coisa) é algo que foi analisado pelo TeX e agora está armazenado na forma correta. Assim, o TeX 'sabe' que uma dimensão internaéuma dimensão válida e não precisa 'procurar' nenhum material adicional. Em contraste, uma dimensão externa (etc.) é algo composto de tokens discretos e teria que ser reanalisado pelo TeX para ser usado. Assim quando nósescrever 12.0pt
, estamos dando umexternorepresentação (o TeX teria que analisá-la para saber que é uma dimensão válida), mas depois
\newdimen\mydimen
\mydimen=12pt %
Eu posso usar \mydimen
e o TeX usanãoprecisa analisar qualquer coisa: \mydimen
possui uma dimensão interna.
Por que isso é importante? É tudo uma questão de regras de análise do TeX, em particular que o TeX permite um espaço final opcional após dimensões, inteiros,etc., e mais importante ainda, com uma representação externa, o TeX não para de analisar até encontrar algo que não “se encaixe”. Por exemplo
\def\foo{123}
\newcount\fooint
\fooint=123 %
\newcount\testint
%%%
\testint=\foo 456 %
\showthe\testint
\testint=\fooint 456 %
\showthe\testint
você verá que o primeiro caso dá o resultado errado: temos uma macro que simplesmente se expande para 123
, e o TeX continua procurando por um número inteiro até atingirmos o espaço opcional. Em contraste, com uma representação de contagem interna, não há questão de análise:\fooint
é 123
.
O ponto principal é que uma representação interna é “mais segura” de usar (além de mais rápida): nunca há dúvida de onde ela termina.
Como isso se relaciona expl3
? Algo como \dim_eval:n
é usado para pegar uma expressão e transformá-la em uma dimensão. Contudo, acaba por ser conveniente permitir que também seja apenas tipografado, armazenado por expansão numa macro ( tl
),etc.Para fazer isso, temos que providenciar para que a avaliação resulte em umexternorepresentação, não umainternoum. Isso significa que essas funções se comportam como armazenar um valor como uma macro: você tem que observar o encerramento.
Para todo expl3
uso 'puro' isso não é um problema, pois temos a terminação correta nos lugares certos. Mas se você misturar essas funções com programação TeX mais clássica, você precisa saber como elas se comportarão. Oresposta por egregmostra isso muito bem.
Para quem quer os detalhes do TeX, \dim_eval:n
é em termos primitivos
\the\dimexpr #1\relax
enquanto se quisermos acabar com uma representação interna, só queremos
\dimexpr #1\relax
No entanto, isso não pode ser usado na composição tipográfica ou (com sucesso) dentro de uma x
expansão -type, portanto, não é adequado para a definição que desejamos.
Responder2
Considere o seguinte exemplo
\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\cs_set_eq:NN \dimeval \dim_eval:n
\ExplSyntaxOff
\newlength{\mylen}
\begin{document}
Do an assignment \mylen=\dimeval{3pt+1cm} plus something else.
\end{document}
o que gera um erro
! Missing number, treated as zero.
<to be read again>
s
l.12 ...assignment \mylen=\dimeval{3pt+1cm} plus s
omething else.
Isto é precisamente o que é referido em interface3
.
An <internal dimension>
é qualquer \dimen
registro ou registro interno que armazena um comprimento (rígido), como \parindent
; com extensões e-TeX, também \dimexpr
é uma instância de <internal dimension>
.
Outro fato importante é que \newlength
aloca um \skip
registro, então o TeX irá aguardar plus
as minus
especificações; isso não ocorre quando \setlength
é usado, porque a macro fornece a \relax
terminação adequada.