自适应对齐

自适应对齐

我正在创建.tex用于批量创建名片的文件。左上角有一个徽标,持有人的基线位于徽标下边缘上方。在 90% 的情况下,姓名和头衔适合内容专用的列。在 99% 的情况下,姓名和头衔不会与徽标冲突。但有百分之一的人会造成问题......

在以下情况下,如果名称太长,则会分成两行。

\parbox[b]{47.5mm}{\flushright%
  {\fontsize{9}{9}\selectfont\textbf{#1}}\\% Typeset the name
  {\fontsize{5}{5}\selectfont\#2}\\% ... Typeset next line
}

如果修改后\makebox溢出的名称则是单行且右对齐,但如果太长则会溢出到徽标中。

\parbox[b]{47.5mm}{\flushright{%
  \makebox[47.5mm][r]{\fontsize{9}{9}\selectfont\textbf{#1}}\\% Typeset the name
  {\fontsize{5}{5}\selectfont#2}\\% ... Typeset next line
}}

有没有办法测量要放置的盒子的宽度?类似这样的方法:

\If{\LengthOf{#1}>50mm}%
{% True branch
\makebox[47.5mm][r]{#1}% Typeset the content
\hspace{50mm-\LengthOf{#1}}% Add a negative glue
\rule{0mm}{0mm}% Add zero width box for the \hspace to work
}%
{% Else branch
\makebox[47.5mm][r]{#1}}

或者当内容适合但内容溢出框时,一些智能\foobox[width][alignment][overflow alignment]{content}功能会进行对齐?说排版:<alignment><direction>\foobox[...][r][l]{...}
| narrow|
|text that fits|
|text that is t|oo wide to fit

答案1

对于单行来说,这很容易实现。在 中也可以做到这一点parbox,但这需要手动换行才能正常工作,这对自动化来说不利。自动执行此操作要困难得多。

下面定义了一个宏\cutbox,它有一个可选参数用于设置,一个必选参数用于文本。可能的键是

  • 对齐设置剪切线和溢出线的对齐方式。它可以采用以下值rr:(右对齐溢出右)、ll(左对齐溢出左)、rl(右对齐溢出左) 和lr(左对齐溢出右)。
  • 切线设置从顶部开始的短线数。
  • 切割宽度设置切割线的最大长度。
  • 溢出宽度设置溢出行的最大长度。
  • 平行对齐设置周围的对齐方式\parbox。可能的值是tbc

结果\parboxcutwidth宽的,并且其中的行可能会溢出到overflowwidth- cutwidth

结果(这里的代码仅用于测试):

短名称和长名称:

在此处输入图片描述

整个段落(带有cutlines=3):

在此处输入图片描述

代码:

\documentclass[a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{tikz} % just for drawing some test lines
\usepackage{xkeyval} % for the keys

\makeatletter
% one line adjusted right overflow to the right
\newcommand*{\onelinerr}[1]{%
    \hbox to \cutbox@cutwidth{\hskip0pt plus 1fill\relax #1\hskip 0pt minus 1fill}%
}
% one line adjusted left overflow to the left
\newcommand*{\onelinell}[1]{%
    \hbox to \cutbox@cutwidth{\hskip0pt minus 1fill\relax #1\hskip 0pt plus 1fill}%
}
% one line adjusted right overflow to the left
\newcommand*{\onelinerl}[1]{%
    \hbox to \cutbox@cutwidth{\hss #1}%
}
% one line adjusted left overflow to the right
\newcommand*{\onelinelr}[1]{%
    \hbox to \cutbox@cutwidth{#1\hss}%
}
% some counters and lengths
\newcount\cutbox@cutlines
\newcount\cutbox@cutlines@cnt
\newdimen\cutbox@cutwidth
\newdimen\cutbox@overflowwidth
\newbox\cutbox@testbox
\newtoks\cutbox@resttoks
% the keys
\define@choicekey{cutbox}{paralign}[\cutbox@paralign]{t,b,c}[b]{}
\define@choicekey{cutbox}{align}[\cutbox@align]{rr,ll,rl,lr}[ll]{}
\define@key{cutbox}{cutlines}[1]{\cutbox@cutlines=#1\relax}
\define@key{cutbox}{cutwidth}[47.5mm]{\cutbox@cutwidth=#1\relax}
\define@key{cutbox}{overflowwidth}[95mm]{\cutbox@overflowwidth=#1\relax}
% initialize the keys
\setkeys{cutbox}{paralign=c,align=ll,cutlines=1,cutwidth=47.5mm,overflowwidth=95mm}
% output the remaining non cut lines
\newcommand*{\cutbox@output@restrr}{%
    \hbox to \cutbox@cutwidth{\parbox[t]{\cutbox@overflowwidth}{\raggedright\the\cutbox@resttoks}\hss}%
}
\newcommand*{\cutbox@output@restll}{%
    \hbox to \cutbox@cutwidth{\hss\parbox[t]{\cutbox@overflowwidth}{\raggedleft\the\cutbox@resttoks}}%
}
\let\cutbox@output@restrl\cutbox@output@restll
\let\cutbox@output@restlr\cutbox@output@restrr
% main macro
% #1: optional, setup
% #2: the text
\newcommand*{\cutbox}[2][]{%
    \def\@tempa{#2}\ifx\@tempa\@empty
    \else
        \begingroup
        \setkeys{cutbox}{#1}%
        \cutbox@cutlines@cnt=\cutbox@cutlines
        \expandafter\parbox\expandafter[\cutbox@paralign]{\cutbox@cutwidth}{\@cutbox{#2}}%
        \endgroup
    \fi
}
\newcommand*{\@cutbox}[1]{%
    \cutbox@resttoks={#1 }% the space is important
    \loop\ifnum\cutbox@cutlines@cnt>\z@\relax
        \setbox\cutbox@testbox=\hbox{}%
        \expandafter\@cutbox@collectline\the\cutbox@resttoks{} {} \@cutbox@end%
        \ifdim\wd\cutbox@testbox=\z@
            \cutbox@cutlines@cnt\z@
        \else
            \csname oneline\cutbox@align\endcsname{\unhbox\cutbox@testbox}%
        \fi
        \advance\cutbox@cutlines@cnt\m@ne
    \repeat
    \ifnum\cutbox@cutlines@cnt<\@ne
        \setbox\@tempboxa=\hbox{\the\cutbox@resttoks\unskip}%
        \ifdim\wd\@tempboxa=\z@
        \else
            \csname cutbox@output@rest\cutbox@align\endcsname
        \fi
    \fi
}
\def\@cutbox@collectline#1 #2 #3 \@cutbox@end{%
    \setbox\cutbox@testbox=\hbox{#1}%
    \ifdim\wd\cutbox@testbox>\cutbox@cutwidth
        \cutbox@set@resttoks{#2}{#3}%
    \else
        \def\@tempa{#2}\ifx\@tempa\@empty
            \cutbox@set@resttoks{#2}{}%
        \else
            \setbox\@tempboxa=\hbox{ #2}%
            \@tempdima\wd\cutbox@testbox
            \advance\@tempdima\wd\@tempboxa
            \ifdim\@tempdima>\cutbox@cutwidth
                \cutbox@set@resttoks{#2}{#3}%
            \else
                \@cutbox@@collectline#2 #3 \@cutbox@end
            \fi
        \fi
    \fi
}
\def\@cutbox@@collectline#1 #2 #3 \@cutbox@end{%
    \setbox\cutbox@testbox=\hbox{\unhbox\cutbox@testbox\space#1}%
    \def\@tempa{#2}\ifx\@tempa\@empty
        \cutbox@set@resttoks{#2}{}%
    \else
        \setbox\@tempboxa=\hbox{ #2}%
        \@tempdima\wd\cutbox@testbox
        \advance\@tempdima\wd\@tempboxa
        \ifdim\@tempdima>\cutbox@cutwidth
            \cutbox@set@resttoks{#2}{#3}%
        \else
            \@cutbox@@collectline#2 #3 \@cutbox@end
        \fi
    \fi
}
\newcommand*{\cutbox@set@resttoks}[2]{%
    \cutbox@resttoks={#1 }%
    \def\@tempa{#2}\ifx\@tempa\@empty
    \else
        \expandafter\cutbox@resttoks\expandafter=\expandafter{\the\cutbox@resttoks#2\unskip\unskip}%
    \fi
}
% for easier setup
\newcommand*{\setcutbox}[1]{%
    \setkeys{cutbox}{#1}%
}
\makeatother

% just for testing
\parindent0pt
\parskip2ex
\oddsidemargin2in

% setup
\setcutbox{cutwidth=40mm,overflowwidth=80mm}

\begin{document}
% draw lines for testing
\makeatletter
\newdimen\line@left@dist
\line@left@dist\cutbox@overflowwidth
\advance\line@left@dist-\cutbox@cutwidth
\begin{tikzpicture}[overlay]
\draw[blue] (0,0) -- (0,-20);
\draw[blue] (\cutbox@cutwidth,0) -- (\cutbox@cutwidth,-20);
\draw[red] (-\line@left@dist,0) -- (-\line@left@dist,-20);
\draw[red] (\cutbox@overflowwidth,0) -- (\cutbox@overflowwidth,-20);
\end{tikzpicture}
\makeatother

%-----------------------------------------------------------
\texttt{\textbf{align=rr}}

\cutbox[align=rr]{Philip Ackermann}

\cutbox[align=rr]{Prof. Dr. sci.fi. Dr. h.c. Philip Marko Maria Ackermann-Waldvogel}

%-----------------------------------------------------------
\texttt{\textbf{align=ll}}

\cutbox[align=ll]{Philip Ackermann}

\cutbox[align=ll]{Prof. Dr. sci.fi. Dr. h.c. Philip Marko Maria Ackermann-Waldvogel}

%-----------------------------------------------------------
\texttt{\textbf{align=rl}}

\cutbox[align=rl]{Philip Ackermann}

\cutbox[align=rl]{Prof. Dr. sci.fi. Dr. h.c. Philip Marko Maria Ackermann-Waldvogel}

%-----------------------------------------------------------
\texttt{\textbf{align=lr}}

\cutbox[align=lr]{Philip Ackermann}

\cutbox[align=lr]{Prof. Dr. sci.fi. Dr. h.c. Philip Marko Maria Ackermann-Waldvogel}


\newpage
% draw lines for testing
\makeatletter
\begin{tikzpicture}[overlay]
\draw[blue] (0,0) -- (0,-20);
\draw[blue] (\cutbox@cutwidth,0) -- (\cutbox@cutwidth,-20);
\draw[red] (-\line@left@dist,0) -- (-\line@left@dist,-20);
\draw[red] (\cutbox@overflowwidth,0) -- (\cutbox@overflowwidth,-20);
\end{tikzpicture}
\makeatother

% lets cut 3 lines now
\setcutbox{cutlines=3}

% a whole paragraph
\texttt{\textbf{align=rr}}

\cutbox[align=rr]{Quisque ullamcorper placerat ipsum. Cras nibh.
  Morbi vel justo vitae lacus tincidunt ultrices. Lorem ipsum dolor
  sit amet, consectetuer adipiscing elit. In hac habitasse platea
  dictumst. Integer tempus convallis augue. Etiam facilisis. Nunc
  elementum fermentum wisi.}

\texttt{\textbf{align=ll}}

\cutbox[align=ll]{Quisque ullamcorper placerat ipsum. Cras nibh.
  Morbi vel justo vitae lacus tincidunt ultrices. Lorem ipsum dolor
  sit amet, consectetuer adipiscing elit. In hac habitasse platea
  dictumst. Integer tempus convallis augue. Etiam facilisis. Nunc
  elementum fermentum wisi.}

\texttt{\textbf{align=rl}}

\cutbox[align=rl]{Quisque ullamcorper placerat ipsum. Cras nibh.
  Morbi vel justo vitae lacus tincidunt ultrices. Lorem ipsum dolor
  sit amet, consectetuer adipiscing elit. In hac habitasse platea
  dictumst. Integer tempus convallis augue. Etiam facilisis. Nunc
  elementum fermentum wisi.}

\texttt{\textbf{align=lr}}

\cutbox[align=lr]{Quisque ullamcorper placerat ipsum. Cras nibh.
  Morbi vel justo vitae lacus tincidunt ultrices. Lorem ipsum dolor
  sit amet, consectetuer adipiscing elit. In hac habitasse platea
  dictumst. Integer tempus convallis augue. Etiam facilisis. Nunc
  elementum fermentum wisi.}

\end{document}

相关内容