%20%D1%88%D0%B8%D1%80%D0%B8%D0%BD%D1%83%3F.png)
есть проблема, которую я пытаюсь решить уже некоторое время, но пока безуспешно. Насколько мне известно, TeX очень хорош в правильном разбиении текстовых строк относительно фиксированной ширины контейнера. Я пытаюсь добиться другого: я хотел бы иметь возможность вычислять «оптимальную» ширину для заданного контента.
Под оптимальным я подразумеваю, что есть базовое ограничение. Например, я хотел бы иметь возможность написать команду, \settooptimalwidth#1#2#3
которая принимает:
- #1 как длина для регулировки
- #2 как максимальная ширина
- #3 как содержание
Если #3 очень короткий (короче, чем #2), он просто сделает то же самое, что и \settowidth
. Если #3 длиннее, чем #2, он разобьет #3 на строки, как если бы он был помещен в мини-бокс, и (вот в чем сложность) вернет длину самых широких строк среди них. Я предполагаю, что алгоритм разрыва строк не использует обычное выравнивание "justified", а вместо этого raggedleft/right или centering (в противном случае проблема не имеет значения).
Позвольте мне привести несколько примеров, где такая команда будет полезна: * автоматическая настройка ширины столбца массива, содержимое которого должно быть центрировано, с возможным переносом строк, * некое подобие среды стиха, выровненного по правому краю, с нарядной рамкой. Если стих очень короткий, то рамка будет маленькой. Если стих очень длинный, она разобьет текст до «оптимальной» ширины.
Я думаю, что это путь с \unhbox
, но я не уверен, как его использовать. Любая помощь будет оценена.
решение1
Как Дэвид Карлайл написал выше, пакет varwidth
— это то, что нужно. Он предоставляет среду varwidth
, которая делает то, о чем я просил. Вот минимальный пример для рисования текста на градиентном фоне с использованием 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}