
¿Por qué es \setlength
ineficaz dentro de un tabular
entorno? Aquí hay un MWE:
\documentclass{article}
\newlength{\globallength}
\newlength{\locallength}
\begin{document}
\setlength{\globallength}{10pt}%
\begin{tabular}{l}
\setlength{\locallength}{10pt}%
\hspace*{10pt}. \\
\hspace*{\globallength}. \\
\hspace*{\locallength}. \\
\hspace*{0pt}. \\
\end{tabular}
\end{document}
Mientras que los dos primeros puntos están bien alineados, el tercero es diferente y se comporta como si \locallength
lo estuviera 0pt
. ¿Por qué es eso y qué puedo hacer? Quiero usarlo \setwidth
dentro del tabular
entorno, por lo que establecer la longitud fuera del entorno no es realmente una opción.
Respuesta1
Las celdas de alineación se procesan dentro de un grupo implícito, por lo que las asignaciones locales a las variables se deshacen cuando finaliza el grupo.
La definición del núcleo de \setlength
es
% latex.ltx, line 2181:
\def\setlength#1#2{#1 #2\relax}
es por eso que\global\setlength
parecetrabajar. Por otro lado, la definición de \settowidth
es
% latex.ltx, line 2187:
\def\settowidth {\@settodim\wd}
y la definición de \@settodim
es
% latex.ltx, line 2183:
\def\@settodim#1#2#3{\setbox\@tempboxa\hbox{{#3}}#2#1\@tempboxa
\setbox\@tempboxa\box\voidb@x}
Así \global\settowidth{\locallength}{abc}
se convertiría
\global\setbox\@tempboxa\hbox{{abc}}\locallength\wd\@tempboxa\setbox\@tempboxa\box\voidb@x
lo cual, por supuesto, es ineficaz para realizar una asignación global a \locallength
.
Sí, \settowidth{\global\locallength}{abc}
funcionaría, pero es sólo por casualidad.
No hay soporte en LaTeX para asignaciones de dimensión/salto global y debe confiar en comandos de nivel inferior. Entonces, una forma más segura es definir nuevos comandos:
\makeatletter
\newlength\local@length@for@global
\newcommand\gsetlength[2]{%
\setlength{\local@length@for@global}{#2}%
\global#1\local@length@for@global
}
\newcommand{\gsettowidth}[2]{%
\settowidth{\local@length@for@global}{#2}%
\global#1\local@length@for@global
}
\makeatother
y de manera similar para \gsettoheight
y \gsettodepth
si es necesario.
Esto funcionará incluso si calc
está cargado y no explota ninguna implementación particular de los comandos "locales".
Respuesta2
Ambos \global\setlength{\locallength}{10pt}
parecen \setlength{\global\locallength}{10pt}
funcionar, pero no tengo idea de por qué sería necesario.
https://tex.stackexchange.com/a/210598/30810Me hizo probarlo y el comentario de @ChristianHupfer explica por qué.
En mi documento más extenso, \global\settowidth{...}
no funcionó; \settowidth{\global...}
hizo.