使用重复文本填充段落的命令(对齐/间距问题)

使用重复文本填充段落的命令(对齐/间距问题)

我正在尝试定义一个命令,用重复次数\todopar[dummy]{msg}填充一个段落并在段落中居中排版。dummymsg

最终结果应该是这样的(没有间距问题)

迫切需要

我的第一次尝试

\documentclass[draft]{article}

\usepackage{lipsum}
\usepackage{xcolor}

\colorlet{todocol}{green!30!black}

\newcommand{\repetita}[1]{\leavevmode\xleaders\hbox{#1\ }\hfill\kern0pt}
\newcommand{\todopar}[2][To Do]{%
  \par\medskip\noindent{%
  \color{todocol!50!white}
  \null\repetita{#1}\\%
  \null\repetita{#1}\\%
  \null\repetita{#1}%
  \textcolor{todocol}{#2}%
  \repetita{#1}\\%
  \null\repetita{#1}\\%
  \null\repetita{#1}\par\medskip%
}}

\begin{document}
  \lipsum*[1]
  \todopar{This is somehing we have to do soooo bad that takes even more than one line oh my gosh.}
  \lipsum*[1]
  \todopar{Lot of work}
  \lipsum*[1]
\end{document}

不幸的是,使用时\xleaders我没有得到与段落其余部分对齐的中心行中的虚拟文本,而且hbox领导者的内容以空格结尾,这意味着最后一次重复也将以空格结束该行。

我该如何解决这两个问题?有没有更优雅的方法来实现这种效果?

答案1

我会用一段话来代替领导者:

在此处输入图片描述

\documentclass[draft]{article}

\usepackage{lipsum}
\usepackage{xcolor}

\colorlet{todocol}{green!30!black}


\newcommand{\todopar}[2][To Do]{%
% end the previous par and start a local group
  \par\medskip{%
% special para uses full length lines, no white space
% at start or end
  \parindent0pt
  \parfillskip0pt
% set colour for the filler text
  \color{todocol!50!white}%
% save filler text in box, for measuring
  \sbox0{#1 }%
% 
% Set the message text in a normal paragraph with normal
% \parfillskip to allow the last line to be short as usual.
% the whole construct is inside a scratch box 2.
  \setbox2\vbox{\parfillskip\fill\strut#2\unskip\strut
% Finish the paragraph with the message text
  \par
% Probably not needed but remove any glue or penalty
% after the last line
  \unskip\unpenalty
% remove the last (or only) line of the message paragraph
  \setbox0\lastbox
% 
% At this point box0 is always full width but contains the last
% line of the message followed by \rightskip and \parfillskip glue
% so \unskip twice and globally save box1 with the natural length
% of the last line of the message.
  \global\setbox1\hbox{\unhbox0\unskip\unskip}%
% 
% Now remove the baselineskip glue before that last line.
  \unskip\unpenalty\unskip\unpenalty
% and finish the box
  }%
% Now box2 contains all the lines of the message except the last
% so for a short message it will be empty
% 
% see how many filler text it takes for 2 lines of text
  \count0=\dimexpr2\columnwidth\relax
  \divide\count0 \wd0 %
% 
% see how many filler text it takes to pad one side
% of a line that has the (last line of) the message in
% the middle
  \count2=\dimexpr(\columnwidth-\wd1-2em)/2\relax
  \divide\count2 \wd0 %
% 
% save the filler text, use a macro rather than the box
% to allow any white space in the filler to stretch
  \def\tmp{\strut#1 }%
% 
% make a paragraph of \count0 copies of the filler making
% a two full length  line paragraph
  \xrep{\count0}\par
% 
% unbox box 2 this is the initial full length lines of the message
% in the main color. As this is unboxed it is a normal sequence of
% line boxes and glue so can break at a page. 
  {\color{todocol}\unvbox2}%
% 
% Now make a 1-line paragraph with count2 copies of filler
% either side of the last line of the message, with a word space 
% padding either side/
  \xrep{\count2} \textcolor{todocol}{\unhbox1} \xrep{\count2}\par
% 
% As before a 2 line filler paragraph
  \xrep{\count0}\par%
% 
% end the local group
  }%
% A skip to match the one at the start.
 \medskip}

% A simple recursive loop macro, makes #1
% copies of \tmp
\def\xrep#1{%
\ifnum#1>0 
\tmp
\xrep{\numexpr#1-1\relax}%
\fi}

% A test document....
\begin{document}
  \lipsum*[1]
  \todopar{This is somehing we have to do soooo bad that takes even more than one line oh my gosh.}
  \lipsum*[1]
  \todopar{Lot of work}
  \lipsum*[1]
\end{document}

相关内容