# Plain TeX: Problems when \loop to set parameters for \parshape

I was trying to write a macro for wrapping text around a figure. I aware that it is available in Latex and there is another package, figflow for plainTex. I am just learning to write my own. My first step was to use \parshape to create a blank area for the figure. I got stuck here. I define the macro as follows:

\newcount\ln
\def\wrap#1#2{\parshape=#1 \loop\relax\ifnum\ln<#1 0cm #2 \advance\ln by 1\repeat}


It does not work. I tried \edef, which did not work either. Please can anyone help? Thanks!

\parshape{6}{10cm} Here is the definitive guide to the use of TeX, written by the system's creator, Donald E. Knuth. TeX represents the state of the art in computer typesetting. It is particularly valuable where the document, article, or book to be produced contains a lot of mathematics, and where the user is concerned about typographic quality. TeX software offers both writers and publishers the opportunity to produce technical text of all kinds, in an attractive form, with the speed and efficiency of a computer system. Novice and expert users alike will gain from The TeXbook the level of information they seek. Knuth warns newcomers away from the more difficult areas, while he entices experienced users with new challenges. The novice need not learn much about TeX to prepare a simple manuscript with it. But for the preparation of more complex documents, The TeXbook contains all the detail required. Knuth's familiar wit, and illustrations specially drawn by Duane Bibby, add a light touch to an unusually readable software manual. The TeXbook is the first in a five-volume series on Computers and Typesetting, all authored by Knuth
\bye

• The problem is that \loop...\repeat isn't expandable, but the way you're using it you need an expandable loop. I think we have an almost duplicate question (but regarding the use in LaTeX) on the network, I'll dig. – Skillmon Dec 20 '20 at 18:42
• Ok, my memory tricked me, that was a loop to set the \widowpenalties, but still very similar in nature. Take a look here: tex.stackexchange.com/questions/26272 – Skillmon Dec 20 '20 at 18:44
• Many thanks, Skillmon. Is there an expandable \loop solution in PlainTeX? – Jun Dec 20 '20 at 18:53
• Not a build in that I'm aware of, no. But if you use the e-TeX extension you can build one analogue to the one shown in the answer to the question I linked, using \numexpr. But you don't necessarily need an expandable loop, instead you could use your \loop ...\repeat construct in a group and utilize \aftergroup to build the list for \parshape. – Skillmon Dec 20 '20 at 18:56
• Note that if you're writing this to include some pictures in a cut-out window, you might be interested in insbox, which already contains all the functionality you'd need for that, and which works in plain. Link: ctan.org/pkg/insbox – Skillmon Dec 20 '20 at 19:31

An answer showing a pretty basic loop with \numexpr.

When you're using \parshape and want only a specific number of lines to be affected, you have to add an additional line with 0cm \hsize to revert to normal lines after \parshape is done, because \parshape will repeat the last specification for every remaining line of the paragraph.

