Se necesita un experto en TeX: ¿cómo establecer el ancho (óptimo)?

Se necesita un experto en TeX: ¿cómo establecer el ancho (óptimo)?

Hay un problema que he estado intentando resolver durante un tiempo pero hasta ahora sin éxito. Hasta donde yo sé, TeX es muy bueno para dividir adecuadamente líneas de texto con respecto a un ancho de contenedor fijo. Lo que intento lograr es diferente: me gustaría poder calcular un ancho "óptimo" para un contenido determinado.

Por óptimo quiero decir que hay una restricción subyacente. Por ejemplo, me gustaría poder escribir un comando \settooptimalwidth#1#2#3que requiera:

  • #1 como longitud para ajustar
  • #2 como ancho máximo
  • #3 como contenido

Si el número 3 es muy corto (más corto que el número 2), simplemente haría lo mismo que \settowidth. Si el n.° 3 es más largo que el n.° 2, dividiría el n.° 3 en líneas como si estuviera colocado en una minicaja y (esa es la parte complicada) devolvería la longitud de las líneas más anchas entre ellas. Supongo aquí que el algoritmo de salto de línea no utiliza la alineación "justificada" habitual, sino que está irregular hacia la izquierda/derecha o centrada (de lo contrario, el problema es irrelevante).

Permítanme darles algunos ejemplos en los que un comando de este tipo sería útil: * ajustar automáticamente el ancho de una columna de matriz cuyo contenido se va a centrar, con posibles saltos de línea, * algún tipo de entorno de verso alineado a la derecha con un marco elegante. Si el verso es muy corto entonces el marco sería pequeño. Si el verso es muy largo, dividiría el texto a un ancho "óptimo".

Creo que el camino a seguir es con \unhbox, pero no estoy seguro de cómo usarlo. Cualquier ayuda sería apreciada.

Respuesta1

Como escribió David Carlisle anteriormente, el paquete varwidthes el camino a seguir. Proporciona el entorno varwidthque hace lo que estaba pidiendo. Aquí hay un ejemplo mínimo para dibujar texto sobre un fondo sombreado degradado usando un proyector.

\documentclass{beamer}

\usepackage{calc,varwidth}

\colorlet{titleshadeA}{white!30!orange}
\colorlet{titleshadeB}{red!30!black}

\newlength\shadeboxwidth
\newlength\shadeboxheight
\newlength\shadeboxsep
\newcommand\shadebox[4]{%
  \setlength\shadeboxsep{#3}%
  \settowidth\shadeboxwidth{\begin{varwidth}{\textwidth}#4\end{varwidth}}%
  \advance\shadeboxwidth by 2\shadeboxsep%
  \settototalheight\shadeboxheight{\begin{varwidth}{\textwidth}#4\end{varwidth}}%
  \advance\shadeboxheight by 2\shadeboxsep%
  \pgfdeclarehorizontalshading{titleshade}{\shadeboxheight}{%
    color(0mm)=(#1);%
    color(\shadeboxwidth)=(#2)%
  }%
  \rlap{\pgfuseshading{titleshade}}%
  \begin{beamercolorbox}[sep=\shadeboxsep,wd=\shadeboxwidth,ht=\shadeboxheight,dp=0pt]{postit}%
    \color{white}\begin{varwidth}{\textwidth}\raggedleft#4\end{varwidth}%
  \end{beamercolorbox}%
}

\begin{document}
\begin{frame}
\strut\hfill\shadebox{titleshadeA}{titleshadeB}{1ex}{\raggedleft\LARGE Something short}\\
\strut\hfill\shadebox{titleshadeA}{titleshadeB}{1ex}{\raggedleft\LARGE Something very long which will be broken and aligned to the right}\bigskip
\hrule height 2pt\bigskip
Notice how it doesnt spawn the total text width (see the black rule above), but instead adjusts itself to the longest text line of the content.
\end{frame}
\end{document}

información relacionada