环境以获得像光学聊天文本一样的递减文本大小

环境以获得像光学聊天文本一样的递减文本大小

目标是获得以下 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}

相关内容