4

I am using plain TeX. I would like to define a macro \cpar that makes

\centerline{A\cpar B}

expand to

\centerline{A}\centerline{B}

I have experiemented with things like

\def\cpar{\egroup\centerline\bgroup}

and various incarnations of \let and \expandafter but couldn't get it to work. Any hints?

  • 1
    see tex.stackexchange.com/questions/69260/… – touhami Sep 26 '18 at 10:17
  • No, this is not exactly what I want.I want to manually control the breaks. Plus the first \centerline is kindof already given. My application is some newsletter program that announces talks. It reads information about the upcoming talks and typesets announcements. To this end, it centers the title with centerline and want the possibility for the inserted title to contain a macro that does the line breaking (while not giving up the entering). Of course, I could rewrite all ready the centerline using 69260 but I would prefer inserting a macro that tricks the above centerline as I indicated. – atdotde Sep 26 '18 at 10:33
6

You can issue \hss\egroup, that closes the box initiated by \line{\hss#1\hss}, and then \line\bgroup\hss to restart the business.

\def\cpar{\hss\egroup\line\bgroup\hss}

\centerline{A\cpar B\cpar CDEF\cpar Some more words}

\bye

enter image description here

Beware that a space before \cpar is not removed.

A different implementation using \\ and where spaces around items are trimmed off.

\input expl3-generic

\ExplSyntaxOn
\cs_set_eq:NN \atdot_centerline:n \centerline
\cs_set_protected_nopar:Npn \centerline #1
 {
  \seq_set_split:Nnn \l_atdotde_centerline_seq { \\ } { #1 }
  \seq_map_inline:Nn \l_atdotde_centerline_seq
   {
    \atdot_centerline:n { ##1 }
   }
 }
\ExplSyntaxOff

\centerline{A \\ A\\ B \\ CDEF\\ Some more words}

\bye

enter image description here

  • yes, this is what I wanted. I should have realised I should not deal with centerline directly by with what it expands to. Thanks! – atdotde Sep 26 '18 at 10:44
2

I create a new macro \Centerline to do it.

\input listofitems
\let\cpar\relax
\def\Centerline#1{%
  \setsepchar{\cpar}%
  \readlist\clarg{#1}%
  \foreachitem\z\in\clarg[]{\centerline{\z}}%
}
\Centerline{Plain old Centerline}

\Centerline{Test number 1\cpar Test number 2 right now}

\Centerline{First\cpar Second\cpar Third}
\bye

enter image description here

I don't really recommend redefining \centerline itself, but that too can be done:

\input listofitems
\let\cpar\relax
\let\svcenterline\centerline
\def\centerline#1{%
  \setsepchar{\cpar}%
  \readlist\clarg{#1}%
  \foreachitem\z\in\clarg[]{\svcenterline{\z}}%
}
\centerline{Plain old Centerline}

\centerline{Test number 1\cpar Test number 2 right now}

\centerline{First\cpar Second\cpar Third}
\bye
  • I am really looking for something more elementary: In the expansion of the first centerline, I want my macro to be expanded yielding a } or something equivalent that ends interpretation of the parameter and then uses the rest as the parameter of a new macro (that in my case also happens to be centerline. Maybe I should have asked for something that makes \a{b \c d} turn into \a{b}\e{d} for all values of b and d (but you can assume \a and \e to be given, it is the way to define \c I am looking for). – atdotde Sep 26 '18 at 10:40
  • @atdotde Well, other than the fact that it loads a package, it's pretty elementary: search the argument for instances of \cpar and apply \centerline to each fragment separated by \cpar. – Steven B. Segletes Sep 26 '18 at 10:41
  • by elementary I meant "playing with how arguments of macros are expanded". – atdotde Sep 26 '18 at 10:43
  • @atdotde Yes, I understand your intent here. egreg has come through for you. – Steven B. Segletes Sep 26 '18 at 10:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.