我的问题
我想定义一个框架固定尺寸(即最小尺寸 = 最大尺寸 = 定义尺寸),其中有富文本(可能有换行符、项目化等等)。
此外,我希望它遵守以下属性:
- 文本应该适合框架,且垂直和水平方向均不得超出。
- 文本应该保持其相对字体大小(即
normalsize
、 或Huge
等),但可能会萎缩如果它不尊重属性#1(在这种情况下,选择能够尊重属性#1 的最大字体大小)。 - 文本应为垂直居中, 和水平左对齐在框架内。
- 应该
\linewidth
等于固定宽度(即,文本应该填充所有水平宽度,最后一行除外)。
已尝试的解决方案
为了使问题保持清晰易读,请参阅下面的答案,其中列出了我尝试过的所有不成功的解决方案。
我的问题
在尝试过的解决方案中,应该进一步研究哪个?那么我缺少哪些设置?也许还有其他更合适的包?
答案1
这是一个很长的问题描述,其中尝试了几种解决方案都没有奏效。我可以提供\tcboxfit
帮助tcolorbox
。
缩放失败的主要原因是标准算法需要加载可自由缩放的字体。另外,fit fontsize macros
需要进行设置才能适应\Huge
。
一个简单的修复方法是将适配算法更改为areasize
不需要可缩放字体:
\documentclass[a4]{scrartcl}
\usepackage[most]{tcolorbox}
\tcbset{
colframe=black,
colback=white,
size=tight,
nobeforeafter,
valign=center,
fit fontsize macros,
fit algorithm=areasize,
}
\begin{document}
\section*{tcolorbox solution}
\tcboxfit[width=8cm,height=2cm]{
Normal size, short text
}
\tcboxfit[width=8cm,height=2cm]{
\Huge Huge size, short text
}
\vspace*{1cm}
\noindent
\tcboxfit[width=8cm,height=2cm]{
Normal size, but this time it is a very very long text, that is normally longer than 8 centimeters. And there is even more text such as lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque blandit nibh et risus malesuada vehicula. Morbi in finibus ex. Cras dictum velit at lorem maximus, quis imperdiet velit lacinia. Nam lobortis facilisis sapien, eget pharetra ante accumsan eget. Pellentesque volutpat vulputate ligula a pretium. Nam sagittis tempus pellentesque. Donec dolor leo, dignissim eget augue in, maximus vehicula dolor. Pellentesque quis nulla aliquet, fringilla risus sed, molestie nisi. Maecenas imperdiet massa et elit molestie, at semper nulla cursus. Morbi blandit porttitor est eu bibendum. orem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque blandit nibh et risus malesuada vehicula. Morbi in finibus ex. Cras dictum velit at lorem maximus, quis imperdiet velit lacinia. Nam lobortis facilisis sapien, eget pharetra ante accumsan eget. Pellentesque volutpat vulputate ligula a pretium. Nam sagittis tempus pellentesque. Donec dolor leo, dignissim eget augue in, maximus vehicula dolor. Pellentesque quis nulla aliquet, fringilla risus sed, molestie nisi. Maecenas imperdiet massa et elit molestie, at semper nulla cursus. Morbi blandit porttitor est eu bibendum.
}
\tcboxfit[width=8cm,height=2cm]{
\Huge Huge size, but this time it is a very very long text, that is normally longer than 8 centimeters.
}
\vspace*{0.5cm}
\end{document}
得出:
答案2
注意:为了保持原始问题的可读性(从而易于理解),您可以在这里找到我最初在问题中发布的试验。请注意这里没有完全令人满意的解决方案。这篇文章更多的是提供一些思考的空间,避免在这种僵局中浪费时间。
已尝试的解决方案
我发现有好几个帖子讨论类似问题。我尝试了一些建议的解决方案。
使用包
environ
++minibox
\relsize
例如kongo09 的解决方案质疑 ”通过调整字体大小使文本适合给定的框“对我来说效果很好...除非文本不够长,字体大小就会增加(这是我所不想要的,因为如果在一个大框架内有小文本,你会得到一个巨大的字体大小,这很难看)。
\tcboxfit
从tcolorbox
包中使用
正如建议的那样此解决方案,也有tcboxfit
解决方案。但是,它不起作用,就像下面的 MWE 一样
\documentclass[a4]{scrartcl}
\usepackage[most]{tcolorbox}
\tcbset{
colframe=black,
colback=white,
boxsep=0pt,
top=0mm,
bottom=0mm,
left=0mm,
right=0mm,
nobeforeafter,
arc=0pt,
outer arc=0pt
}
\begin{document}
\section*{tcolorbox solution}
\tcboxfit[width=8cm,height=2cm]{
Normal size, short text
}
\tcboxfit[width=8cm,height=2cm]{
\Huge Huge size, short text
}
\vspace*{1cm}
\noindent
\tcboxfit[width=8cm,height=2cm]{
Normal size, but this time it is a very very long text, that is normally longer than 8 centimeters. And there is even more text such as lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque blandit nibh et risus malesuada vehicula. Morbi in finibus ex. Cras dictum velit at lorem maximus, quis imperdiet velit lacinia. Nam lobortis facilisis sapien, eget pharetra ante accumsan eget. Pellentesque volutpat vulputate ligula a pretium. Nam sagittis tempus pellentesque. Donec dolor leo, dignissim eget augue in, maximus vehicula dolor. Pellentesque quis nulla aliquet, fringilla risus sed, molestie nisi. Maecenas imperdiet massa et elit molestie, at semper nulla cursus. Morbi blandit porttitor est eu bibendum. orem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque blandit nibh et risus malesuada vehicula. Morbi in finibus ex. Cras dictum velit at lorem maximus, quis imperdiet velit lacinia. Nam lobortis facilisis sapien, eget pharetra ante accumsan eget. Pellentesque volutpat vulputate ligula a pretium. Nam sagittis tempus pellentesque. Donec dolor leo, dignissim eget augue in, maximus vehicula dolor. Pellentesque quis nulla aliquet, fringilla risus sed, molestie nisi. Maecenas imperdiet massa et elit molestie, at semper nulla cursus. Morbi blandit porttitor est eu bibendum.
}
\tcboxfit[width=8cm,height=2cm]{
\Huge Huge size, but this time it is a very very long text, that is normally longer than 8 centimeters.
}
\vspace*{0.5cm}
\end{document}
使用 Steven 的解决方案
正如建议的那样史蒂文的评论, 我在看他的解决方案。但是,我发现原始字体大小可能会增加,并且在减小字体大小时并非所有文本宽度都得到利用。这是一个 MWE:
\documentclass[a4]{scrartcl}
\usepackage{scalerel}
\usepackage{fp}
\usepackage{stackengine}
\newcount\boxheight
\newcount\boxwidth
\newlength\constrainedwidth
\newsavebox\testbox
\newlength\currentwidth
\newcommand\aspect[1]{%
\boxheight=\ht#1\relax%
\boxwidth=\wd#1\relax%
\FPdiv\testaspect{\the\boxheight}{\the\boxwidth}%
%\testaspect\\% COMMENT THIS LINE TO REMOVE ASPECT-RATIO PRINTS
}
% TARGET-HEIGHT, TARGET-WIDTH, CONTENT, GUESS>NATURAL-WIDTH, dWIDTH
\newcommand\constraintext[5]{%
\def\svfboxsep{\the\fboxsep}%
\setlength\fboxsep{0pt}%
\setlength\constrainedwidth{#2}%
\sbox\testbox{\rule{#2}{#1}}%
%TARGET ASPECT RATIO\\% COMMENT THIS LINE TO REMOVE COMMENT
%V\\% COMMENT THIS LINE TO REMOVE COMMENT
\aspect{\testbox}%
\edef\aspectratio{\testaspect}%
\constrainsize{#1}{\aspectratio}{#3}{#4}{#5}%
\setlength\fboxsep{\svfboxsep}%
}
\newcommand\constrainsize[5]{%
\sbox{\testbox}{\fbox{\parbox[b]{#4}{#3}}}%
\aspect{\testbox}%
\FPiflt{\testaspect}{#2}%
\setlength{\currentwidth}{#4}%
\addtolength{\currentwidth}{-#5}%
\constrainsize{#1}{#2}{#3}{\currentwidth}{#5}%
\else
\setlength\constrainedwidth{#1}%
\FPdiv\result{1.0}{#2}%
% CHANGE \framebox TO \makebox TO REMOVE FRAME
\framebox[\result\constrainedwidth]{\hfill%
\scaleto{\parbox[b]{\currentwidth}{#3}}{#1}%
\hfill%
}%
\fi%
}
\parindent 0pt
\begin{document}
\section*{Steven's solution}
\constraintext{2cm}{8cm}{
Normal size, short text
}{20cm}{0.1cm}
\constraintext{2cm}{8cm}{
\Huge Huge size, short text
}{20cm}{0.1cm}
\vspace*{1cm}
\noindent
\constraintext{2cm}{8cm}{
Normal size, but this time it is a very very long text, that is normally longer than 8 centimeters. And there is even more text such as lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque blandit nibh et risus malesuada vehicula. Morbi in finibus ex. Cras dictum velit at lorem maximus, quis imperdiet velit lacinia. Nam lobortis facilisis sapien, eget pharetra ante accumsan eget. Pellentesque volutpat vulputate ligula a pretium. Nam sagittis tempus pellentesque. Donec dolor leo, dignissim eget augue in, maximus vehicula dolor. Pellentesque quis nulla aliquet, fringilla risus sed, molestie nisi. Maecenas imperdiet massa et elit molestie, at semper nulla cursus. Morbi blandit porttitor est eu bibendum. orem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque blandit nibh et risus malesuada vehicula. Morbi in finibus ex. Cras dictum velit at lorem maximus, quis imperdiet velit lacinia. Nam lobortis facilisis sapien, eget pharetra ante accumsan eget. Pellentesque volutpat vulputate ligula a pretium. Nam sagittis tempus pellentesque. Donec dolor leo, dignissim eget augue in, maximus vehicula dolor. Pellentesque quis nulla aliquet, fringilla risus sed, molestie nisi. Maecenas imperdiet massa et elit molestie, at semper nulla cursus. Morbi blandit porttitor est eu bibendum.
}{20cm}{0.1cm}
\constraintext{2cm}{8cm}{
\Huge Huge size, but this time it is a very very long text, that is normally longer than 8 centimeters.
}{20cm}{0.1cm}
\end{document}
使用
adjustbox
包
我也听说过这个adjustbox
包,在我看来,它似乎适合我的问题。然而,经过几次尝试,我找不到符合我要求的参数。我探索了两种解决方案:
- 基于命令的环境
\adjustbox
, - 这
\adjustbox
第一种方法效果很好,只是我无法强制遵守垂直最大尺寸。第二种方法在这种情况下是不可接受的,因为它不接受换行符、条目等。
这是我的 MWE:
\documentclass[a4]{scrartcl}
\usepackage[calc]{adjustbox}
\newenvironment{fitbox}[2]{% \begin{fitbox}{<width>}{<height>} stuff \end{fitbox}
\def\Xwidth{#1}
\def\Yheight{#2}
\noindent
\adjustbox{
frame,
margin= 0pt 0pt 0pt 0pt,
minipage=[c][\Yheight]{\Xwidth},
min width=\Xwidth ,
min totalheight=\Yheight ,
max width=\Xwidth ,
max totalheight=\Yheight ,
env={minipage}[t][\Yheight]{\Xwidth}
}\bgroup
}{%
\egroup
}
\begin{document}
\section{fitbox solution}
\begin{fitbox}{8cm}{2cm}
Normal size, short text
\end{fitbox}
\begin{fitbox}{8cm}{2cm}
\Huge Huge size, short text
\end{fitbox}
\vspace*{1cm}
\begin{fitbox}{8cm}{2cm}
Normal size, but this time it is a very very long text, that is normally longer than 8 centimeters.
\end{fitbox}
\begin{fitbox}{8cm}{2cm}
\Huge Huge size, but this time it is a very very long text, that is normally longer than 8 centimeters.
\end{fitbox}
\vspace*{0.5cm}
\section{maxsizebox solution}
\maxsizebox*{8cm}{2cm}{\fbox{Normal size, short text}}
\maxsizebox*{8cm}{2cm}{\fbox{\Huge Huge size, short text }}
\noindent
\maxsizebox*{8cm}{2cm}{\fbox{Normal size, but this time it is a very very long text, that is normally longer than 8 centimeters.}}
\maxsizebox*{8cm}{2cm}{\fbox{\Huge Huge size, but this time it is a very very long text, that is normally longer than 8 centimeters.}}
\end{document}
答案3
我遇到了一个问题,我需要缩小文本以适合框内的大小,但只能以 1 pt 为增量。如果您使用LuaLaTeX或者西拉特克斯,这个解决方案有效。
使用一个宽度为 400bp、高度为 300bp 的框,我最终测量了文本的高度,并将尺寸向下循环直到适合为止。(在此示例中,文本大小最终为 57pt。)请注意,这\count255
是一个未使用的整数,我们只是借用了它。
\documentclass{article}
\usepackage{calc}
\begin{document}
\newlength{\mycontentheight}
\count255 = 100
\loop
\fontsize{\count255 pt}{\count255 pt}
\selectfont
\settototalheight{\mycontentheight}{\parbox{400bp}{
\begin{flushleft}
This is where the content goes. \emph{Italics}, graphics, you name it. It goes here.
\end{flushleft}}}
\ifdim \mycontentheight>300bp
\advance \count255 by -1
\repeat
\the\count255
\parbox{400bp}{
\begin{flushleft}
This is where the content goes. \emph{Italics}, graphics, you name it. It goes here.
\end{flushleft}}
\end{document}
(也许您可以使用\savebox
,\usebox
这样您就不必在测量后在页面上再次写入内容,但是在播放过程中我遇到了一些困难。)