TeX-Experte gesucht: Wie kann ich die (optimale) Breite festlegen?

TeX-Experte gesucht: Wie kann ich die (optimale) Breite festlegen?

es gibt ein Problem, das ich schon seit einiger Zeit zu lösen versuche, bisher aber ohne Erfolg. Soweit ich weiß, ist TeX sehr gut darin, Textzeilen in Bezug auf eine feste Containerbreite angemessen umzubrechen. Was ich erreichen möchte, ist etwas anderes: Ich möchte in der Lage sein, eine „optimale“ Breite für einen bestimmten Inhalt zu berechnen.

Mit optimal meine ich, dass eine zugrunde liegende Einschränkung vorliegt. Ich möchte beispielsweise einen Befehl schreiben können, \settooptimalwidth#1#2#3der Folgendes erfordert:

  • #1 als Länge zum Anpassen
  • #2 als maximale Breite
  • #3 als Inhalt

Wenn #3 sehr kurz ist (kürzer als #2), würde es einfach dasselbe tun wie \settowidth. Wenn #3 länger als #2 ist, würde es #3 in Zeilen aufteilen, als ob es in eine Minibox gesetzt wäre, und (das ist der schwierige Teil) die Länge der breitesten Zeilen unter diesen zurückgeben. Ich gehe hier davon aus, dass der Zeilenumbruchalgorithmus nicht die übliche „Blocksatz“-Ausrichtung verwendet, sondern stattdessen links/rechts oder zentriert (sonst ist das Problem irrelevant).

Hier sind einige Beispiele, bei denen ein solcher Befehl nützlich wäre: * automatische Anpassung der Breite einer Array-Spalte, deren Inhalt zentriert werden soll, mit möglichem Zeilenumbruch, * eine Art rechtsbündige Versumgebung mit einem schicken Rahmen. Wenn der Vers sehr kurz ist, wäre der Rahmen klein. Wenn der Vers sehr lang ist, würde er den Text auf eine „optimale“ Breite umbrechen.

Ich denke, der richtige Weg ist mit \unhbox, aber ich bin nicht sicher, wie ich es verwenden soll. Für jede Hilfe wäre ich dankbar.

Antwort1

Wie David Carlisle oben schrieb, varwidthist das Paket die Lösung. Es bietet die Umgebung varwidth, die das tut, wonach ich gesucht habe. Hier ist ein minimales Beispiel zum Zeichnen von Text auf einem Hintergrund mit Farbverlauf und Schattierung mit Beamer.

\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}

verwandte Informationen