Expl3 检查行是否超出 \textwidth

Expl3 检查行是否超出 \textwidth

我想修改列出作者的命令,以填写尽可能多的作者,\textwidth然后et al.在没有更多空间容纳更多作者时将其放在最后。

目前,它会检查最长的名称并生成一个整数\textwidth / <longest name width value>。这个整数表示包含的作者数。当其中一个名称很长而其他名称很短时,就会出现问题:

在此处输入图片描述

以下是 MWE:

\RequirePackage{fix-cm}
\documentclass[fontsize=13pt,paper=a4,openany,parskip=half,DIV=calc]{scrbook}
\usepackage[T1]{fontenc}
\usepackage{DejaVuSans} % Sans-serif

% These are the actual lenghts used in the document:
\usepackage{mathtools}
\setlength\topmargin{-58pt}                  
\setlength\headheight{27pt}                 
\setlength\headsep{25pt}                     
\setlength\marginparwidth{-20pt}             
\setlength\textwidth{\paperwidth - 52pt}     
\setlength\textheight{\paperheight - 112pt}  
\setlength\oddsidemargin{-45pt} 
\setlength\evensidemargin{-45pt} 

\usepackage{showframe}

\ExplSyntaxOn

% for the production version, comment the second definition
\cs_new_protected:Nn \__vebjorn_by_author_print:n
 {
  \makebox{#1}
 }

%%% comment from here
\cs_set_protected:Nn \__vebjorn_by_author_print:n
 {
  \group_begin:
  \dim_set:Nn \fboxsep { 0pt }
  \framebox{#1}
  \group_end:
 }
%%% to here

\NewDocumentCommand{\by}{m}
 {
  \vebjorn_by:n { #1 }
 }

\seq_new:N \l__vebjorn_by_in_seq
\seq_new:N \l__vebjorn_by_out_seq
\dim_new:N \l__vebjorn_by_widest_dim
\dim_new:N \l__vebjorn_by_counting_dim
\box_new:N \l__vebjorn_by_author_box
\int_new:N \l__vebjorn_by_max_int

\cs_new_protected:Nn \vebjorn_by:n
 {
  \seq_set_split:Nnn \l__vebjorn_by_in_seq { \\ } { #1 }
  \seq_set_map:NNn \l__vebjorn_by_out_seq \l__vebjorn_by_in_seq { \__vebjorn_by_author:nn ##1 }
  \__vebjorn_by_measure:
 }

\cs_new_protected:Nn \l__vebjorn_by_fil:
 {
  \int_compare:nTF { \seq_count:N \l__vebjorn_by_out_seq < 4 } { \hspace{2mm} } { \hspace{2mm} }
 }

\cs_new_protected:Nn \__vebjorn_by_author:nn
 {
  \begin{tabular}[t]{@{}c@{}}
    \fontsize{9}{11}\sffamily \text_uppercase:n{#1} \\[1ex]
    \fontsize{7}{10}\sffamily #2
  \end{tabular}
 }

\cs_new_protected:Nn \__vebjorn_by_measure:
 {
  \seq_map_function:NN \l__vebjorn_by_out_seq \__vebjorn_by_measure_author:n
  \int_set:Nn \l__vebjorn_by_max_int {  \textwidth /  \l__vebjorn_by_widest_dim   }
  % now we can print!
  \begin{center}
  \renewcommand{\arraystretch}{0}
  \seq_indexed_map_inline:Nn \l__vebjorn_by_out_seq
   {
    \__vebjorn_by_author_print:n {##2}
    \int_compare:nTF { ##1 < \l__vebjorn_by_max_int }
     {
      \int_compare:nT { ##1 < \seq_count:N \l__vebjorn_by_out_seq }
       {
        {\l__vebjorn_by_fil:\fontsize{7}{10}\sffamily og\l__vebjorn_by_fil:}
       }
     }
     {
      \int_compare:nT  { \l__vebjorn_by_max_int < \seq_count:N \l__vebjorn_by_out_seq }
       {% we've got more authors than they fit
        \seq_map_break:n { \l__vebjorn_by_fil:\fontsize{7}{10}\sffamily et~al. }
       }
     }
   }
  \end{center}
 }

\cs_new_protected:Nn \__vebjorn_by_measure_author:n
 {
  \hbox_set:Nn \l__vebjorn_by_author_box
   {
    #1
    {\fontsize{7}{10}\sffamily\quad og \quad}
   }
  \dim_set:Nn \l__vebjorn_by_widest_dim
   {
    \dim_max:nn { \l__vebjorn_by_widest_dim } { \box_wd:N \l__vebjorn_by_author_box }
   }
  \dim_set:Nn \l__vebjorn_by_counting_dim
   {
    \l__vebjorn_by_widest_dim + \box_wd:N \l__vebjorn_by_author_box 
   }
 }

\ExplSyntaxOff

\begin{document}

\by{
  {Someone}{Tagline}
}

\by{
  {Someone}{Tagline} \\
  {Someone Else}{tagline}
}

\by{
  {Someone}{Tagline} \\
  {Someone Else}{tagline} \\
  {Someone 2}{Tagline}
}

\by{
  {Someone}{Tagline} \\
  {Someone else}{tagline} \\
  {my backk hurtss}{hey ho matey yo ho} \\
  {Someone}{Tagline} \\
  {Someone}{Tagline} \\
  {Someone}{Tagline} \\
  {som}{tagline}
}

\by{
  {I have THE Longest name here}{Tagline} \\  
  {Short name}{Tagline} \\
  {Shorter}{tagline} \\
  {Someone}{Tagline} \\
  {Someone 4}{Tagline} \\
  {Someone 5}{Tagline}
}


\end{document}

textwidth我的想法是与之进行比较\l__vebjorn_by_counting_dim。但是,我不确定如何实现这一改变。

答案1

我们不需要 expl3。您可以使用 TeX 原语完成您的任务,并且生成的代码更紧凑且更接近 TeX 本身。

\def\by#1{\setbox1=\box0 \setbox1=\box3 \byA\\#1\end}
\def\byA#1{\ifx\end#1\expandafter\byC
   \else
   \expandafter\byB
   \fi
}
\def\byB#1#2{%
   \ifvoid3
      \setbox1=\hbox{\framebox{\vtop{\halign{\hfil##\hfil\cr#1\cr#2\cr}}}}%
      \ifvoid0\setbox0=\box1
      \else
         \setbox2=\hbox{\unhcopy0 \ og \unhcopy1 \ et al.}
         \ifdim\wd2>\hsize 
            \setbox3=\hbox{\unhbox0 \ et al.}
         \else
            \setbox0=\hbox{\unhbox0 \ og \unhbox1}
         \fi
      \fi
   \fi
   \byA
}
\def\byC{\ifvoid3 \setbox3=\box0 \fi \hbox to\hsize{\hss\box3\hss}\bigskip}


\by{
  {Someone}{Tagline}
}

\by{
  {Someone}{Tagline} \\
  {Someone Else}{tagline}
}

\by{
  {Someone}{Tagline} \\
  {Someone Else}{tagline} \\
  {Someone 2}{Tagline}
}

\by{
  {Someone}{Tagline} \\
  {Someone else}{tagline} \\
  {my backk hurtss}{hey ho matey yo ho} \\
  {Someone}{Tagline} \\
  {Someone}{Tagline} \\
  {Someone}{Tagline} \\
  {som}{tagline}
}

\by{
  {I have THE Longest name here}{Tagline} \\  
  {Short name}{Tagline} \\
  {Shorter}{tagline} \\
  {Someone}{Tagline} \\
  {Someone 4}{Tagline} \\
  {Someone 5}{Tagline}
}

编辑:以下是具有适当字体且不带框的代码:

\def\by#1{\setbox1=\box0 \setbox1=\box3 \byA\\#1\end}
\def\byA#1{\ifx\end#1\expandafter\byC
   \else
   \expandafter\byB
   \fi
}
\def\byB#1#2{%
   \ifvoid3
      \setbox1=\hbox{\makebox{\vtop{\halign{\hfil##\hfil\cr{\fontsize{9}{11}\sffamily\MakeUppercase{#1}}\cr{\fontsize{7}{10}\sffamily#2}\cr}}}}%
      \ifvoid0\setbox0=\box1
      \else
         \setbox2=\hbox{\unhcopy0 \ \hspace{2mm}{\fontsize{7}{10}\sffamily og} \hspace{2mm} \unhcopy1 \ \hspace{2mm} {\fontsize{7}{10}\sffamily et al.}}
         \ifdim\wd2>\hsize 
            \setbox3=\hbox{ \unhbox0 \ \hspace{2mm}{\fontsize{7}{10}\sffamily et al.}\hspace{2mm}}
         \else
            \setbox0=\hbox{\unhbox0 \ \hspace{2mm}{\fontsize{7}{10}\sffamily og}\hspace{2mm} \unhbox1}
         \fi
      \fi
   \fi
   \byA
}
\def\byC{\ifvoid3 \setbox3=\box0 \fi \hbox to\hsize{\hss\box3\hss}\bigskip}

相关内容