Command to fill paragraph with repeated text (alignment/spacing problem)

I am trying to define a command \todopar[dummy]{msg} that fills a paragraph with dummy repeated a number of times and msg typeset centered in the paragraph.

The end result should look like this (without the spacing issues)

My first attempt is

\documentclass[draft]{article}

\usepackage{lipsum}
\usepackage{xcolor}

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

\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}


Unfortunately, using \xleaders I do not get the dummy text in the central line aligned with the ones in the rest of the paragraph, plus the contents of the hbox of the leaders end with a space which means that the last repetition will end the line with a space as well.

How can I solve these two problems? Is there a more elegant way to implement this effect?

I'd use a paragraph rather than leaders:

\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
\xrep{\count2} \textcolor{todocol}{\unhbox1} \xrep{\count2}\par
%
% As before a 2 line filler paragraph
\xrep{\count0}\par%
%
% end the local group
}%
\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}

• thanks, this gives a great result although I still have to understand every line. I would put \par\medskip before changing \parindent and \parfillskip so the previous paragraph is unaltered even if no space occurs between it and \todopar – Bordaigorl Feb 22 '15 at 22:37
• I would also use \linewidth instead of \textwidth to support two column layouts – Bordaigorl Feb 22 '15 at 22:58
• @Bordaigorl Use \columnwidth that is good in both cases. – egreg Feb 22 '15 at 23:03
• @DavidCarlisle could you briefly explain how you construct the boxes? I kind of get the calculations on the widths and \xrep but I am not sure how you manage to construct the centered paragraph so that it can break in multiple lines and even across pages – Bordaigorl Feb 22 '15 at 23:32
• @Bordaigorl I'll add some comments to the code.... – David Carlisle Feb 22 '15 at 23:41