目标是获得以下 MWE
\documentclass{book}
\begin{document}
\begin{degressive}
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit.
\end{degressive}
\end{document}
大致如下的渲染:
解释:每行的文本大小都必须小于前一行(例如,可以是正常文本大小的 {400%、300%、200%、150%})。但理想情况下,环境应该将文本大小四舍五入以适应文本宽度并保留合适的字间距。
那么,谁来构建这样的环境呢?
答案1
概念证明:
\documentclass{book}
\usepackage{xparse}
\usepackage{lmodern}
\ExplSyntaxOn
\NewDocumentEnvironment{degressive}{b}
{
\frenchspacing
\setlength{\parindent}{0pt}
\fauve_degressive:n { #1 }
}
{}
\seq_new:N \l__fauve_degressive_text_seq
\seq_new:N \l__fauve_degressive_tentative_seq
\tl_new:N \l__fauve_degressive_word_tl
\box_new:N \l__fauve_degressive_tentative_box
\cs_new_protected:Nn \fauve_degressive:n
{
\seq_set_split:Nnn \l__fauve_degressive_text_seq { ~ } { #1 }
% first line at 30pt size
\seq_clear:N \l__fauve_degressive_tentative_seq
\__fauve_degressive_line:n { 30 }
% second line at 25pt size
\seq_clear:N \l__fauve_degressive_tentative_seq
\__fauve_degressive_line:n { 25 }
% third line at 20pt size
\seq_clear:N \l__fauve_degressive_tentative_seq
\__fauve_degressive_line:n { 20 }
% fourth line at 15pt size
\seq_clear:N \l__fauve_degressive_tentative_seq
\__fauve_degressive_line:n { 15 }
% the rest
\seq_use:Nn \l__fauve_degressive_text_seq { ~ } \par
}
\cs_new_protected:Nn \__fauve_degressive_line:n
{
\seq_pop_left:NN \l__fauve_degressive_text_seq \l__fauve_degressive_word_tl
\hbox_set:Nn \l__fauve_degressive_tentative_box
{
\fontsize{#1}{0}\selectfont
\seq_use:Nn \l__fauve_degressive_tentative_seq { ~ } ~
\l__fauve_degressive_word_tl
}
\dim_compare:nTF
{
\box_wd:N \l__fauve_degressive_tentative_box > \textwidth
}
{% the previous attempt was the maximum
{
\fontsize{#1}{\fp_eval:n{1.2*(#1)}}\selectfont
\seq_use:Nn \l__fauve_degressive_tentative_seq { ~ }
\setlength{\parfillskip}{0pt}\par
}
\seq_put_left:NV \l__fauve_degressive_text_seq \l__fauve_degressive_word_tl
}
{% do it again
\seq_put_right:NV \l__fauve_degressive_tentative_seq \l__fauve_degressive_word_tl
\__fauve_degressive_line:n { #1 }
}
}
\ExplSyntaxOff
\begin{document}
\begin{degressive}
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Sed non risus. Suspendisse lectus tortor, dignissim sit
amet, adipiscing nec, ultricies sed, dolor. Cras elementum
ultrices diam. Maecenas ligula massa, varius a, semper
congue, euismod non, mi. Proin porttitor, orci nec nonummy
molestie, enim est eleifend mi, non fermentum diam nisl sit
amet erat. Duis semper. Duis arcu massa, scelerisque vitae,
consequat in, pretium a, enim. Pellentesque congue. Ut in
risus volutpat libero pharetra tempor. Cras vestibulum
bibendum augue. Praesent egestas leo in pede. Praesent
blandit odio eu enim. Pellentesque sed dui ut augue blandit
sodales. Vestibulum ante ipsum primis in faucibus orci
luctus et ultrices posuere cubilia Curae; Aliquam nibh.
Mauris ac mauris sed pede pellentesque fermentum. Maecenas
adipiscing ante non diam sodales hendrerit.
\end{degressive}
\end{document}
如果您没有xparse
版本 2019-03-05 (或更高版本),请使用environ
:
\documentclass{book}
\usepackage{xparse}
\usepackage{lmodern}
\usepackage{environ}
\ExplSyntaxOn
\NewEnviron{degressive}
{
\frenchspacing
\setlength{\parindent}{0pt}
\fauve_degressive:V \BODY
}
\seq_new:N \l__fauve_degressive_text_seq
\seq_new:N \l__fauve_degressive_tentative_seq
\tl_new:N \l__fauve_degressive_word_tl
\box_new:N \l__fauve_degressive_tentative_box
\cs_new_protected:Nn \fauve_degressive:n
{
\seq_set_split:Nnn \l__fauve_degressive_text_seq { ~ } { #1 }
% first line at 30pt size
\seq_clear:N \l__fauve_degressive_tentative_seq
\__fauve_degressive_line:n { 30 }
% second line at 25pt size
\seq_clear:N \l__fauve_degressive_tentative_seq
\__fauve_degressive_line:n { 25 }
% third line at 20pt size
\seq_clear:N \l__fauve_degressive_tentative_seq
\__fauve_degressive_line:n { 20 }
% fourth line at 15pt size
\seq_clear:N \l__fauve_degressive_tentative_seq
\__fauve_degressive_line:n { 15 }
% the rest
\seq_use:Nn \l__fauve_degressive_text_seq { ~ } \par
}
\cs_generate_variant:Nn \fauve_degressive:n { V }
\cs_new_protected:Nn \__fauve_degressive_line:n
{
\seq_pop_left:NN \l__fauve_degressive_text_seq \l__fauve_degressive_word_tl
\hbox_set:Nn \l__fauve_degressive_tentative_box
{
\fontsize{#1}{0}\selectfont
\seq_use:Nn \l__fauve_degressive_tentative_seq { ~ } ~
\l__fauve_degressive_word_tl
}
\dim_compare:nTF
{
\box_wd:N \l__fauve_degressive_tentative_box > \textwidth
}
{% the previous attempt was the maximum
{
\fontsize{#1}{\fp_eval:n{1.2*(#1)}}\selectfont
\seq_use:Nn \l__fauve_degressive_tentative_seq { ~ }
\setlength{\parfillskip}{0pt}\par
}
\seq_put_left:NV \l__fauve_degressive_text_seq \l__fauve_degressive_word_tl
}
{% do it again
\seq_put_right:NV \l__fauve_degressive_tentative_seq \l__fauve_degressive_word_tl
\__fauve_degressive_line:n { #1 }
}
}
\ExplSyntaxOff
\begin{document}
\begin{degressive}
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Sed non risus. Suspendisse lectus tortor, dignissim sit
amet, adipiscing nec, ultricies sed, dolor. Cras elementum
ultrices diam. Maecenas ligula massa, varius a, semper
congue, euismod non, mi. Proin porttitor, orci nec nonummy
molestie, enim est eleifend mi, non fermentum diam nisl sit
amet erat. Duis semper. Duis arcu massa, scelerisque vitae,
consequat in, pretium a, enim. Pellentesque congue. Ut in
risus volutpat libero pharetra tempor. Cras vestibulum
bibendum augue. Praesent egestas leo in pede. Praesent
blandit odio eu enim. Pellentesque sed dui ut augue blandit
sodales. Vestibulum ante ipsum primis in faucibus orci
luctus et ultrices posuere cubilia Curae; Aliquam nibh.
Mauris ac mauris sed pede pellentesque fermentum. Maecenas
adipiscing ante non diam sodales hendrerit.
\end{degressive}
\end{document}