% \iffalse meta-comment
% 
% Copyright (C) 2004 by Robert J Lee <latex@rjlee.homelinux.org>
% --------------------------------------------------------------
% 
% This file may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.2
% of this license or (at your option) any later version.
% The latest version of this license is in:
% 
% http://www.latex-project.org/lppl.txt
% 
% and version 1.2 or later is part of all distributions of LaTeX 
% version 1999/12/01 or later.
% 
% \fi
% 
% \iffalse
%<*driver> 
\ProvidesFile{rjlpshap.dtx}
%</driver> 
%<package> \NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package> \ProvidesPackage{rjlpshap}
%<*package> 
[2004/11/05 v1.0 .dtx rjlpshap file]
%</package> 
% 
%<*driver> 
\documentclass{ltxdoc}
\EnableCrossrefs         
\CodelineIndex
\RecordChanges
\usepackage{lipsum}
\begin{document}
\DocInput{rjlpshap.dtx}
\end{document}
%</driver> 
% \fi
% 
% \CheckSum{0}
% 
% \CharacterTable
% {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
% 
% 
% \changes{v1.0}{2004/11/05}{Initial version}
% 
% \GetFileInfo{rjlpshap.dtx}
% 
% \DoNotIndex{\newcommand,\newenvironment}
% 
% 
% \title{The \textsf{rjlpshap} class\thanks{This document
%     corresponds to \textsf{rjlpshap}~\fileversion, dated \filedate.}}
% \author{Robert J Lee \\ \texttt{latex@rjlee.homelinux.org}}
% 
% \maketitle
% 
% \section{Introduction}
% 
% This package provides low-level helper macros and environments. It
% is intended for authors of \LaTeX\ packages, who wish to
% programmatically change the shape of paragraphs. It overcomes several
% difficulties with \TeX's \texttt{$\backslash$parshape} register:
% 
% \begin{enumerate}
% \item It is not possible to re-use a length register when issuing a
%   \texttt{$\backslash$parshape} command; this makes it difficult to
%   calculate the shape of a paragraph in \LaTeX\ using some
%   algorithms that re-use one or more variables (registers).
% \item The number of lines must be known \textit{before} the lengths
%   of each line, which can lead to difficult calculations.
% \item The format of the \texttt{$\backslash$parshape} command is
%   very strict and evaluated early on by \TeX, and so it doesn't
%   easily allow for parameter-replacement, making it difficult to use
%   any calculations at all.
% \end{enumerate}
% 
% It differs from the \texttt{shapepar} package, in that it provides
% no actual calculations for paragraph shapes. Instead, it provides a
% framework by which paragraph shapes can be calculated in a single
% run of the document by the author (or package writer).
% 
% The package provides both environments and commands by which the
% author can accumulate any number of lengths and then use them in a
% \texttt{$\backslash$parshape} command injected into the document,
% without the need to re-run \LaTeX.
% 
% \pagebreak[4]
% \section{Usage}
% 
% There are two modes of operation: environment mode and command
% mode. Environment mode has the advantage that it does not
% require the number of lengths to be known in advance, while command
% mode provides various options for passing pre-calculated lengths.
% 
% \subsection{Environment Mode}
% 
% Environment mode uses a single environment,
% \texttt{parshapecollect}, which starts and ends before the paragraph
% of text. The contents of the environment are a \LaTeX\ program,
% supplied by the user, that calculates the lengths of each line. 
% 
% \DescribeEnv{parshapecollect} The \texttt{parshapecollect}
% environment goes at the start of a paragraph, and the entire
% environment defines a single \texttt{$\backslash$parshape} command.
% Any even number of lengths are collected, and at the end of the
% environment, the \texttt{$\backslash$parshape} command is
% automatically generated and inserted into the document.
% 
% \DescribeMacro{\parshapelenout} This macro takes one mandatory
% parameter, which is the next length in the
% \texttt{$\backslash$parshape} command. Note that the parameter is
% expanded: the value of the length at the time
% \texttt{$\backslash$parshapelenout} is called is the value which is
% used --- this means the same length command can be re-used
% repeatedly. The value may be a length register, and the same
% register may be re-used after changing its contents, for example:
% 
% \begin{quote}
% \begin{verbatim}
%  \newlength{\foo}
%  \begin{parshapecollect}
%     \setlength{\foo}{1in}\parshapelenout{\foo}
%     \setlength{\foo}{3in}\parshapelenout{\foo}
%     \setlength{\foo}{0.5in}\parshapelenout{\foo}
%     \setlength{\foo}{3.5in}\parshapelenout{\foo}
%     \setlength{\foo}{0in}\parshapelenout{\foo}
%     \setlength{\foo}{4in}\parshapelenout{\foo}
%  \end{parshapecollect}
%  \lipsum[1]
% \end{verbatim}
%   Produces:
%
% \parshape 3 1in 4in 0.5in 4.5in 0in 5in 
% \lipsum[1]
% \end{quote}

%
% \DescribeMacro{\parshapearrlenout} This macro is the same as
% \texttt{$\backslash$parshapelenout}, but allows the programmer to
% pass the length as the value from an array (see the
% \texttt{arrayjob} package). This is intended for situations where
% pre-calculated lengths are to be used alongside calculations; to
% pass an array of lengths the various command modes may be
% easier. The parameters to the macro are the name of the array and
% the name of a counter containing the index.
%
% For example, the above paragraph could have been created
% using:
% \begin{quote}
% \begin{verbatim}
%  \newarray{foo} \newcounter{ctr}
%  \begin{parshapecollect}
%     \foo(1)={1in}\setcounter{ctr}{1}\parshapearrlenout{foo}{ctr}
%     \foo(2)={3in}\setcounter{ctr}{2}\parshapearrlenout{foo}{ctr}
%     \foo(3)={0.5in}\setcounter{ctr}{3}\parshapearrlenout{foo}{ctr}
%     \foo(1)={3.5in}\setcounter{ctr}{1}\parshapearrlenout{foo}{ctr}
%     \foo(2)={0in}\setcounter{ctr}{2}\parshapearrlenout{foo}{ctr}
%     \foo(2)={4in}\parshapearrlenout{foo}{ctr}
%  \end{parshapecollect}
%  \lipsum[1]
% \end{verbatim}
% \end{quote}
% 
% \subsection{Command Mode}

% Command mode enables the author to use calculated shapes by
% outputting the $\backslash$parshape command as a single operation at
% the end of the calculation.

% \DescribeMacro{\parshapeary}
% This macro takes one parameter, being the name of an array. The
% contents of the array are simply expanded and passed directly to
% \texttt{$\backslash$parshape} --- the first parameter is the number
% of lines, then for each line the left margin and line width are
% supplied in subsequent elements.
%
% For example:
% \begin{quote}
% \begin{verbatim}
% \newcommand{\ltest}{50pt}
% \newlength{\test}\setlength{\test}{300pt}
% \newarray{sizes}\readarray{sizes}{2&0em&\the\test&\ltest&\test}
% \parshapeary{sizes}
% \lipsum[1]
% \end{verbatim}
% produces:
%
% \parshape 2 0em 300pt 50pt 300pt \lipsum[1]
% \end{quote}
%
% 
% \DescribeMacro{\parshapearray} This macro takes two parameters. The
% first is also the name of an array. The only difference to
% \texttt{$\backslash$parshapeary} is that instead of passing the
% width of the line, the width of the right margin is passed
% instead. This means the macro needs to know the width of the line.
% 
% The second parameter is the length of the line. This is usually
% $\backslash$columnwidth, passing any other value will effectively
% change the right margin. ($\backslash$columnwidth is often equal to
% $\backslash$textwidth, but in multi-column mode,
% $\backslash$columnwidth is more likely to be correct, unless you
% want to overstrike the text with text in another column --- so
% $\backslash$columnwidth is the recommended length to use).
%
% In a similar vein to the previous example:
% \begin{quote}
% \begin{verbatim}
%\newcommand{\ltest}{50pt}
%\newlength{\test}\setlength{\test}{75pt}
%\newlength{\cwidth}\setlength{\cwidth}{\columnwidth}
%\addtolength{\cwidth}{-50pt}
%
%\newarray{sizes}\readarray{sizes}{2&0em&\the\test&\ltest&\test}
%\parshapearray{sizes}{\cwidth}
%\lipsum[1]
%
% \end{verbatim}
% which produces:
%
% \parshape 2 0.0pt
%220.0pt
%50.0pt
%170.0pt
% \lipsum[1]
% \end{quote}
% 
% \DescribeMacro{\Parshapearray}
% This macro also takes two parameters, and is used to combine
% multiple shapes, where the width of the paragraph is not consistent
% throughout the paragraph.
% 
% The first parameter is the name of an array, in the same format as
% the first parameter to \texttt{$\backslash$parshapeary}.
% 
% The second parameter is the name of a second array. The first
% element is the number of lines in this second array, and subsequent
% elements are the widths of lines (excluding margins) in that array
% --- starting from the first line. As usual, if an insufficient
% number of lines are passed, the last line will be re-used.
% 
% The actual width of a line will be the total width excluding margins
% (as per the second parameter), minus the left margin (taken from the
% first parameter, even indexes), minus the right margin (as per the
% first parameter, odd indexes).
% 
% In this way, it is possible to set a shaped paragraph that allows
% for non-straight margins or non-rectangular paper --- for example, to
% typeset a list item in such a way as to allow for a cut-out on the
% page.
% 
% For a larger example, consider that the paper has a sloped shape
% that extends 1em wider for every line for the first 15 lines
% only. The author wishes to set a text in an quadrilateral, with
% margins offset $\frac{1}{8}\verb!"!$ to the right for each line, but
% extending equally to follow the width of the paper.

% \begin{quote}
% \begin{verbatim}
% \newarray{quad}
% \readarray{quad}{17 & 0.000in & 2.000in & 0.125in & 1.875in & 
%   0.250in & 1.750in & 0.375in & 1.625in & 0.500in & 1.500in &
%   0.625in & 1.375in & 0.750in & 1.250in & 0.875in & 1.125in &
%   1.000in & 1.000in & 1.125in & 0.875in & 1.250in & 0.750in &
%   1.375in & 0.675in & 1.500in & 0.500in & 1.625in & 0.375in &
%   1.750in & 0.250in & 1.875in & 0.125in & 2.000in & 0.000in}
% \newarray{papershape}
% \readarray{papershape}{15& 25em & 26em & 27em & 28em & 29em & 30em & 31em 
%             & 32em & 33em & 34em & 35em & 36em & 37em & 38em & 39em}
% \Parshapearray{quad}{papershape} \lipsum[1]
% \end{verbatim}
% Produces:
%
% \parshape 17
% 0.0pt 
% 105.46039pt 
% 9.03374pt 
% 115.46042pt 
% 18.06749pt 
% 125.46043pt 
% 27.10124pt 
% 135.46045pt 
% 36.135pt 
% 145.46045pt 
% 45.16875pt 
% 155.46046pt 
% 54.2025pt 
% 165.46048pt 
% 63.23624pt 
% 175.46051pt 
% 72.26999pt 
% 185.46053pt 
% 81.30374pt 
% 195.46054pt 
% 90.3375pt 
% 205.46054pt 
% 99.37125pt 
% 211.84685pt 
% 108.405pt 
% 225.46057pt 
% 117.43874pt 
% 235.4606pt 
% 126.47249pt 
% 245.46062pt 
% 135.50624pt 
% 235.4606pt 
% 144.54pt 
% 235.46059pt \lipsum[1]
% \end{quote}
%


% \section{Prerequisites}

% This package requires the \texttt{arrayjob} package from
% CTAN\footnote{http://tug.ctan.org/cgi-bin/ctanPackageInformation.py?id=arrayjob}. Arrays
% are used as a convenient mechanism to pass values to functions,
% although they may not be used in environment mode.

% \section{Limitations and Possible Improvements}

% \begin{itemize}
% \item Usage of this package can be slow, because two temporary files
%   are used for each $\backslash$parshape. Theoretically, only one
%   should be needed and so it should be possible to improve this.
% \item There is no support for combining arrays, other than to change
%   the paper size itself. Extra commands could be provided to
%   calculate the intersection of two cutouts, or to add margins
%   together.
% \item In a future version, it may be possible to avoid temporary
%   files completely by using token registers, or
%   $\backslash$aftergroup, with some form of string processing.
% \end{itemize}

% \section{Package Name}

% The somewhat obscure name ``rjlpshap'' was chosen following the
% guidelines given in \textit{\LaTeXe\ for Class and Package
%   Writers}\footnote{\texttt{http://www.tex.ac.uk/tex-archive/macros/latex/doc/clsguide.pdf}}~(section~2.7.3,
% ``Make it Portable''). The common prefix used by these packages
% is~''rjl--'', which was chosen as the author's initials as he is
% not writing these packages as part of any organisation.

% The postfix of ``--pshap'' was chosen as a contraction of
% ``parshape'', the \TeX\ command to which this package is a front
% end. The name was contracted due to the 5-character length
% restriction. It was also considered that that the obvious package
% name of ``parshape'' would be best avoided to avoid confusion with
% the existing shapepar\footnote{\texttt{http://www.ctan.org/tex-archive/macros/latex/contrib/shapepar/}} package, and also because parshape is a
% standard \TeX\ command --- the only requirement that exists is to
% avoid the name of a standard package, but avoiding the name of a
% standard macro also seems like a good idea as this leaves the name
% free for use as a standard package name in the future.

% \section{Other References}

% The following references were essential in producing this package:

% \begin{itemize}
% \item The \TeX Book\footnote{ISBN:~978-0201134483} 
% \item \TeX Live package
%   contributions\footnote{http://tug.org/texlive/pkgcontrib.html}
% \item TDS Guidelines\footnote{http://dante.ctan.org/TDS-guidelines.html}
% \end{itemize}

% \StopEventually{\PrintChanges\PrintIndex}
% 
% \section{Implementation}
% 
% Arrayjob: we need to pass arrays of lengths and length-commands,
% so build on the established array handling functionality.
%    \begin{macrocode}
\RequirePackage{arrayjob}
%    \end{macrocode}

% Forloop: we need to iterate over the arrays that are passed in
%    \begin{macrocode}
\RequirePackage{forloop}
%    \end{macrocode}
% Internal commands use @ as a letter, not a special character, so
% switch catcodes
%    \begin{macrocode}
\makeatletter
%    \end{macrocode}


% \subsection{Environment mode}

% \begin{environment}{parshapecollect}
%   Environment to handle writing the file, cleaning up etc.
%   
%   Note the importance of the % at the end of each line here: we're
%   in horizontal mode so any space characters get expanded and added
%   into the start of the paragraph. Any spaces here are output before
%   $\backslash$parshape itself, and so will be visible in the output
%   page. The $\backslash$ignorespaces is a last line of defence
%   against any extra spaces inadvertently introduced by the user.
%
%    \begin{macrocode}
\newenvironment{parshapecollect}{%
  \immediate\openout\rjlpshap@writer=\jobname.parshape%
  \setcounter{rjlpshap@linecount}{0}%
  \setboolean{rjlpshap@isodd}{false}%
  \ignorespaces
}{%
  \immediate\closeout\rjlpshap@writer%
%    \end{macrocode}
% Because the environment forms a group, we need to use aftergroup to
% delay the $\backslash$parshape command. Otherwise the group will end first and
% $\backslash$parshape will be discarded.
%    \begin{macrocode}
  \rjlpshap@doparshape%
  \aftergroup\input\aftergroup{\aftergroup\jobname\aftergroup%
    .\aftergroup%
    p\aftergroup%
    a\aftergroup%
    r\aftergroup%
    s\aftergroup%
    h\aftergroup%
    a\aftergroup%
    p\aftergroup%
    e\aftergroup%
    t\aftergroup%
    m\aftergroup%
    p\aftergroup}\ignorespaces
}
%    \end{macrocode}
% \end{environment}

% \begin{macro}{\rjlpshap@doparshape}
%   Internal method to handle the final processing of the built
%   up $\backslash$parshape command. The lengths have been written to
%   the first temporary file, so write the entire $\backslash$parshape
%   command to the second one, ready to be input.
%    \begin{macrocode}
\newcommand{\rjlpshap@doparshape}{%
  \immediate\openout\rjlpshap@finalwriter=\jobname.parshapetmp%
  \immediate\write\rjlpshap@finalwriter{\noexpand\parshape \arabic{rjlpshap@linecount}}%
  \openin\rjlpshap@reader=\jobname.parshape%
  \setboolean{rjlpshap@loop}{true}%
  \whiledo{\boolean{rjlpshap@loop}}{%
    \read\rjlpshap@reader to\rjlpshap@temp%
%    NB: \ifeof matches \loop...\repeat
    \ifeof\rjlpshap@reader%
    \setboolean{rjlpshap@loop}{false}%
    \else
    \immediate\write\rjlpshap@finalwriter{\rjlpshap@temp }%
    \fi
  }%
  \immediate\closeout\rjlpshap@finalwriter%
  \immediate\closein\rjlpshap@reader%
  \let\rjlpshap@temp=\relax%
}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\parshapelenout}
%   Used inside a parshapecollect environment, writes length \#1 to
%   the $\backslash$parshape command file. (If used anywhere else,
%   it'll just write to the console since the file will not be open).
%    \begin{macrocode}
\newcommand{\parshapelenout}[1]{%
  \setlength{\rjlpshap@tempwidth}{#1}%
  \immediate\write\rjlpshap@writer{\the\rjlpshap@tempwidth}%
  \ifthenelse{\boolean{rjlpshap@isodd}}{%
    \setboolean{rjlpshap@isodd}{false}%
  }{%
    \stepcounter{rjlpshap@linecount}%
    \setboolean{rjlpshap@isodd}{true}%
  }%
  \ignorespaces
}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\parshapearrlenout}
%   Used inside a parshapecollect environment, writes a length to the
%   $\backslash$parshape command file.  As $\backslash$parshapelenout,
%   except that the element is passed as the member of an array.
%   
%   Length is taken from array with name \#1, element at index \#2
%    \begin{macrocode}
\newcommand{\parshapearrlenout}[2]{%
  \testarray{#1}(\arabic{#2})%
  \parshapelenout{\temp@macro}%
  \ignorespaces
}
%    \end{macrocode}
% \end{macro}

% \subsection{Command Mode}

% \begin{macro}{\parshapeary}
%   As $\backslash$parshape, but takes one argument being an array
%   name defined in arrayjob form. The array contains the arguments,
%   starting with the count at index 1, then one length per array
%   element.
%    \begin{macrocode}
\newcommand{\parshapeary}[1]{%
  \testarray{#1}(1)%
  \edef\rjlpshap@max{\temp@macro}%
  \begin{parshapecollect}%
    \forloop{rjlpshap@ctr}{1}{\not \value{rjlpshap@ctr} > \rjlpshap@max }{%
      \setcounter{rjlpshap@ctr2}{\value{rjlpshap@ctr}}%
      \addtocounter{rjlpshap@ctr2}{\value{rjlpshap@ctr}}%
      \parshapearrlenout{#1}{rjlpshap@ctr2}%
      \stepcounter{rjlpshap@ctr2}%
      \parshapearrlenout{#1}{rjlpshap@ctr2}%
    }%
  \end{parshapecollect}%
  \typeout{parshapeary end}%
  \ignorespaces
}
%    \end{macrocode}
% \end{macro}


% \begin{macro}{\parshapearray}
%   As $\backslash$parshapeary, but the second parameter is the name
%   of a single-parameter macro taking a number and returning the
%   width of the line on that line
%    \begin{macrocode}
\newcommand{\parshapearray}[2]{%
  \begin{parshapecollect}%
    \testarray{#1}(1)%
    \edef\rjlpshap@max{\temp@macro}%
    \forloop{rjlpshap@ctr}{1}{\not \value{rjlpshap@ctr} > \rjlpshap@max }{%
      \setcounter{rjlpshap@ctr2}{\value{rjlpshap@ctr}}%
      \addtocounter{rjlpshap@ctr2}{\value{rjlpshap@ctr}}%
      \edef\rjlpshap@pos{\arabic{rjlpshap@ctr2}}%
      \testarray{#1}(\rjlpshap@pos)%
      \setlength{\rjlpshap@tempwidth}{\temp@macro}%
      \setlength{\rjlpshap@templinewidth}{#2}%
      \addtolength{\rjlpshap@templinewidth}{-1\rjlpshap@tempwidth}%
      \parshapelenout{\rjlpshap@tempwidth}%
      \stepcounter{rjlpshap@ctr2}%
      \edef\rjlpshap@pos{\arabic{rjlpshap@ctr2}}%
      \testarray{#1}(\rjlpshap@pos)%
      \setlength{\rjlpshap@tempwidth}{\temp@macro}%
      \addtolength{\rjlpshap@templinewidth}{-1\rjlpshap@tempwidth}%
      \parshapelenout{\rjlpshap@templinewidth}%
    }%
  \end{parshapecollect}%
}
%    \end{macrocode}
% \end{macro}


% \begin{macro}{\Parshapearray}
%   First parameter is as $\backslash$parshapea\{r,rra\}y, but each pair
%   is left and right margin rather than left margin and text width,
%   while the second tracks the page width.
%   
%   \textit{i.e.}
%   
%   The first parameter (an array) is the shape of the paragraph
%   relative to the page.
%   \begin{itemize}
%   \item first element is the number of pairs of lengths in the array
%   \item subsequent arguments are pairs of lengths, left margin width then
%     right margin width.
%   \end{itemize}
%   
%   The second parameter is the overall text width. This is given in the
%   following format:
%   \begin{itemize}
%   \item first element is the number lengths
%   \item subsequent elements are one width per parameter
%   \end{itemize}
%    \begin{macrocode}
\newcommand{\Parshapearray}[2]{%
  \testarray{#1}(1)\edef\rjlpshap@maxA{\temp@macro}%
  \testarray{#2}(1)\edef\rjlpshap@maxB{\temp@macro}%
  \ifthenelse{\rjlpshap@maxA > \rjlpshap@maxB} {\edef\rjlpshap@max{\rjlpshap@maxA}}{\edef\rjlpshap@max{\rjlpshap@maxB}}%
  \begin{parshapecollect}%
    \forloop{rjlpshap@ctr}{1}{\not \value{rjlpshap@ctr} > \rjlpshap@max}{%
      \ifthenelse{\value{rjlpshap@ctr} > \rjlpshap@maxA}{%
        \setcounter{rjlpshap@ctr2}{\rjlpshap@maxA}%
        \addtocounter{rjlpshap@ctr2}{\rjlpshap@maxA}%
      }{%
        \setcounter{rjlpshap@ctr2}{\value{rjlpshap@ctr}}%
        \addtocounter{rjlpshap@ctr2}{\value{rjlpshap@ctr}}%
      }%
%    \end{macrocode}
% left margin from \#1:
%    \begin{macrocode}
      \parshapearrlenout{#1}{rjlpshap@ctr2}%
%    \end{macrocode}
% get the line width
%    \begin{macrocode}
      \ifthenelse{\value{rjlpshap@ctr} > \rjlpshap@maxB}{%
        \edef\rjlpshap@pos{\rjlpshap@maxB}%
        \setcounter{rjlpshap@ctr3}{\rjlpshap@maxB}%
        \typeout{A pos=\rjlpshap@pos\space of \rjlpshap@maxB}%
        \testarray{#2}(\arabic{rjlpshap@ctr3})%
        \typeout{temp=\temp@macro}%
        \setlength{\rjlpshap@templinewidth}{\temp@macro}%
      }{%
        \stepcounter{rjlpshap@ctr}%
        \edef\rjlpshap@pos{\arabic{rjlpshap@ctr}}%
        \typeout{B pos=\rjlpshap@pos}%
        \addtocounter{rjlpshap@ctr}{-1}%
        \testarray{#2}(\rjlpshap@pos)%
        \setlength{\rjlpshap@templinewidth}{\temp@macro}%
      }%
      \typeout{width=\the\rjlpshap@templinewidth}%
%    \end{macrocode}
% subtract the left margin from the line width
%    \begin{macrocode}
      \addtolength{\rjlpshap@templinewidth}{-1\rjlpshap@tempwidth}%
%    \end{macrocode}
% subtract the right margin from the line width
%    \begin{macrocode}
      \stepcounter{rjlpshap@ctr2}%
      \edef\rjlpshap@pos{\arabic{rjlpshap@ctr2}}%
      \testarray{#1}(\rjlpshap@pos)%
      \setlength{\rjlpshap@tempwidth}{\temp@macro}%
      \addtolength{\rjlpshap@templinewidth}{-1\rjlpshap@tempwidth}%
      \parshapelenout{\rjlpshap@templinewidth}%
    }%
  \end{parshapecollect}%
}
%    \end{macrocode}
% \end{macro}

% \subsection{Internal Definitions}

% rjlpshap@ctr: outermost loop counter:
%    \begin{macrocode}
\newcounter{rjlpshap@ctr}
%    \end{macrocode}

% rjlpshap@ctr2: used for index calculations internally:
%    \begin{macrocode}
\newcounter{rjlpshap@ctr2}
%    \end{macrocode}

% rjlpshap@ctr3: used for index calculations internally:
%    \begin{macrocode}
\newcounter{rjlpshap@ctr3}
%    \end{macrocode}

% rjlpshap@tempwidth: used as a register to read widths from arrays,
% and for calculations
%    \begin{macrocode}
\newlength{\rjlpshap@tempwidth}
%    \end{macrocode}

% rjlpshap@templinewidth: used as a register to calculate the line
% width when subtracting margins:
%    \begin{macrocode}
\newlength{\rjlpshap@templinewidth}
%    \end{macrocode}

% boolean used for breaking out of loops
%    \begin{macrocode}
\newboolean{rjlpshap@loop}
%    \end{macrocode}

% boolean used to track if the number of lengths output is odd or even
%    \begin{macrocode}
\newboolean{rjlpshap@isodd}
%    \end{macrocode}

% Filehandles needed for reading and writing temporary files
%    \begin{macrocode}
\newwrite\rjlpshap@writer % holds \parshape lengths
\newwrite\rjlpshap@finalwriter  % holds entire \parshape command
\newread\rjlpshap@reader % used to read writer to transfer to finalwriter
%    \end{macrocode}

% rjlpshap@linecount: counts the number of lines read in the environment
%    \begin{macrocode}
\newcounter{rjlpshap@linecount}
%    \end{macrocode}

% Finally, undo the effect of $\backslash$makeatletter, and make @ be
% a special character again.
%    \begin{macrocode}
\makeatother
%    \end{macrocode}

% \Finale
\endinput