diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/cutwin/cutwin.dtx')
-rwxr-xr-x | Master/texmf-dist/source/latex/cutwin/cutwin.dtx | 1019 |
1 files changed, 1019 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/cutwin/cutwin.dtx b/Master/texmf-dist/source/latex/cutwin/cutwin.dtx new file mode 100755 index 00000000000..e04aca02c8b --- /dev/null +++ b/Master/texmf-dist/source/latex/cutwin/cutwin.dtx @@ -0,0 +1,1019 @@ +%% \iffalse meta-comment +% +% cutwin.dtx +% Author: Peter Wilson, Herries Press (herries dot press at earthlink dot net) +% and Alan Hoenig +% Copyright 2010 Peter R. Wilson +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either +% version 1.3 of this license or (at your option) any +% later version. +% The latest version of the license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of +% LaTeX version 2003/06/01 or later. +% +% This work has the LPPL maintenance status "author-maintained". +% +% This work consists of the files listed in the README file. +% +%<*driver> +\documentclass[twoside]{ltxdoc} +\usepackage{alltt} +\usepackage{cutwin} +%\usepackage[draft=false, +% plainpages=false, +% pdfpagelabels, +% bookmarksnumbered, +% hyperindex=false +% ]{hyperref} +\providecommand{\phantomsection} +\show\makeatletter +\makeatletter + \@mparswitchfalse +\makeatother +\renewcommand{\MakeUppercase}[1]{#1} +\pagestyle{headings} +\EnableCrossrefs +\CodelineIndex +%%\OnlyDescription +\setcounter{StandardModuleDepth}{1} +\begin{document} + \raggedbottom + \DocInput{cutwin.dtx} +\end{document} +%</driver> +% +% \fi +% +% \CheckSum{720} +% +% \DoNotIndex{\',\.,\@M,\@@input,\@addtoreset,\@arabic,\@badmath} +% \DoNotIndex{\@centercr,\@cite} +% \DoNotIndex{\@dotsep,\@empty,\@float,\@gobble,\@gobbletwo,\@ignoretrue} +% \DoNotIndex{\@input,\@ixpt,\@m} +% \DoNotIndex{\@minus,\@mkboth,\@ne,\@nil,\@nomath,\@plus,\@set@topoint} +% \DoNotIndex{\@tempboxa,\@tempcnta,\@tempdima,\@tempdimb} +% \DoNotIndex{\@tempswafalse,\@tempswatrue,\@viipt,\@viiipt,\@vipt} +% \DoNotIndex{\@vpt,\@warning,\@xiipt,\@xipt,\@xivpt,\@xpt,\@xviipt} +% \DoNotIndex{\@xxpt,\@xxvpt,\\,\ ,\addpenalty,\addtolength,\addvspace} +% \DoNotIndex{\advance,\Alph,\alph} +% \DoNotIndex{\arabic,\ast,\begin,\begingroup,\bfseries,\bgroup,\box} +% \DoNotIndex{\bullet} +% \DoNotIndex{\cdot,\cite,\CodelineIndex,\cr,\day,\DeclareOption} +% \DoNotIndex{\def,\DisableCrossrefs,\divide,\DocInput,\documentclass} +% \DoNotIndex{\DoNotIndex,\egroup,\ifdim,\else,\fi,\em,\endtrivlist} +% \DoNotIndex{\EnableCrossrefs,\end,\end@dblfloat,\end@float,\endgroup} +% \DoNotIndex{\endlist,\everycr,\everypar,\ExecuteOptions,\expandafter} +% \DoNotIndex{\fbox} +% \DoNotIndex{\filedate,\filename,\fileversion,\fontsize,\framebox,\gdef} +% \DoNotIndex{\global,\halign,\hangindent,\hbox,\hfil,\hfill,\hrule} +% \DoNotIndex{\hsize,\hskip,\hspace,\hss,\if@tempswa,\ifcase,\or,\fi,\fi} +% \DoNotIndex{\ifhmode,\ifvmode,\ifnum,\iftrue,\ifx,\fi,\fi,\fi,\fi,\fi} +% \DoNotIndex{\input} +% \DoNotIndex{\jobname,\kern,\leavevmode,\let,\leftmark} +% \DoNotIndex{\list,\llap,\long,\m@ne,\m@th,\mark,\markboth,\markright} +% \DoNotIndex{\month,\newcommand,\newcounter,\newenvironment} +% \DoNotIndex{\NeedsTeXFormat,\newdimen} +% \DoNotIndex{\newlength,\newpage,\nobreak,\noindent,\null,\number} +% \DoNotIndex{\numberline,\OldMakeindex,\OnlyDescription,\p@} +% \DoNotIndex{\pagestyle,\par,\paragraph,\paragraphmark,\parfillskip} +% \DoNotIndex{\penalty,\PrintChanges,\PrintIndex,\ProcessOptions} +% \DoNotIndex{\protect,\ProvidesClass,\raggedbottom,\raggedright} +% \DoNotIndex{\refstepcounter,\relax,\renewcommand,\reset@font} +% \DoNotIndex{\rightmarnnnnnnngin,\rightmark,\rightskip,\rlap,\rmfamily,\roman} +% \DoNotIndex{\roman,\secdef,\selectfont,\setbox,\setcounter,\setlength} +% \DoNotIndex{\settowidth,\sfcode,\skip,\sloppy,\slshape,\space} +% \DoNotIndex{\symbol,\the,\trivlist,\typeout,\tw@,\undefined,\uppercase} +% \DoNotIndex{\usecounter,\usefont,\usepackage,\vfil,\vfill,\viiipt} +% \DoNotIndex{\viipt,\vipt,\vskip,\vspace} +% \DoNotIndex{\wd,\xiipt,\year,\z@} +% +% \changes{v0.1}{2010/09/29}{First public release} +% +% \def\dtxfile{cutwin.dtx} +% \def\fileversion{v0.1} \def\filedate{2010/09/29} +% \newcommand*{\Lpack}[1]{\textsf {#1}} ^^A typeset a package +% \newcommand*{\Lopt}[1]{\textsf {#1}} ^^A typeset an option +% \newcommand*{\file}[1]{\texttt {#1}} ^^A typeset a file +% \newcommand*{\Lcount}[1]{\textsl {\small#1}} ^^A typeset a counter +% \newcommand*{\pstyle}[1]{\textsl {#1}} ^^A typeset a pagestyle +% \newcommand*{\Lenv}[1]{\texttt {#1}} ^^A typeset an environment +% \newcommand*{\ablankline}{\vspace{\baselineskip}} +% +% \title{Making cutouts in paragraphs\thanks{This +% file (\texttt{\dtxfile}) has version number \fileversion, last revised +% \filedate.}} +% +% \author{% +% Peter Wilson\thanks{Herries Press, \texttt{herries dot press at earthlink dot net}} +% and Alan Hoenig +% } +% \date{\filedate} +% \maketitle +% \begin{abstract} +% The \Lpack{cutwin} package helps in making a cutout window in the middle +% of a paragraph. +% +% \end{abstract} +% \tableofcontents +% +% +% +% \section{Introduction} +% +% ^^A Based on Alan Hoenig, `TeX Does Windows --- The Conclusion', +% ^^A TUGboat, 8, 2 pp211-215, 1987 +% +% +% This manual is typeset according to the conventions of the +% \LaTeX{} \textsc{docstrip} utility which enables the automatic +% extraction of the \LaTeX{} macro source files~\cite{COMPANION}. +% +% Section~\ref{sec:usc} describes the usage of the \Lpack{cutwin} +% package and +% commented source code is in Section~\ref{sec:code}. +% +% \section{The \Lpack{cutwin} package} \label{sec:usc} +% +% The code provided by the \Lpack{cutwin} package is meant to help +% in creating windows, or cutouts, in a text-only paragraph. It is +% based on code originally published by Alan Hoenig~\cite{HOENIG87}. +% +% \subsection{General} +% +% \DescribeMacro{\opencutleft} +% \DescribeMacro{\opencutright} +% \DescribeMacro{\opencutcenter} +% Declarations specifying where a window is to be placed. The choices +% are: \cs{opencutleft} open into the left margin, \cs{opencutright} +% open into the right margin, and \cs{opencutcenter}, which is the default, +% open in the `center' of the text, i.e, have text on both sides of the +% window. +% +% \DescribeMacro{\cutfuzz} +% This is provided as a convenience to reduce the number of overfull +% and underfull warnings. Its default definition is: +% \begin{verbatim} +% \newcommand{\cutfuzz}{% +% \vbadness=50000 +% \hbadness=50000 +% \sloppy} +% \end{verbatim} +% and it is only applied to the paragraph being windowed. +% +% \subsection{Rectangular cutouts} +% +% \newcommand*{\tinwin}{% +% \centering\bfseries +% Text \\ in \\Window \par} +% \newcommand*{\qinwin}{% +% \centering\bfseries\Huge ?\, +% \par} +% \let\windowpagestuff\tinwin +% \begin{cutout}{2}{0.2\textwidth}{0.4\textwidth}{3} +% A rectangular space can be placed in a paragraph with the text flowing +% across the gap. The space may break open into the top or side of the +% paragraph or, with some care, into the bottom (the number of lines +% specified for the cutout should not exceed the amount of text +% available for those lines). Some text or a logo or +% graphic may be placed within the window, or it may be left empty. +% In this instance I have put three short bold text lines in the window +% opening. The window should not be too wide as it can be difficult +% to track the exterior text lines across the gap. +% \end{cutout} +% +% \DescribeEnv{cutout} +% The |cutout| environment, the body of which must be a single paragraph, +% enables a rectangular window to be cut out of the paragraph with the +% text flowing across the cutout. Use as:\\ +% \verb?\begin{cutout}?\marg{numtop}\marg{leftwidth}\marg{rightwidth}\marg{numcut} \\ +% where \meta{numtop} is the number of full lines above the window +% and \meta{numcut} is the number of lines to be cut (giving the height +% of the window). +% The meaning of the lengths \meta{leftwidth} and \meta{rightwidth} depend +% on the location of the cutout: +% \begin{itemize} +% \item for a centered cutout \meta{leftwidth} and \meta{rightwidth} are the +% lengths of the text lines at the left and right sides of the window; +% \item for an open left cutout \meta{leftwidth} is ignored and +% \meta{rightwidth} is the length of the lines to the right of the cutout; and +% \item for an open right cutout \meta{rightwidth} is ignored and +% \meta{leftwidth} is the length of the lines at the left of the cutout. +% \end{itemize} +% +% +% \DescribeMacro{\pageinwindow} +% \DescribeMacro{\windowpagestuff} +% The macro \cs{pageinwindow} puts a zero-sized |picture| positioned +% at the left of the window aligned with the first line of the window (i.e, +% at the top left of the cutout). +% The |picture| consists of a |minipage| sized to fit the window. +% The contents of the minipage is \cs{windowpagestuff}. These two +% macros may be used to put a graphic or text into the windowed area. +% +% The default definition of \cs{windowpagestuff} is: \\ +% \verb?\newcommand*{\windowpagestuff}{}? \\ +% and you can change it as you wish. For instance, I used the following +% to put some text centrally within the above cutout. +% \begin{verbatim} +% \renewcommand*{\windowpagestuff}{% +% \centering\bfseries +% Text \\ in \\ Window \par} +% \end{verbatim} +% You may well need to experiment to get everything adjusted to your +% satisfaction. +% +% \subsection{Shaped cutouts} +% +% \newcommand*{\mycut}{% +% 0.1\textwidth, 0.3\textwidth, +% 0.2\textwidth, 0.4\textwidth, +% 0.3\textwidth, 0.5\textwidth} +% \renewcommand*{\putstuffinpic}{% +% \put(0,-8){\makebox(0,0){\Huge\bfseries \$}}} +% +% \begin{shapedcutout}{2}{3}{\mycut} +% A \emph{shaped cutout} is one where the shape of the window is +% specified by the user who has to supply the length of the text lines +% bordering the cutout. Normally there is text on either side of the +% window but it could be open at either the left or right side of +% the paragraph. It is possible to put a logo or some text in the +% window. In this paragraph with a shaped cutout I have used a large +% \$ sign as a simple logo. +% \end{shapedcutout} +% +% +% \DescribeEnv{shapedcutout} +% The |shapedcutout| environment, the body of which must be a single paragraph, +% enables an arbitrary shaped window to be cut out of the paragraph with the +% text flowing across the cutout. Use as:\\ +% \verb?\begin{shapedcutout}?\marg{numtop}\marg{numcut}\marg{shapespec} +% where \meta{numtop} is the number of full lines above the window, +% \meta{numcut} is the number of lines to be cut (giving the height of +% the window) and +% \meta{shapespec} is the specification of the length of the lines +% bordering the cutout. +% +% More precisely \meta{shapespec} is a comma-separated list of the +% lengths of the +% text lines bordering the window. +% \begin{itemize} +% \item For a centered cutout one pair of entries are required for each cut +% line denoting the length of the left and right part of the cut line. +% There must be exactly \meta{numcut} pairs. +% \item +% For example you might do something along the lines of: +% \begin{verbatim} +% \newcommand*{\mycut}{% +% 0.1\textwidth, 0.3\textwidth, +% 0.2\textwidth, 0.4\textwidth, +% 0.3\textwidth, 0.5\textwidth} +% \begin{shapedcutout}{2}{3}{\mycut} +% ... +% \end{verbatim} +% which is what I used to create the shaped cutout above. +% \item For an open cutout each entry is the text length of a line. There must +% be exactly \meta{numcut} entries. For instance, given the above definition +% of \cs{mycut} then a call out for an open window would be like: \\ +% \verb?\begin{shapedcutout}{2}{6}{\mycut}? +% \end{itemize} +% +% \DescribeMacro{\picinwindow} +% In a shaped cutout the macro \cs{picinwindow} is placed at the center +% of the gap in the first line of the +% cutout. The default \cs{picinwindow} is a zero-sized picture whose contents +% is \cs{putstuffinpic}. +% +% \cs{picinwindow} and \cs{putstuffinpic} are initially defined as +% \begin{verbatim} +% \newcommand*{\picinwindow}{% +% \begin{picture}(0,0) +% \putstuffinpic +% \end{picture}} +% \newcommand*{\putstuffinpic}{} +% \end{verbatim} +% +% You can change \cs{putstuffinpic} to place what you want in the picture. +% For example, to put the large \$ symbol in the shaped cutout paragraph above +% I used: +% \begin{verbatim} +% \renewcommand*{\putstuffinpic}{% +% \put(0,-8){\makebox(0,0){\Huge\bfseries \$}}} +% \end{verbatim} +% You have to adjust the placement to suit your purposes and the shape of +% the cutout. +% +% \StopEventually{ +% \bibliographystyle{alpha} +% \begin{thebibliography}{GMS04} +% \bibitem[GM04]{COMPANION} +% Frank Mittelbach and Michel Goossens. +% \newblock \emph{The LaTeX Companion}. Second edition. +% \newblock Addison-Wesley Publishing Company, 2004. +% \bibitem[Hoe87]{HOENIG87} +% Alan Hoenig. +% \newblock TeX does windows --- The conclusion, +% \newblock \emph{TUGboat}, vol 8, no 2, pp 211--215, 1987. +% \end{thebibliography} +% } +% +% +% \clearpage +% \section{The package code} \label{sec:code} +% +% To try and avoid name clashes, all the internal commands include +% the string |c@tw|. +% +% \subsection{Preliminaries} +% +% Announce the name and version of the package, which requires +% \LaTeXe. +% \begin{macrocode} +%<*pkg> +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{cutwin}[2010/09/29 v0.1 cutout windows] + +% \end{macrocode} +% +% +% \subsection{General} +% +% \begin{macro}{\c@twwinlines} +% \begin{macro}{\c@twtoplines} +% \begin{macro}{\c@twcnt} +% We need lots of variables. First some counts. +% \begin{macrocode} +\newcount\c@twwinlines % window lines +\newcount\c@twtoplines % top lines +\newcount\c@twcnt % a count + +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\c@twlftside} +% \begin{macro}{\c@twrtside} +% \begin{macro}{\c@twtopht} +% \begin{macro}{\c@twvsilg} +% And some lengths. +% \begin{macrocode} +\newdimen\c@twlftside % left width +\newdimen\c@twrtside % right width +\newdimen\c@twtopht % height of top text +\newdimen\c@twvsilg % Vertical Shift or InterLine Glue + +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\c@twtoka} +% \begin{macro}{\c@twtokb} +% And some tokens. +% \begin{macrocode} +\newtoks\c@twtoka % build of parshape spec +\newtoks\c@twtokb % build of parshape spec + +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\c@twrawtext} +% \begin{macro}{\c@twholdwin} +% \begin{macro}{\c@twwindow} +% \begin{macro}{\c@twfinaltext} +% \begin{macro}{\c@twslicea} +% \begin{macro}{\c@twsliceb} +% And some boxes. +% \begin{macrocode} +\newbox\c@twrawtext % text as input +\newbox\c@twholdwin % text for window sides +\newbox\c@twwindow % composed window +\newbox\c@twfinaltext % final assembled cutout paragraph +\newbox\c@twslicea % slice A of window text +\newbox\c@twsliceb % slice B of window text + +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\opencutleft} +% \begin{macro}{\opencutright} +% \begin{macro}{\opencutcenter} +% \begin{macro}{\c@twl@c} +% User commands for positioning a cutout; left, right, or center. +% The default is \cs{opencutcenter}. +% \cs{c@twl@c} is the internal representation. +% \begin{macrocode} +\newcommand*{\opencutleft}{\def\c@twl@c{-1}} +\newcommand*{\opencutright}{\def\c@twl@c{1}} +\newcommand*{\opencutcenter}{\def\c@twl@c{0}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macrocode} +\opencutcenter + +% \end{macrocode} +% +% \begin{macro}{\cutfuzz} +% An attempt to stop TeX moaning about over/under full h/v boxes. +% \begin{macrocode} +\newcommand{\cutfuzz}{\vbadness=50000 + \hbadness=50000 +% \hfuzz=1pt + \sloppy} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\c@twcalcilg} +% Calculate the interline glue. +% \begin{macrocode} +\newcommand*{\c@twcalcilg}{% + \c@twvsilg=\baselineskip + \setbox0=\hbox{(} + \advance\c@twvsilg-\ht0 \advance\c@twvsilg-\dp0} + +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Rectangular cutouts} +% +% \begin{macro}{\pageinwindow} +% \begin{macro}{\windowpagestuff} +% User modifiable macros for putting (\cs{pageinwindow}), via a +% zero-sized picture, +% stuff (\cs{windowpagestuff}) in a cutout window. +% \begin{macrocode} +\newcommand*{\pageinwindow}{% + \@tempdimc=\c@twwinlines\baselineskip % cutout height + \@tempdimb=\hsize + \ifnum\c@twl@c=\m@ne % openleft + \advance\@tempdimb -\c@twrtside + \else + \ifnum\c@twl@c=\@ne % openright + \advance\@tempdimb -\c@twlftside + \else% center + \advance\@tempdimb - \c@twlftside + \advance\@tempdimb - \c@twrtside + \fi + \fi + \begin{picture}(0,0)% + \put(0,0){% + \raisebox{4pt}{% +%\fbox{% + \begin{minipage}[t][\@tempdimc][c]{\@tempdimb} + \windowpagestuff + \end{minipage} +%}% end fbox + }% end raisebox + }% end put + \end{picture}} +\newcommand*{\windowpagestuff}{} + +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{environment}{cutout} +% The environment for cutting a rectangular window from a paragraph. +% +% \verb?\begin{cutout}?\marg{numtop}\marg{leftwidth}\marg{rightwidth}\marg{numcut} \\ +% where \meta{numtop} is the number of full lines above the window, +% \meta{leftwidth} and \meta{rightwidth} are the widths of the text +% at the sides of the window, +% and \meta{numcut} is the number of lines to be cut (giving the height +% of the window). +% +% The basic method is to split the paragraph into three parts (a) +% the top lines above the window, (b) the window lines and (c) the rest +% (which will be below the window). \cs{parshape} is used to do the +% splitting. The top lines are left at their natural length, each line +% crossing the window is treated as a pair of short lines, and the rest +% are left at their natural length. +% +% The top lines are put into one box, the windowed ones into another +% and then there are the remainder. When being boxed, the window lines +% are combined pairwise to make single lines with space in the middle. +% Finally, the boxes are output. +% \begin{macrocode} +\newenvironment{cutout}[4]{% + \cutfuzz + \c@twtoplines=#1\relax + \c@twwinlines=#4\relax + \c@twlftside=#2\relax + \c@twrtside=#3\relax + \c@twtoka={}% +% \end{macrocode} +% Generate the \cs{parshape} specification. +% \begin{macrocode} + \c@twmakeparspec +% \end{macrocode} +% Reset the arguments and calculate a vertical shift. +% \begin{macrocode} + \c@twtoplines=#1\relax + \c@twwinlines=#4\relax + \c@twcalcshift \vskip-\c@twvsilg +% \end{macrocode} +% Open the \cs{c@twrawtext} box, call the \cs{parshape} and start +% collecting the text to be windowed. +% \begin{macrocode} + \setbox\c@twrawtext=\vbox\bgroup + \parshape=\c@twcnt \the\c@twtoka}% +% \end{macrocode} +% Now the code for the actions at \verb?\end{cutout}?, which starts by ending +% the \cs{c@rawtext} box, resetting \cs{parshape} and calculating +% the interline glue. +% \begin{macrocode} + {\egroup% end \box\c@twrawtext + \parshape=0 % reset parshape; + \c@twcalcilg % find ILG using current font +% \end{macrocode} +% If there are lines above the window, split them off from \cs{c@twrawtext} +% into \cs{c@twfinaltext}. +% \begin{macrocode} + \ifnum\c@twtoplines>\z@ + \setbox\c@twfinaltext=\vsplit\c@twrawtext to\c@twtoplines\baselineskip + \fi +% \end{macrocode} +% Calculate the `height' of the lines that make up the window. If +% the window is in the center then this is twice the expected height +% (at this point each final window line is stored as a pair of lines), +% otherwise it is the expected height based on \meta{numcut}. +% \begin{macrocode} + \c@twtopht=\c@twwinlines\baselineskip + \ifnum\c@twl@c=\z@ % center + \c@twtopht=2\c@twtopht + \fi +% \end{macrocode} +% Split the window lines from what is left in the \cs{c@twrawtext} box +% into box \cs{c@twholdwin} which will then contain the narrowed text for the +% window side(s). +% \begin{macrocode} + \setbox\c@twholdwin=\vsplit\c@twrawtext to\c@twtopht +% \end{macrocode} +% Now `compose' the window side(s) text (\cs{c@twholdwin}) +% into the final set of windowed lines (\cs{c@twwindow}). +% The process depends on whether the cutout is at the left, right, or center. +% \begin{macrocode} + \ifnum\c@twl@c=\z@% center + \c@twcompctr{\c@twholdwin}{\c@twwindow} + \else% left or right + \c@twcomplftrt{\c@twholdwin}{\c@twwindow} + \fi +% \end{macrocode} +% Assemble the various boxes into the final box (\cs{c@twfinaltext}) +% to be output. +% \begin{macrocode} + \setbox\c@twfinaltext= + \vbox{\ifnum\c@twtoplines>\z@\unvbox\c@twfinaltext\vskip\c@twvsilg\fi + \unvbox\c@twwindow% + \vskip-\c@twvsilg\unvbox\c@twrawtext}% +% \end{macrocode} +% We're done, hand off the paragraph. +% \begin{macrocode} + \box\c@twfinaltext} + +% \end{macrocode} +% \end{environment} +% +% \begin{macro}{\c@twcompctr} +% \begin{macro}{\c@twfirst} +% \cs{c@twcompctr}\marg{linepairbox}\marg{composedbox} composes a +% center window box \meta{linepairbox} consisting of pairs of short +% lines into a box \meta{composedbox} where the pairs have been assembled +% into single lines. +% +% \cs{c@twfirst} is used as a flag for indicating the first line of a cutout. +% \begin{macrocode} +\newcommand*{\c@twcompctr}[2]{% + \def\c@twfirst{1} + \loop\advance\c@twwinlines\m@ne +% \end{macrocode} +% Get a pair of lines and remove skips. +% \begin{macrocode} + \setbox\c@twslicea=\vsplit#1 to\baselineskip + \setbox\c@twsliceb=\vsplit#1 to\baselineskip + \c@twprune{\c@twslicea}{\c@twlftside}% + \c@twprune{\c@twsliceb}{\c@twrtside}% +% \end{macrocode} +% \begin{macrocode} + \ifnum\c@twfirst=\@ne +% \end{macrocode} +% The first time put the texts into a box at the left and right with +% \cs{pageinwindow} at the end of the left text. +% \begin{macrocode} + \setbox#2=\vbox{\unvbox#2\hbox + to\hsize{\box\c@twslicea\pageinwindow\hfil\box\c@twsliceb}}% + \else +% \end{macrocode} +% For further lines just put the texts at the left and right. +% \begin{macrocode} + \setbox#2=\vbox{\unvbox#2\hbox + to\hsize{\box\c@twslicea\hfil\box\c@twsliceb}}% + \fi +% \end{macrocode} +% \begin{macrocode} + \def\c@twfirst{2} + \ifnum\c@twwinlines>\z@\repeat} + +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\c@twcomplftrt} +% Compose an open (left or right) sided rectangular window. +% \begin{macrocode} +\newcommand*{\c@twcomplftrt}[2]{% + \def\c@twfirst{1}% + \loop\advance\c@twwinlines\m@ne +% \end{macrocode} +% For an open window we simply deal with one line at a time, not +% pairs. In other respects the code is generally similar to that for +% \cs{c@twcompctr}. +% \begin{macrocode} + \setbox\c@twslicea=\vsplit#1 to\baselineskip + \ifnum\c@twl@c=\m@ne% open left, text at right + \c@twprune{\c@twslicea}{\c@twrtside} + \ifnum\c@twfirst=\@ne + \setbox#2=\vbox{\unvbox#2\hbox + to\hsize{\pageinwindow\hfil\box\c@twslicea}}% + \else + \setbox#2=\vbox{\unvbox#2\hbox + to\hsize{\mbox{}\hfil\box\c@twslicea}}% + \fi + \def\c@twfirst{2} + \else + \ifnum\c@twl@c=\@ne% open right, text at left + \c@twprune{\c@twslicea}{\c@twlftside} + \ifnum\c@twfirst=\@ne\relax + \setbox#2=\vbox{\unvbox#2\hbox + to\hsize{\box\c@twslicea\pageinwindow}}% + \else + \setbox#2=\vbox{\unvbox#2\hbox + to\hsize{\box\c@twslicea}}% + \fi + \def\c@twfirst{2} + \fi + \fi + \ifnum\c@twwinlines>\z@\repeat} + +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\c@twprune} +% \cs{c@twprune}\marg{vbox}\marg{width} chops off the \cs{lastskip}. +% It takes a \meta{vbox} containing a single \cs{hbox}, \cs{unvbox}es +% it,cancels the \cs{lastskip} which can be put at the right of +% a short \cs{parshape} line, then puts it in a box width \meta{width}. +% \begin{macrocode} +\newcommand*{\c@twprune}[2]{% + \unvbox#1 \setbox#1=\lastbox % \box#1 is now an \hbox + \setbox#1=\hbox to#2{\strut\unhbox#1\unskip}} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\c@twmakeparspec} +% Calculate the required \cs{parshape} spec for a paragraph with a rectangular +% cutout window. +% \begin{macrocode} +\newcommand*{\c@twmakeparspec}{% +% \end{macrocode} +% \cs{c@twcnt} is the total number of lines for the \cs{parshape}, i.e., +% the number of the top lines plus (twice) the number of window line +% plus one for the remaining lines. +% \begin{macrocode} + \c@twcnt=\c@twwinlines + \ifnum\c@twl@c=\z@ + \multiply \c@twcnt by \tw@ + \fi + \advance\c@twcnt by \c@twtoplines \advance\c@twcnt by \@ne +% \end{macrocode} +% If there are top lines generate a \verb?0pt \hsize? for each +% \begin{macrocode} + \ifnum\c@twtoplines>\z@ + \loop\c@twtoka=\expandafter{\the\c@twtoka 0pt \hsize} + \advance\c@twtoplines -1\relax + \ifnum\c@twtoplines>\z@\repeat + \fi +% \end{macrocode} +% Now do the cutout portion of the spec. +% \begin{macrocode} + \ifnum\c@twl@c=\m@ne % openleft +% \end{macrocode} +% For open left calculate the width of the open cutout as \cs{c@twlftside}. +% \begin{macrocode} + \c@twlftside=\hsize + \advance\c@twlftside -\c@twrtside + \fi +% \end{macrocode} +% Loop over the windowed lines. +% \begin{macrocode} + \loop\c@twtoka=% + \ifnum\c@twl@c=\m@ne % openleft +% \end{macrocode} +% For open left generate a \verb?\c@twlftside \c@twrtside? for each. +% \begin{macrocode} + \expandafter{\the\c@twtoka \c@twlftside \c@twrtside} + \else + \ifnum\c@twl@c=\@ne % openright +% \end{macrocode} +% For open right generate a \verb?\0pt c@twlftside? for each +% \begin{macrocode} + \expandafter{\the\c@twtoka 0pt \c@twlftside} + \else %center +% \end{macrocode} +% For centered generate \verb?0pt \c@twlftside 0pt \c@twrtside? for each pair. +% \begin{macrocode} + \expandafter{\the\c@twtoka 0pt \c@twlftside 0pt \c@twrtside} + \fi + \fi + \advance\c@twwinlines \m@ne + \ifnum\c@twwinlines>\z@\repeat +% \end{macrocode} +% That finishes the cutout portion. For the remaining lines in the +% paragraph just generate a single \verb?0pt \hsize?. +% \begin{macrocode} + \c@twtoka=\expandafter{\the\c@twtoka 0pt \hsize}} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\c@twcalcshift} +% Calculate the estimated vertical shift needed for the window. +% I determined the values experimentally based on a 10pt font. +% In may be different for different fonts, but I hope not. +% \begin{macrocode} +\newcommand*{\c@twcalcshift}{% vertical shift + \c@twvsilg=\c@twwinlines\baselineskip + \ifnum\c@twtoplines<\@ne + \advance\c@twvsilg -0.25\baselineskip + \fi + \c@twvsilg=0.5\c@twvsilg + \ifnum\c@twl@c=\z@\else + \c@twvsilg=0.5\c@twvsilg + \fi} + +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Shaped cutouts} +% +% \begin{macro}{\picinwindow} +% A zero-sized picture, with contents \cs{putstuffinpic}, which is placed in +% the center of the first gap in a shaped cutout. +% \begin{macrocode} +\newcommand*{\picinwindow}{% + \begin{picture}(0,0) + \putstuffinpic + \end{picture}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\putstuffinpic} +% Default \cs{putstuffinpic} is empty. +% \begin{macrocode} +\newcommand*{\putstuffinpic}{} + +% \end{macrocode} +% \end{macro} +% +% \begin{environment}{shapedcutout} +% \begin{macro}{\c@twb} +% A shaped cutout where the user defines the shape. \\ +% \verb?\begin{shapedcutout}?\marg{numtop}\marg{numcut}\marg{shapespec} \\ +% where \meta{numtop} is the number of full lines above the window, +% \meta{numcut} is the number of lines to be cut (giving the height +% of the window) and +% \meta{shapespec} is the user's specification of the shape of the +% surroundings of the cutout. This is in the form of a comma-separated +% list of either the pairs of widths of the left and right texts of a centered +% cutout or the widths of the left or right texts of an open cutout. +% +% \cs{c@twb} holds arg 3 (\meta{shapespec}), the user's parspec. +% +% The code is very similar to that for the |cutout| environment. +% \begin{macrocode} +\newenvironment{shapedcutout}[3]{% + \cutfuzz + \c@twtoplines=#1\relax + \c@twwinlines=#2\relax + \edef\c@twb{#3}% user's parspec +% \end{macrocode} +% Generate the top lines portion of the parspec followed by the cutout +% portion. +% \begin{macrocode} + \c@twmaketopoddspec + \c@twbuildoddspec{#3} +% \end{macrocode} +% Continue like the |cutout| code. +% \begin{macrocode} + \c@twtoplines=#1\relax + \c@twwinlines=#2\relax + \c@twcalcshift \vskip-\c@twvsilg + \setbox\c@twrawtext=\vbox\bgroup +% \end{macrocode} +% \cs{c@twcnt} is the total number of parshape lines; \cs{c@twtoka} is the +% spec for the top lines; \cs{c@twtokb} is the spec for the cutout lines; +% and \verb?0pt \hsize? is the spec for the remainder of the paragraph. +% \begin{macrocode} + \parshape=\c@twcnt \the\c@twtoka \the\c@twtokb 0pt \hsize}% +% \end{macrocode} +% \end{macro} +% The code for the end of the environment, where most of the work is done. +% It is similar to the code for the end of the |cutout| environment. +% \begin{macrocode} + {\egroup + \parshape=0 + \c@twcalcilg + \ifnum\c@twtoplines>\z@ + \setbox\c@twfinaltext=\vsplit\c@twrawtext to\c@twtoplines\baselineskip + \fi + \c@twtopht=\c@twwinlines\baselineskip + \ifnum\c@twl@c=\z@ % center + \c@twtopht=2\c@twtopht + \fi + \setbox\c@twholdwin=\vsplit\c@twrawtext to\c@twtopht + \ifnum\c@twl@c=\z@% center + \c@twcompoddctr{\c@twholdwin}{\c@twwindow} + \else% open left or righyt + \c@twcompoddlftrt{\c@twholdwin}{\c@twwindow} + \fi + \setbox\c@twfinaltext= + \vbox{\ifnum\c@twtoplines>\z@\unvbox\c@twfinaltext\vskip\c@twvsilg\fi + \unvbox\c@twwindow% + \vskip-\c@twvsilg\unvbox\c@twrawtext}% + \box\c@twfinaltext} + +% \end{macrocode} +% \end{environment} +% +% \begin{macro}{\c@twmaketopoddspec} +% Make up the easy part of the odd \cs{parshape} specification; +% total number \cs{c@twcnt} and the toplines spec (\cs{c@twtoka}). +% \begin{macrocode} +\newcommand*{\c@twmaketopoddspec}{% + \c@twcnt=\c@twwinlines + \ifnum\c@twl@c=\z@ + \multiply \c@twcnt by \tw@ + \fi + \advance\c@twcnt by \c@twtoplines \advance\c@twcnt by \@ne +%% \c@twcnt is total of toplines + 2(window lines) + 1 + \c@twtoka={} + \ifnum\c@twtoplines>\z@ + \loop\c@twtoka=\expandafter{\the\c@twtoka 0pt \hsize} + \advance\c@twtoplines -1\relax + \ifnum\c@twtoplines>\z@\repeat + \fi} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\c@twaddtospec} +% Adds a `zero-indented line' to a parshape spec being assembled in +% \cs{c@twtokb}. +% \begin{macrocode} +\newcommand*{\c@twaddtospec}[1]{% + \c@twtokb=\c@twxpf{\the\c@twtokb 0pt #1 }} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\c@twbuildoddspec} +% \begin{macro}{\c@twxpf} +% \cs{c@twbuildoddspec}\marg{commalist} builds up the parshape spec for +% the odd cutout lines from the comma-separated list of lengths +% in \meta{commalist}. +% +% \cs{c@twxpf} is a shorthand for \cs{expandafter} +% to try and make the code shorter to read. +% \begin{macro}{\c@twlspec} +% \cs{c@twlspec} is used as a temporary variable when iterating over +% a comma-separated list. +% \end{macro} +% +% \begin{macrocode} +\let\c@twxpf\expandafter +\newcommand*{\c@twbuildoddspec}[1]{% + \c@twtokb={} + \@for\c@twlspec:=#1\do{% + \c@twxpf\c@twxpf\c@twxpf\c@twaddtospec\c@twxpf{\c@twlspec}}} + +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\c@twcompoddctr} +% \begin{macro}{\c@twrounds} +% Compose the lines of an odd shaped center cutout. +% +% We go through the user's shape list an item at a time but we need to +% collect pairs of items. The \cs{c@twrounds} variable is for managing the +% pairing. \cs{c@twfirst} is a flag for positioning the \cs{picinwindow} in +% the first line of the cutout. +% \begin{macrocode} +\newcommand*{\c@twcompoddctr}[2]{% + \def\c@twrounds{1} + \def\c@twfirst{1} + \@for\c@twlspec:=\c@twb\do{% + \ifnum\c@twrounds=1 + \setbox\c@twslicea=\vsplit#1 to\baselineskip % first of pair + \c@twprune{\c@twslicea}{\c@twlspec}% + \def\c@twrounds{2} + \else + \setbox\c@twsliceb=\vsplit#1 to\baselineskip % second of pair + \c@twprune{\c@twsliceb}{\c@twlspec}% + \ifnum\c@twfirst=1 + \setbox#2=\vbox{\unvbox#2\hbox + to\hsize{\box\c@twslicea\hfil\picinwindow\hfil\box\c@twsliceb}}% + \def\c@twfirst{2} + \else + \setbox#2=\vbox{\unvbox#2\hbox + to\hsize{\box\c@twslicea\hfil\box\c@twsliceb}}% + \fi + \def\c@twrounds{1} + \fi}} + +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\c@twcompoddlftrt} +% Compose the open (left or right) lines of an odd shaped cutout. +% \begin{macrocode} +\newcommand*{\c@twcompoddlftrt}[2]{% + \def\c@twfirst{1} + \@for\c@twlspec:=\c@twb\do{% + \setbox\c@twslicea=\vsplit#1 to\baselineskip % get a line + \c@twprune{\c@twslicea}{\c@twlspec}% + \ifnum\c@twl@c=\m@ne% open left, text at right + \ifnum\c@twfirst=1 + \setbox#2=\vbox{\unvbox#2\hbox + to\hsize{\mbox{}\hfil\picinwindow\hfil\box\c@twslicea}}% + \def\c@twfirst{2} + \else + \setbox#2=\vbox{\unvbox#2\hbox + to\hsize{\mbox{}\hfil\box\c@twslicea}}% + \fi + \else + \ifnum\c@twl@c=\@ne% open right, text at left + \ifnum\c@twfirst=1 + \setbox#2=\vbox{\unvbox#2\hbox + to\hsize{\box\c@twslicea\hfil\picinwindow\hfil}}% + \def\c@twfirst{2} + \else + \setbox#2=\vbox{\unvbox#2\hbox + to\hsize{\box\c@twslicea\hfil}}% + \fi + \fi + \fi}} + +% \end{macrocode} +% \end{macro} +% +% +% +% +% The end of this package. +% \begin{macrocode} +%</pkg> +% \end{macrocode} +% +% +% +% +% \Finale +% \PrintIndex +% +\endinput + +%% \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 \~} + + |