Article View: comp.text.tex
Article #925Re: Wanted: the paragragh shape in TeX
From: Donald Arseneau
Date: Thu, 09 Apr 1992 23:56
Date: Thu, 09 Apr 1992 23:56
142 lines
6660 bytes
6660 bytes
In article <1992Apr9.145118.14359@rockyd.rockefeller.edu>, wangfei@rocky8 (Fei Wang) writes...
> Does any one who knows how to produce (in TeX) a paragragh whose shape
>is a diamond?
> I mean if the paragragh is big, the shape of this paragragh (diamond)
>will be big, if the paragragh is small, the diamond will be small.
This is at least the fourth time I've seen this plea, and I am fed up with
it. So I did it.
The macros lend themselves to various shaps, so maybe next Feb. 14 I will
make a \heartpar version.
--- Donald Arseneau
% 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
%
% Send problem reports to asnd@triumfcl.bitnet or asnd@Jack.TRIUMF.CA
%
% test integrity:
% brackets: round, square, curly, angle: () [] {} <>
% backslash, slash, vertical, hat, tilde: \ / | ^ ~
Technical Details
Message-ID:
<9APR199216564466@msr.triumf.ca>Path:
arc1-ca.pugleaf.net!sparky!uunet!van-bc!ubc-cs!unixg.ubc.ca!msr.triumf.ca!asndReferences:
<1992Apr9.145118.14359@rockyd.rockefeller.edu>Show Full Headers
Complete Article Headers
Newsgroups: comp.text.tex Path: arc1-ca.pugleaf.net!sparky!uunet!van-bc!ubc-cs!unixg.ubc.ca!msr.triumf.ca!asnd From: asnd@msr.triumf.ca (Donald Arseneau) Subject: Re: Wanted: the paragragh shape in TeX Message-ID: <9APR199216564466@msr.triumf.ca> News-Software: VAX/VMS VNEWS 1.41 Sender: news@unixg.ubc.ca (Usenet News Maintenance) Nntp-Posting-Host: msr.triumf.ca Organization: TRIUMF: Tri-University Meson Facility References: <1992Apr9.145118.14359@rockyd.rockefeller.edu> Date: Thu, 9 Apr 1992 23:56:00 GMT