\catcode\@=11
\long\def\@gobble#1{}
\long\def\@secondoftwo#1#2{#2}
\def\wrap#1#2%
{%
\parshape=\numexpr#1+1\relax \wrap@{0}{#1}{#2} 0cm \hsize\relax
}
\def\wrap@#1#2#3%
{%
\ifnum#1<#2
0cm #3
\expandafter\@secondoftwo
\fi
\@gobble{\expandafter\wrap@\expandafter{\the\numexpr#1+1}{#2}{#3}}%
}
\catcode\@=12

\wrap{6}{10cm} Here is the definitive guide to the use of TeX, written by the
system's creator, Donald E. Knuth. TeX represents the state of the art in
computer typesetting. It is particularly valuable where the document, article,
or book to be produced contains a lot of mathematics, and where the user is
concerned about typographic quality. TeX software offers both writers and
publishers the opportunity to produce technical text of all kinds, in an
attractive form, with the speed and efficiency of a computer system. Novice and
expert users alike will gain from The TeXbook the level of information they
seek. Knuth warns newcomers away from the more difficult areas, while he entices
experienced users with new challenges. The novice need not learn much about TeX
to prepare a simple manuscript with it. But for the preparation of more complex
documents, The TeXbook contains all the detail required. Knuth's familiar wit,
and illustrations specially drawn by Duane Bibby, add a light touch to an
unusually readable software manual. The TeXbook is the first in a five-volume
series on Computers and Typesetting, all authored by Knuth.
\bye


• Thanks. It works. It seems my TexLive installation comes with e-Tex. – Jun Dec 21 '20 at 7:16
• @Jun e-TeX is around since decades, you have to actively pick e-TeX-free engines nowadays (Knuthian TeX is still available). – Skillmon Dec 21 '20 at 7:52

For a relatively simple application such as this (the indentation extends over only one paragraph), plain TeX offers \hangafter (the number of lines to indent, positive if from the left, negative if from the right, as here) and \hangindent (positive if the indent starts after the number the number given by \hangafter, negative if starting at line 1) — see Knuth's The TeXbook, page 102.

\hangafter=-6 \hangindent=-6cm
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

\bye


Just to be complete, a simple macro, \wrap could be defined (the output is identical):

\def\wrap#1#2{\hangafter-#1\hangindent-#2}

\wrap{6}{6cm}
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

• Many thanks, neat! – Jun Dec 20 '20 at 20:05

A simple expandable loop in expl3; it's easy to specify the wanted number of special lines instead of being one off.

\input expl3-generic

\ExplSyntaxOn

\cs_new:Npn \wrap #1 #2
{
\parshape
\int_to_arabic:n { #1 + 1 } \c_space_tl % number of special lines
\prg_replicate:nn { #1 } { 0pt~#2~ } % parameters for the special lines
0pt~\hsize % further lines
\ignorespaces
}

\ExplSyntaxOff

\wrap{6}{10cm} Here is the definitive guide to the use of TeX, written by
the system's creator, Donald E. Knuth. TeX represents the state of the art
in computer typesetting. It is particularly valuable where the document,
article, or book to be produced contains a lot of mathematics, and where
the user is concerned about typographic quality. TeX software offers both
writers and publishers the opportunity to produce technical text of all
kinds, in an attractive form, with the speed and efficiency of a computer
system. Novice and expert users alike will gain from The TeXbook the level
of information they seek. Knuth warns newcomers away from the more difficult
areas, while he entices experienced users with new challenges. The novice
need not learn much about TeX to prepare a simple manuscript with it. But
for the preparation of more complex documents, The TeXbook contains all
the detail required. Knuth's familiar wit, and illustrations specially
drawn by Duane Bibby, add a light touch to an unusually readable software
manual. The TeXbook is the first in a five-volume series on Computers and
Typesetting, all authored by Knuth

\bye


The macro \wrap is itself expandable, so you can do

\edef\wrapsix{\wrap{6}{10cm}}

\wrapsix Here is the definitive guide to the use of TeX, written by
the system's creator, Donald E. Knuth. TeX represents the state of the art
in computer typesetting. It is particularly valuable where the document,
article, or book to be produced contains a lot of mathematics, and where
[...]


and define various shapes of this kind at the beginning.

• It works although the syntax looks so different and new. Thanks. – Jun Dec 21 '20 at 10:39

OpTeX supports expandable \fornum command, so another approach is using this \fonrum command inside \parshape parameters. But OpTeX is not pure plain TeX, it is extended plain TeX:

\def\wrap#1#2{\parshape \numexpr#1+1\relax\space \fornum 1..#1\do{0cm#2}0cm\hsize}

\wrap{6}{10cm}\lipsum[1]
\bye

• It does not work on my Tex. I suppose I do not have OpTeX. – Jun Dec 21 '20 at 7:22
• @Jun You can try to run optex document. OpTeX is a part of current TeXlive or MikTeX. See petr.olsak.net/optex – wipet Dec 21 '20 at 9:06

Another approach is: prepare a list of \parshape parameters before \parshape is run. Such preparing should be done by classical (non-expandable) loop command.

\newcount\tmpnum
\def\wrap#1#2{\tmpnum=0 \def\parshapelist{}
\ifnum\tmpnum<#1 \repeat
\parshape \the\tmpnum\space \parshapelist 0cm\hsize
}

\wrap{6}{10cm} Here is the definitive guide to the use of TeX, written by the
system's creator, Donald E. Knuth. TeX represents the state of the art in
computer typesetting. It is particularly valuable where the document, article,
or book to be produced contains a lot of mathematics, and where the user is
concerned about typographic quality. TeX software offers both writers and
publishers the opportunity to produce technical text of all kinds, in an
attractive form, with the speed and efficiency of a computer system. Novice and
expert users alike will gain from The TeXbook the level of information they
seek. Knuth warns newcomers away from the more difficult areas, while he entices
experienced users with new challenges. The novice need not learn much about TeX
to prepare a simple manuscript with it. But for the preparation of more complex
documents, The TeXbook contains all the detail required. Knuth's familiar wit,
and illustrations specially drawn by Duane Bibby, add a light touch to an
unusually readable software manual. The TeXbook is the first in a five-volume
series on Computers and Typesetting, all authored by Knuth.
\bye


Of course, such concrete example could be solved by \hangafter=-6 \hangindent=-6cm as mentioned by sgmoye. But I suppose that you give this example only as studying material of \parshape behavior.

More explanation, how it works: first: \parshapelist is defined as empty and the text 0cm10cm (if #2=10cm) is appended to the \parshapelist. We have 0cm10cm0cm10cm0cm10cm0cm10cm0cm10cm0cm10cm in \parshapelist at the end of the loop. Now the primitive \parshape is processed:

\parshape 7 0cm10cm0cm10cm0cm10cm0cm10cm0cm10cm0cm10cm0cm\hsize


and it does the real work.

• It does work but I do not understand how. – Jun Dec 21 '20 at 7:10
• @Jun I added more explanation. – wipet Dec 21 '20 at 8:47

As already mentioned in the comments, \loop...\repeat is not expandable and therefore \parshape stops reading the specification. However, you can define a simple fully expandable version of \loop in Plain TeX using \romannumeral.

Essentially the trick boils down to the fact that the largest roman numeral is m which corresponds to \romannumeral1000. Hence \romannumeral2000 is turned into mm and so on. We can (ab)use this to convert our loop variable using \romannumeral into a sequence of m and strip one off in every iteration until nothing is left.

I've called the macro \replicate. It is not as powerful as \loop because you cannot access the loop counter but it's fully expandable.

\catcode@=11

\long\def\@firstoftwo#1#2{#1}
\long\def\@secondoftwo#1#2{#2}
\long\def\@gobble#1{}
\def\@ifx#1#2{%
\ifx#1#2%
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
}

% replicate
\def\replicate#1{\expandafter\@replicate\romannumeral#1000\relax\relax}
\def\@replicate#1#2#{\@ifx{\relax}{#1}{\@gobble}{\@@replicate{#2}}}
\long\def\@@replicate#1#2{#2\@replicate#1{#2}}

\catcode@=12

%%% begin document

\def\wrap#1#2{\parshape=#1\replicate{#1}{ 0cm #2}}

\input lorem\par

\wrap{6}{10cm} \input lorem\par

\input lorem\par

\bye

• You should add an additional line to the \parshape specification with 0cm \hsize. – Skillmon Dec 20 '20 at 19:30