% D I A M O N D P A R . S T Y or . T E X % % \diamondpar{17pt} A macro to typeset paragraphs in a diamond shape. % The size is adjusted automatically. There is one parameter: the increment % by which to change the indentation with every line. The command % "\diamondpar{\baselineskip}" produces a square paragraph standing on its % corner. There can be no displayed math, and no "\vadjust" material, which % includes "\vspace". These macros work for both \LaTeX\ and plain \TeX\ . % % \diamondpar{6pt} The paragraph is repeatedly formatted until the size % and shape are right; this process can be very slow. It is a bit faster % with \TeX~3 because "\emergencystretch" is used for the formatting. % If \TeX~2 is being used, the "\leftskip" and "\rightskip" are increased % until the paragraph formats cleanly, so some ``diamonds'' might look % pretty bad. A short first word and a space before the final period help . % % \diamondpar{30pt} Donald Arseneau Apr. 1992 % % % make file load whatever status of @ \expandafter\edef\csname D@catcode\endcsname {\catcode`\noexpand\@=\the\catcode`\@ \let \csname D@catcode\endcsname \noexpand\UnDefinedButNoAt} \catcode`\@=11 % Define variables. Use LaTeX names for some. \newbox\D@boxa \newbox\D@boxb \ifx\@tempdima\@undefined \newdimen\@tempdima \fi \ifx\@tempdimb\@undefined \newdimen\@tempdimb \fi \ifx\@tempcnta\@undefined \newcount\@tempcnta \fi \ifx\@tempcntb\@undefined \newcount\@tempcntb \fi \newdimen\D@pd \newdimen\D@step \newcount\D@gcount % Take a square root of counter \sqrtcount using Newton's method. \newcount\sqrtcount \def\sqrtofcount{\@tempcnta\sqrtcount \sqrtcount=20 \squiterate} \def\squiterate{\@tempcntb\@tempcnta \divide\@tempcntb\sqrtcount \advance\sqrtcount\@tempcntb \divide\sqrtcount\tw@ \advance \@tempcntb -\sqrtcount \ifnum \ifnum \@tempcntb<\z@ -\fi \@tempcntb>3 % approximate, use 1 for exact \expandafter \squiterate \fi} \def\diamondpar#1{% #1 = distance to step indentation at every line. \par \D@step#1\relax \D@pd\prevdepth \setbox\D@boxa\vbox\bgroup \parindent\z@ \leftskip\z@ \rightskip\z@ \parfillskip\z@ plus 1fill \begingroup \let\par\D@endpar \hsize\maxdimen \pretolerance\m@ne \ifx\textwidth\@undefined\else \textwidth\hsize \linewidth\hsize\fi \def\vadjust{{\def\D@dm{special vertical material}\the\everydisplay}}% \everydisplay{\errhelp{Press RETURN, and only the text following the error will be printed.}\errmessage{Diamond Paragraph Error: \D@dm\space is illegal in a diamond paragraph}}% \ignorespaces} \def\D@endpar{\endgraf \endgroup \unskip\unkern\unpenalty \setbox\D@boxa\lastbox \setbox\D@boxa\hbox{\unhbox\D@boxa\unskip\unskip\unpenalty}% \@tempdima\wd\D@boxa \divide\@tempdima\D@step \sqrtcount\@tempdima \sqrtofcount % guess num lines \advance\sqrtcount\tw@ \global\D@gcount\sqrtcount \begingroup \ifx\emergencystretch\@undefined % TeX 2, ugly \tolerance\@M \spaceskip .333333emplus1.66666emminus1.11111em \hfuzz4\D@step \else % TeX 3, nicer \tolerance\@m \emergencystretch 2in\relax \fi \hbadness\@M % avoid error messages \global\let\D@again\D@tryparshape \D@tryparshape} \def\D@tryparshape{% try a diamond parshape with \D@gcount lines \@tempcntb\D@gcount \advance\@tempcntb\@ne \edef\D@parshape{\parshape\the\@tempcntb\space}\def\D@shapepar{\z@.5\maxdimen}% \@tempcntb\@ne \@tempdimb\D@step \@tempdima.5\hsize \advance\@tempdima-.5\D@step \loop % construct the \parshape command \ifnum\@tempcntb<\D@gcount \edef\D@parshape{\D@parshape\the\@tempdima\the\@tempdimb\space}% \edef\D@shapepar{\the\@tempdima\the\@tempdimb\space\D@shapepar}% \advance\@tempdima-\D@step \advance\@tempdimb2\D@step \advance\@tempcntb\tw@ \repeat \global\setbox\D@boxb\vbox{% \D@parshape \ifodd\D@gcount \the\@tempdima\the\@tempdimb\fi \D@shapepar \noindent\unhcopy\D@boxa\endgraf \ifnum\prevgraf=\D@gcount % right size, done \global\advance\D@gcount\m@ne \aftergroup\D@done \else\ifnum\prevgraf>\D@gcount % text too long, do again \global\advance\D@gcount\@ne \global\let\D@again\D@done \aftergroup\D@tryparshape \else % too small; if was too big before, then done, otherwise do again \global\advance\D@gcount\m@ne \aftergroup\D@again \fi\fi}} \def\D@done{\global\advance\D@gcount\tw@ \leftskip\z@ plus2ptminus2pt \rightskip\z@ plus2ptminus2pt \parfillskip.5\maxdimen % this will drag text to the bottom point. \D@reform % reformat paragraph \endgroup\egroup % back to the outer page list \D@pd\dp\D@boxb \unvbox\D@boxb \prevdepth\D@pd } \def\D@reform{\global\setbox\D@boxb\vbox\bgroup \D@parshape \ifodd\D@gcount\else \the\@tempdima\the\@tempdimb\fi \D@shapepar %% get prevdepth from outside, penalty puts \parskip and favors breaks \prevdepth\D@pd \ifdim\D@pd>-\@m\p@ \penalty-50 \fi \noindent\unhcopy\D@boxa\unskip\unskip\unpenalty\strut \penalty-\@m\hbox{\kern\hfuzz}\endgraf \ifnum\prevgraf=\D@gcount % good, it worked. \setbox\D@boxa\lastbox \unskip\unpenalty %remove mongo last box \egroup \else \egroup \multiply\leftskip\tw@ \multiply\rightskip\tw@ \expandafter \D@reform \fi} \def\D@dm{displayed math} \D@catcode % restore catcode of @ to starting value \endinput % % Send problem reports to asnd@triumfcl.bitnet or asnd@Jack.TRIUMF.CA % % test integrity: % brackets: round, square, curly, angle: () [] {} <> % backslash, slash, vertical, hat, tilde: \ / | ^ ~