1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936 |
- \relax
- % **********************************************************************
- % **** ****
- % **** DRAFT: The TeX-REDUCE-Interface ****
- % **** Werner Antweiler, University of Cologne, August 1, 1988 ****
- % **** ****
- % **********************************************************************
- \magnification=1200
- \hoffset=10truemm\hsize=16truecm\vsize=10truein
- \tolerance 1500 \hbadness=800
- \parindent=12pt \parskip=0pt \displayindent=30pt
- \baselineskip=12pt plus0.1pt minus0.2pt
- \newdimen\narrowskip \narrowskip=10pt
- % Make Use of 12pt-Fonts Default
- %
- \font\caps=cmcsc10
- \font\smallcaps=cmcsc10 at 10truept
- \font\small=cmr8
- \font\smallit=cmti8
- \font\smallbf=cmbx8
- \font\smalltt=cmtt8
- \font\big=cmbx10 at 15pt
- %
- \catcode`\"=\active \let"=\" \let\3=\ss
- \def\zB{z.B.\ }
- \def\D{\char'042}
- \def\B{\char'134}
- % -----------
- % Hilfsmacros
- % -----------
- \def\ttq{\par\vskip3.6135pt\begingroup\baselineskip=14.454pt
- \parindent=30pt\parskip=0pt\let\par=\endgraf\obeyspaces\obeylines\tt\ttf}
- {\obeylines\gdef\ttf^^M#1\endtt{\vbox{#1}\endgroup\par\noindent}}
- {\obeyspaces\gdef {\ }}
- \def\iq#1{{\it#1\/}}
- \def\quote{\par\begingroup\leftskip=\parindent
- \baselineskip=9.03pt\small\noindent}
- \def\endquote{\par\endgroup\par}
- \def\today{\ifcase\month\or January\or February\or March\or April\or May\or
- June\or July\or August\or September\or October\or November\or December\fi
- \space\number\day, \number\year}
- \def\endpage{\par\vfill\eject}
- \newcount\Defcount \Defcount=0
- \def\Def#1\par{\global\advance\Defcount by1\par
- \vskip3.6135pt{\baselineskip=14.454pt
- \noindent\bf Definition \the\Defcount:\sl\enspace#1\par}}
- \let\YY=\let % now you can send the control sequence \YY
- \newcount\Figcount \Figcount=0
- \def\VFig{\vFig\smalltt}
- \def\VVFig{\vFig\tt}
- \def\vFig#1{\midinsert\global\advance\Figcount by 1
- \message{[Fig. \the\Figcount]}
- \vbox\bgroup
- \hrule height.6pt
- \hbox to\hsize\bgroup
- \vrule width.6pt \hskip 9.4pt
- \vbox\bgroup
- \advance\hsize by-20pt \line{}
- \vskip 9.4pt \nointerlineskip
- \let\vtt=#1\verbatim}
- \def\endVFig#1:#2\par{\vskip 9.4pt
- \egroup \hss \vrule width.6pt
- \egroup \hrule height.6pt
- \vskip3pt\baselineskip=\narrowskip
- \noindent\smallbf Fig. \the\Figcount: #1.
- \small #2\par
- \egroup\endinsert}
- % ------------------
- % Fussnotensteuerung
- % ------------------
- \newcount\notenumber\notenumber=0
- \def\vfootnote#1{\insert\footins\bgroup
- \interlinepenalty=\interfootnotelinepenalty
- \splittopskip=\ht\strutbox \splitmaxdepth=\dp\strutbox
- \floatingpenalty=20000 \leftskip=0pt \rightskip=0pt
- \spaceskip=0pt \xspaceskip=0pt
- \item{#1}\footstrut\futurelet\next\fooot}
- \def\fooot{\ifcat\bgroup\noexpand\next\let\next\foooot
- \else\let\next\foot\fi\next}
- \def\foooot{\bgroup\aftergroup\oofoot\let\next}
- \def\foot#1{#1\oofoot}
- \def\oofoot{\strut\egroup}
- \def\note#1{\global\advance\notenumber by1
- \begingroup\small\baselineskip=\narrowskip
- \setbox\strutbox=\hbox{\vrule height7.0pt depth3.0pt width0pt}%
- \footnote{$^{\the\notenumber}$}{\bgroup\small\baselineskip=\narrowskip
- #1\egroup}\endgroup}
- % -----------------------------------
- % Seitenkopf und Fusszeilen-Steuerung
- % -----------------------------------
- \pageno=1
- \headline={\ifnum\pageno=1\hfill\else\hfill\rm---\ \folio\ ---\hfill\fi}
- \footline={\hfil}
- % ------------------
- % Inhaltsverzeichnis
- % ------------------
- \let\ZZ=\let % now you can send the control sequence \ZZ
- \newcount\seccount \seccount=0
- \newcount\subseccount \subseccount=0
- \newcount\subsubseccount \subsubseccount=0
- \def\secnum{\number\seccount%
- \ifnum\subseccount=0\else.\number\subseccount\fi%
- \ifnum\subsubseccount=0\else.\number\subsubseccount\fi}
- % --------
- % Textteil
- % --------
- \newbox\secbox
- \def\secindent#1#2#3{\par\bigskip\begingroup
- \message{\secnum #1}\setbox\secbox=\hbox{#3\secnum\hskip1.5em}
- \hangafter=1\hangindent=\wd\secbox\baselineskip=\ht\secbox
- \advance\baselineskip by5pt
- \noindent #3\box\secbox#1
- \par\endgroup\nobreak\smallskip
- \nobreak\smallskip\vskip-\parskip\noindent}
- \def\sec#1\par{\global\advance\seccount by1\global\subseccount=0
- \global\subsubseccount=0\secindent{#1}{0}\bf}
- \def\subsec#1\par{\global\advance\subseccount by1
- \global\subsubseccount=0\secindent{#1}{1}\bf}
- \def\subsubsec#1\par{\global\advance\subsubseccount by1
- \secindent{#1}{2}\bf}
- % --------------
- % Spezial Makros
- % --------------
- \def\center{\vskip\parskip\begingroup
- \parindent=0pt \parskip=0pt plus 1pt
- \rightskip=0pt plus 1fill \leftskip=0pt plus 1fill
- \obeylines}
- \def\endcenter{\endgroup}
- \def\flushleft{\vskip\parskip\begingroup
- \parindent=0pt \parskip=0pt plus 1pt
- \rightskip=0pt plus 1fill \leftskip=0pt
- \obeylines}
- \def\endflushleft{\endgroup}
- \def\flushright{\vskip\parskip\begingroup
- \parindent=0pt \parskip=0pt plus 1pt
- \rightskip=0pt \leftskip=0pt plus 1fill
- \obeylines}
- \def\endflushright{\endgroup}
- \def\itemize#1{\par\begingroup\parindent=#1}
- \def\litem#1{\par\hang\noindent\hbox to \parindent{#1\hfil}}
- \def\ritem#1{\par\hang\noindent\hbox to \parindent{\hfil#1\enspace}}
- \def\sitemize#1{\par\begingroup\parindent=#1\baselineskip=\narrowskip\small}
- \def\enditemize{\par\endgroup\par}
- \def\bitem{\ritem{$\bullet$}}
- % ------------
- % Mathe-Makros
- % ------------
- \newcount\eqcount \eqcount=0
- \newcount\eqoffcount
- \def\adveq{\global\advance\eqcount by1}
- \def\eqcon{\adveq(\number\eqcount)}
- \def\eqco{\eqno{\eqcon}}
- \def\ceqc#1{(\number\eqcount.#1)}
- \def\ceqalign{\adveq\eqalignno}
- \def\eqoff#1{\eqoffcount=\eqcount\advance\eqoffcount by-#1%
- (\the\eqoffcount)}
- \catcode`\*=\active \def*{\ifmmode\cdot\else\char'52\fi}
- % Spezialmakros
- \def\aut#1 \ttl#2 \pub#3 \ref#4 \dat#5 \inx#6 \^^M{\par
- {\baselineskip=\narrowskip
- \parindent=24pt\hang\noindent{\smallcaps#1}\small\ (#6) #2. #3, #5%
- \ifx\\#4\else, #4\fi.\par}\medskip\penalty0}
- \def\example{\par\vskip5pt\flushleft\tt\parindent=50pt}
- \def\endexample{\endflushleft\vskip5pt\noindent\ignorespaces}
- \def\i#1{{\it #1\/}}
- \def\t#1{{\tt #1}}
- \def\VAX{$\mu$VAX-I\kern-0.1em I}
- % ----------------------------------------------------------------------
- % Verbatim Mode Macros
- % ----------------------------------------------------------------------
- \def\uncatcodespecials{\def\do##1{\catcode`##1=12}\dospecials\do\"}
- \let\vtt=\tt
- \def\setupverbatim{\vtt\Obeylines\uncatcodespecials\obeyspaces}
- \def\newlinepar{~\par}
- {\catcode`\^^M=\active % these lines must end with `%'
- \gdef\Obeylines{\catcode`\^^M=\active\def^^M{\newlinepar}}}%
- {\obeyspaces\global\let =\ }
- \def\verbatim{\par\begingroup\parskip=0pt plus 1pt
- \ifx\vtt\smalltt\baselineskip=10pt\fi
- \setupverbatim\doverbatim}
- {\catcode`\|=0 \catcode`\\=12
- |Obeylines|gdef|doverbatim^^M#1\endverbatim{#1|endgroup}}
- \def\verb{\begingroup\setupverbatim\doverb}
- \def\doverb#1{\def\next##1#1{##1\endgroup}\next}
- % ----------------------------------------------------------------------
- % REDUCE-LISP Programming Language Documentation
- % ----------------------------------------------------------------------
- \newdimen\xindent \dimen\xindent=15pt
- \catcode`\@=\active
- \def\@{\char'100}
- \def@{\hskip\dimen\xindent\ignorespaces}
- \def\gets{$\leftarrow$}
- \def\\#1/{{\it#1\/\kern.05em}} % italic type for identifiers
- \def\&{{\bf#1\/}} % boldface type for reserved words
- \def\.#1.{{\tt#1\/}} % typewriter type for strings
- \def\!#1!{{\rm$\langle$ #1 $\rangle$\/}} % roman for operations
- \def\[#1]{{\rm$\{$ #1 $\}$}} % comments in roman
- \def\DOC{\midinsert\global\advance\Figcount by 1
- \message{[Fig. \the\Figcount]}
- \vbox\bgroup
- \hrule height.6pt
- \hbox to\hsize\bgroup
- \vrule width.6pt \hskip 9.4pt
- \vbox\bgroup
- \advance\hsize by-20pt \line{}
- \vskip 9.4pt \nointerlineskip
- \parindent=0pt \parskip=0pt plus 1pt
- \rightskip=0pt plus 1fill \leftskip=0pt
- \begingroup\obeylines}
- \def\endDOC{\endgroup\endDoc}
- \def\endDoc#1:#2\par{\vskip 9.4pt
- \egroup \hss \vrule width.6pt
- \egroup \hrule height.6pt
- \vskip3pt\baselineskip=\narrowskip
- \noindent\smallbf Fig. \the\Figcount: #1.\ \small#2\par
- \egroup\endinsert}
- % ----------------------------------------------------------------------
- % Titel
- % ----------------------------------------------------------------------
- \line{}
- \vskip10mm
- \center\big\baselineskip=24pt
- Typesetting REDUCE output with \TeX
- --- A REDUCE-\TeX-Interface ---
- \endcenter
- \vskip13mm
- \center\baselineskip=12pt
- \smallcaps Werner Antweiler
- \smallcaps Andreas Strotmann
- \smallcaps Volker Winkelmann
- \small University of Cologne Computer Center, West Germany{\parindent=12pt%
- \note{The authors are with: %
- Rechenzentrum der Universit"at zu K"oln (University of Cologne %
- Computer Center), %
- Abt. Anwendungssoftware (Application Software Department), %
- Robert-Koch-Stra\3e 10, 5000 K"oln 41, West Germany.}}
- \small\today
- \endcenter
- \vskip15mm
- \begingroup\narrower\narrower\baselineskip=\narrowskip
- \noindent\smallbf Abstract: \small
- REDUCE is a well known computer algebra system invented by
- Anthony C. Hearn.
- Although a pretty-printer is already incorporated in REDUCE,
- the output is produced only in line-printer quality.
- The simple idea to produce high quality output from REDUCE
- is to link REDUCE with Donald E. Knuth's famous \TeX\ typesetting
- language. This draft reviews our efforts in this direction.
- We introduce a program written in REDUCE-Lisp which is able to typeset REDUCE
- formulas using \TeX. Our REDUCE-\TeX-Interface incorporates three
- levels of \TeX\ output: without line breaking, with line breaking,
- and with line breaking plus indentation. This paper deals with
- some of the ideas we have put into LISP-code and it summarizes some of our
- experiments we have made with it yet. Furthermore, we compile a small
- user's manual introducing to the use of our REDUCE-\TeX-Interface.
- \par\bigskip
- \noindent\smallbf Keywords: \small
- Line-Breaking Algorithm, LISP, Prefix-to-Infix Conversion,
- REDUCE, \TeX, Typesetting
- \par\endgroup\vskip10mm
- \rm
- %begin(text)
- % ----------------------------------------------------------------------
- \sec Introduction\par
- % ----------------------------------------------------------------------
- REDUCE is a well known computer algebra system invented by
- Anthony C. Hearn. While every effort was made to improve
- the system's algebraic capabilities, the readability of the
- output remained poor by modern typesetting standards.
- Although a pretty-printer is already incorporated in REDUCE,
- the output is produced only in line-printer quality.
- The simple idea to produce high quality output from REDUCE
- is to link REDUCE with Donald E. Knuth's famous \TeX\ typesetting
- language. This draft reviews our efforts in this direction.
- We introduce a program written in REDUCE-Lisp to typeset REDUCE
- formulas with \TeX. Our REDUCE-\TeX-Interface incorporates three
- levels of \TeX\ output: without line breaking, with line breaking,
- and with line breaking plus indentation. While speed
- without line breaking is comparable to that achieved with
- REDUCE's pretty-printer, line breaking consumes much more CPU time.
- Nevertheless, we reckon with a cost increase due to line breaking
- which is almost linear in the length of the expression to be broken.
- This paper deals with some of the ideas and algorithms we have
- programmed and it summarizes some of the experiments we have made
- with our program.
- Furthermore, at the end of this paper we provide a small user's manual
- which gives a short introduction to the use of our REDUCE-\TeX-Interface.
- For simplicity's sake the name ``REDUCE-\TeX-Interface'' will be
- abbreviated to ``TRI'' in this paper.\note{The reason why it was called
- TRI and not RTI is simply due to the fact that TRI corresponds better
- to the three-level (``tri-level'') mode.}
- At this point we should mention major goals we pursue with TRI:
- \bitem We want to produce REDUCE-output in typesetting quality.\par
- \bitem The intermediate files (\TeX-input files) should be easy to edit.
- The reason is that it is likely that the proposed
- line-breaks are sub-optimal from the user's point of view.\par
- \bitem We apply a \TeX-like algorithm which ``optimizes''
- the line-breaking over the whole expression. This differs
- fundamentally from the standard left-to-right, one-line look-ahead
- pretty-printers of REDUCE, LISP and the like.\par
- % ----------------------------------------------------------------------
- \sec From REDUCE to \TeX: concepts\par
- % ----------------------------------------------------------------------
- REDUCE uses the function \t{varpri} to decide how to output a REDUCE
- expression. The function gets three arguments: the expression to be
- printed, a list of variables to each of which the expression to be
- printed gets assigned, and a flag which determines if the expression to be
- printed is the first, last or only expression in the line. \t{varpri}
- may be called consecutively for preparing a line for output. So, our
- task is to assemble all expressions before finally printing them.
- When !*TeX is true, \t{varpri} redirects output to our function
- \t{TeXvarpri}, which receives a REDUCE expression, translates it into
- \TeX\ and pushes it onto a variable called \t{TeXStack*} before
- eventually printing it once the line is completed.\par
- The \t{TeXvarpri} function first calls a function named \t{makeprefix}.
- Its job is to change a REDUCE algebraic expression to a standard prefix list
- while retaining the tree structure of the whole expression. Generally, this
- is done using a call \t{prepsq*(simp(expression))}, but lists and
- matrices need some special treatment. After this has been done the
- new intermediate expression is passed to the most important module
- of the TRI: the \t{mktag/makefunc}-family.\note{The whole family currently
- has five members. The ``parents'' are the mktag and makefunc
- functions which do the most burdensome job. The ``children'' are
- \t{makearg, makemat and makeDF} which handle special cases such as
- list construnction or differentiation operators. We do not review
- the minor functions since they are easily understandable.}
- These functions recursively expand the structured list (or operator tree)
- into a flat list, translating each REDUCE symbol or
- expression into so-called \TeX-items on passing by.
- For that reason, this list is called the \TeX-item list.
- If the simple \TeX-mode (without line breaking) was chosen this list
- is then printed immediately without further considerations.
- Translation and printing this way is almost as fast as with
- the standard REDUCE pretty printer.\par
- When line-breaking has been enabled things get a bit more complicated.
- The greatest effort with TRI was to implement the line-breaking
- algorithm. More than half of the entire TRI code deals with this
- task.
- The ultimate goal is to add some ``break items'', i.e. \verb|\nl|-%
- \TeX-commands\note{This is not a \TeX-primitive but a TRI-specific
- \TeX-macro command which expands into a lot of stuff.},
- marking --- in a certain way --- optimal line-breaks.
- Additionally, these break items can be followed immediately by
- ``indentation items'', i.e. \verb|\OFF{...}| \TeX-commands\note{see
- previous footnote}, specifying
- the amount of indentation applicable for the next new line.
- The problem is to choose the right points where to insert these
- special \TeX-items. Therefore, the \TeX-item list undergoes
- three further transformation steps.\par
- First, the \TeX-item list gets enlarged by so-called ``glue items''.
- Glue items are two-element lists, where the first element is a width
- info and the second element is a penalty info. The ``penalty'' is
- a value in the range $-10000\ldots+10000$ indicating a mark-up on a
- potential break-point, thus determining if this point is a
- fairly good (if negative) or bad (if positive) choice.
- The amount of penalty depends (a) on the kind of \TeX-items
- surrounding the glue item, (b) on the bracket nesting, and finally
- (c) on special characteristics.\note{For example, the plus- and
- the difference operator have special impact on the amount of
- penalty.} The function handling this job is named
- \t{insertglue} which implicitly calls the function
- \t{interglue}. The latter determines the glue item to insert
- between a left and a right \TeX-item.\par
- During the second level, the \TeX-item list becomes transformed
- into a so-called breaklist consisting of active and passive nodes.
- A passive node is simply a width info giving the total width of
- \TeX-items not interspersed by glue items. On the other hand,
- active nodes are glue items enlarged by a third element, the
- offset info, indicating an indentation level which is used later
- for computing the actual amount of indentation.
- Active nodes are used as potential breakpoints.
- Moreover, while creating the breaklist, the \TeX-item list will be
- modified if necessary according to the length of fractions and square
- roots which cannot be broken if retained in their ``classical''
- form. Hence fractions look like \t{(...)/(...)} if they don't fit
- into a single line, especially in the case of large polynomial fractions.
- The major function for this job is named \t{breaklist} which
- calls \t{resolve} if necessary.
- \par
- The third and most important level is the line-breaking algorithm
- itself. This algorithm embedded in the function \t{trybreak}
- will be described below. The idea how to break lines is based
- on the article by Knuth/Plass(1981). Line-breaking can occur at
- active nodes only. So, you can loop through the breaklist considering
- all potential break-points. But in order to find a suitable way
- in a reasonable amount of time you have to limit the number of
- potential breakpoints considered. This is performed by associating
- a ``badness'' with each potential breakpoint, describing how
- good looking or bad looking a line turns out. If the badness is less than
- a given amount of ``tolerance'' --- as set by the user ---
- then an active node is considered to be feasible and becomes
- a delta node. A delta node is simply an active node enlarged
- by four further infos: an identification number for this node,
- a pointer to the best feasible break-point (i.e. delta-node) to come from%
- \note{If one were to break the formula at this delta-node, the
- best place to start this line is given by this pointer.}
- the total amount of demerits (i.e. a compound value derived from
- badness and penalty) accumulated so far, and a value indicating
- the amount of indentation applied to a new line beginning at this
- node.
- When \t{trybreak} has stepped through the list, the breakpoints
- will have been determined. Afterwards all glue items (i.e. active nodes)
- are deleted from the \TeX-item list while break- and indentation-%
- items for those nodes marked as break-points are inserted.
- \par
- Finally the \TeX-item list is printed with regular ASCII-characters.
- We didn't put much emphasis on the question on how to format the
- intermediate output since it will be input directly into
- \TeX. The best way to characterize the routine \t{texout}
- is to call it quick and dirty. The readabiltiy of the output
- is low, but it may be quite good enough for users
- to do some final editing work.
- Nevertheless, \t{texout} keeps the nesting structure of the term
- visible when printed, so it will be easy to distinguish between
- parenthesis levels simply by considering the amount of indentation.
- % ----------------------------------------------------------------------
- \sec Creating a \TeX-item list\par
- % ----------------------------------------------------------------------
- The first \TeX-specific step in preparing a typesettable equivalent
- of a REDUCE expression is to expand the operator tree generated by
- REDUCE into a so-called \TeX-item list. The operator tree is
- preprocessed by \t{makeprefix} in order to receive an operator tree
- in standard prefix notation. A \TeX-item is either a character (letter or
- digit or special character) or a \TeX-primitive
- or -macro (i.e. a LISP symbol), with properties \t{'CLASS}, \t{'TEXTAG},
- \t{'TEXNAME} and (only if the item represents an operator)
- \t{'TEXPREC}, \t{'TEXPATT} and \t{'TEXUBY}
- bound to them, depending on what kind of \TeX-item it actually is.
- The latter three properties are used for operators only. \t{'TEXPREC}
- is the precedence of the operator, a number between 0 and 999.
- Here the value itself is less important than the position with
- respect to other operators' precedences. The remaining properties
- will be described later.
- \par
- First let's have a look at how a REDUCE expression arriving at TRI's main
- entry --- the function \t{TeXvarpri} --- is transformed through
- several levels of TRI-processing. For instance, let us consider
- the expression $(x-y)^{12}$, which expands into a polynomial
- $x^{12}-12*x^{11}*y+\cdots-12*x*y^{11}+y^{12}$ when evaluated.
- REDUCE uses a special form to store an expression. This form is
- called ``standard quotient'' because it in fact represents a quotient of two
- polynomials. The contents of the following figure 1 shows the
- ``standard quotient'' form of our example.\par
- % ----------------------------------------------------------------------
- \VFig
- (*SQ ((((X . 12) . 1)
- ((X . 11) ((Y . 1) . -12))
- ((X . 10) ((Y . 2) . 66))
- ((X . 9) ((Y . 3) . -220))
- ((X . 8) ((Y . 4) . 495))
- ((X . 7) ((Y . 5) . -792))
- ((X . 6) ((Y . 6) . 924))
- ((X . 5) ((Y . 7) . -792))
- ((X . 4) ((Y . 8) . 495))
- ((X . 3) ((Y . 9) . -220))
- ((X . 2) ((Y . 10) . 66))
- ((X . 1) ((Y . 11) . -12))
- ((Y . 12) . 1)
- ) . 1) T)
- \endverbatim
- \endVFig Standard Quotient Notation: This form is the way REDUCE represents
- terms.\par
- % ----------------------------------------------------------------------
- \noindent The term has been indented by hand to retain the structure
- of this expression. Actually the denominator is 1 as you easily find out
- from the last line.\note{The ``T'' in the last line is an ``already-%
- simplified''-flag indicating that the term doesn't need to undergo any more
- processing.} Obviously the standard-quotient form is a bit complicated
- for further manipulations. It can be changed to a real prefix
- notation as displayed in figure 2. Here, too, the term was edited
- by hand to make it a bit more readable and comparable to the other
- forms.\note{``Edit'' only means we have provided some additional
- indentation. We have changed neither the expression nor its structure.}
- Note that \t{PLUS} is not a binary but a $n$-ary operator,
- i.e. it takes an arbitrary number of arguments, while \t{MINUS} is
- always a unary operator.\note{The same problem arises with the
- RECIP-operator which is the unary form of the binary QUOTIENT-%
- operator.} This causes a bit of trouble because real
- binary operators are much easier to handle. To tackle this problem
- we have introduced the \t{'TEXUBY} property, which is used to change
- a unary into a binary form if possible.\par
- % ----------------------------------------------------------------------
- \VFig
- (PLUS (EXPT X 12)
- (MINUS (TIMES 12 (EXPT X 11) Y ))
- (TIMES 66 (EXPT X 10) (EXPT Y 2))
- (MINUS (TIMES 220 (EXPT X 9) (EXPT Y 3)))
- (TIMES 495 (EXPT X 8) (EXPT Y 4))
- (MINUS (TIMES 792 (EXPT X 7) (EXPT Y 5)))
- (TIMES 924 (EXPT X 6) (EXPT Y 6))
- (MINUS (TIMES 792 (EXPT X 5) (EXPT Y 7)))
- (TIMES 495 (EXPT X 4) (EXPT Y 8))
- (MINUS (TIMES 220 (EXPT X 3) (EXPT Y 9)))
- (TIMES 66 (EXPT X 2) (EXPT Y 10))
- (MINUS (TIMES 12 X (EXPT Y 11)))
- (EXPT Y 12))
- \endverbatim
- \endVFig Prefix Notation: This list represents the state after
- application of {\smalltt makeprefix}\par
- % ----------------------------------------------------------------------
- A REDUCE expression is expanded using the two functions \t{mktag}
- and \t{makefunc}. Function \t{mktag} identifies the operator and is
- able to put some brackets around the expression if necessary.
- \t{makefunc} is a pattern oriented ``unification''\note{in the
- terminology of the programming language Prolog} function, which matches
- arguments of a REDUCE expression in order of appearance with so-called
- ``unification tags'', as explained below. Thus, \t{mktag} and
- \t{makefunc} are mutually dependent and highly recursive functions.\par
- A ``unification tag list'' is a list (or a pattern, if you like)
- which consists of single ``unfication tags''.
- Each REDUCE operator is associated with a unification pattern.
- While expanding the expression, each tag is replaced by the appropiate
- \TeX-item or partial \TeX-item list created subsequently.
- A tag is defined as either an atom declared as a \TeX-item or one of
- the following:\par\itemize{27mm}\smallskip
- \litem{(F)}insert operator
- \litem{(X)}insert non-associative argument
- \litem{(Y)}insert a left- or right-associative argument
- \litem{(Z)}insert superscript/subscript argument
- \litem{(R)}use tail recursion to unify remaining arguments (necessary
- with operators having more than two arguments, e.g. the plus operator;
- associativity depends on previous (X) or (Y) tag)
- \litem{(L \i{hs})}insert a list of arguments (eat up all arguments on
- passing by); put \i{hs} as a horizontal separator between the arguments
- (e.g., a separator could be a comma for simple argument lists.)
- \litem{(M \i{vs} \i{hs})}insert a matrix (and eat up all arguments on
- passing by); put \i{vs} as a vertical separator and \i{hs} as a
- horizontal separator between the rows and columns
- \litem{(APPLY \i{fun})}apply function \i{fun} to remaining argument list
- \par\enditemize\smallskip
- \noindent
- These ``tags'' are assembled to a tag-list or pattern, respectively.
- For each functor (i.e. the head of a prefix list, e.g. \t{PLUS},
- \t{MINUS} or \t{SQRT}) such a list is bound to its property
- \t{'TEXPATT}. For instance, the functor \t{PLUS} has got the pattern
- \t{((X) (F) (R))} bound to it, and the functor \t{EXPT} possesses the
- pattern \verb|((X) ^{ (Z) })|.
- The following two boxes with pseudo-code (figures 3 and 4)
- survey the two major functions performing the expansion of a
- prefix REDUCE-expression into a TeX-item list.\par
- % ----------------------------------------------------------------------
- \DOC
- \&function& \\mktag/(\\tag/,\\outer-precedence/,\\associative/);
- \&begin&
- @ \&if& \!tag is empty! \&then return nil&
- @ \&else if& \!tag is an atom! \&then return& \!get the \TeX-item for%
- \\tag/!
- @ \&else begin& \[the tag is a list]
- @ @ \\precedence/\gets\!precedence of this tag or 999!
- @ @ \[now expand the expression, the first element is the]
- @ @ \[functor, the following elements are the arguments]
- @ @ \\term/\gets\\makefunc/(\&car& \\tag/,\&cdr& \\tag/,\\precedence/);
- @ @ \[check for parentheses: term is surrounded by parentheses in order]
- @ @ \[to prevent it from overruling by precedence]
- @ @ \&if& (\\associative/ \&and& (\\precedence/ = \\outer-precedence/))
- @ @ @ \&or& (\\precedence/ $<$ \\outer-precedence/)
- @ @ \&then& \\term/\gets\!put a pair of brackets around \\term/!;
- @ @ \&return& \\term/
- @ \&end&
- \&end&;
- \endDOC The function {\smalltt mktag}: This function deals with the
- transformation from prefix notation to \TeX\ notation. One important
- task of it is to decide whether or not brackets should be placed
- around the term.\par
- % ----------------------------------------------------------------------
- At this point, the way we use our LISP pseudo-code should be
- explained. Words typeset in boldface are reserved words, e.g.
- \&begin& and \&end&. We use a PASCAL-like syntax which is actually
- used by REDUCE-Lisp, too, but with a few differences: we use the
- word \&function& to indicate that a value is returned\note{REDUCE-Lisp
- uses the phrase ``symbolic procedure'' here.}, and
- we use \&return& to return the value of the function and therefore
- to exit the function. This is in contrast to the use of \t{return}
- in REDUCE-Lisp, where \t{return} is used only to return the value
- of a begin-end-block. Identifiers are printed in italics. Where
- identifiers are used as logical values, e.g. in conditions, they
- are either false if their value is \&nil& or true otherwise,
- regardless of their exact value. Pseudo-operations are printed
- in roman and are put in angle brackets. Comments, too, are printed
- in roman but they are put in curly brackets. Assignments are
- typeset by the assignment operator \gets, thus indicating the
- direction of assignment. Semicolons are used (as in PASCAL and REDUCE) as
- separators. In order to improve readability, mathematical expressions
- are given in mathematical form instead of real code. Finally,
- the operator {\tt ::=} is used to identify a pseudo-code-operation
- with its real code. We do not provide proper data type declarations
- for variables since this seems to be superfluous in LISP where you
- only deal with atoms and lists.
- % ----------------------------------------------------------------------
- \DOC
- \&function& \\makefunc/(\\functor/,\\argument-list/,\\precedence/);
- \&begin&
- @ \\term/\gets\&nil&;
- @ \\pattern/\gets\!pattern of this functor or default pattern!;
- @ \&while& \\pattern/ \&do& \[as long as pattern isn't empty]
- @ \&begin&
- @ @ \\tag/\gets\&car& \\pattern/;
- @ @ \\pattern/\gets\&cdr& \\pattern/;
- @ @ \&if& \!\\tag/ is an atom! \&then& \\aux/\gets\&nil&
- @ @ \&else if& \!tag is (F)! \&then& \\aux/\gets\!get the \TeX-item for%
- \\functor/!
- @ @ \&else if& \!\\argument-list/ is empty! \&then& \\aux/\gets\&nil&
- @ @ \&else if& \!tag is (X)! \&then&
- @ @ \&begin&
- @ @ @ \\aux/\gets\\mktag/(\&car& \\argument-list/,\\precedence/,\&nil&);
- @ @ @ \\argument-list/\gets\&cdr& \\argument-list/
- @ @ \&end&
- @ @ \&else if& \!tag is (Y)! \&then&
- @ @ \&begin&
- @ @ @ \\aux/\gets\\mktag/(\&car& \\argument-list/,\\precedence/,\&T&);
- @ @ @ \\argument-list/\gets\&cdr& \\argument-list/
- @ @ \&end&
- @ @ \&else if& \!tag is (R)! \&then& \[tail recursive pattern]
- @ @ @ \&if cdr& \\argument-list/ \[more than one argument remaining?]
- @ @ @ \&then begin&
- @ @ @ @ \\pattern/\gets\!pattern for \\functor/!;
- @ @ @ @ \\argument-list/\gets\&nil&
- @ @ @ \&end&
- @ @ @ \&else begin&
- @ @ @ @ \\aux/\gets\\mktag/(\&car& \\argument-list/,\\precedence/,%
- \&nil&);
- @ @ @ @ \\argument-list/\gets\&cdr& \\argument-list/
- @ @ @ \&end&
- @ @ \&else if& \!tag is (L \\hs/), (M \\vs hs/) or (APPLY xxx)! \&then&
- @ @ \&begin&
- @ @ @ \\aux/\gets\!result from call to a special routine!;
- @ @ @ \\argument-list/\gets\&nil&
- @ @ \&end&
- @ @ \&else& \\aux/\gets\&nil&;
- @ @ \&if& \\aux/ \&then& \!concatenate it to the end of term!
- @ \&end&;
- @ \&return& \\term/
- \&end&;
- \endDOC The function {\smalltt makefunc}: As well as the function
- {\smalltt mktag} this function performs the prefix-to-\TeX\
- notation. Its major task is to ``unify'' operators and their
- arguments with predefined patterns in order to build up lists of
- \TeX-items.\par
- % ----------------------------------------------------------------------
- You can bind a \TeX-item to any REDUCE atom (except the
- operators) you like. This is supported by binding the \TeX-item
- to the specific atom by its property \t{'TEXNAME}.
- You can choose to have some default \t{'TEXNAME}
- properties for your variables. Function \t{makeset} defines a set of
- such default names. At the moment, two sets are provided for greek
- and for lowercase letters. Refer to the User's Guide for how you can
- use them.\par
- But now turn back to the state of modifications our example term
- has undergone. With our set of functions we have expanded the prefix form
- into a \TeX-item list consisting of single \TeX-items such as
- numbers, letters, \TeX-macros, \TeX-primitives and other \TeX\
- symbols. The result is shown in figure 5. The \verb|\cdot|
- command is the multiplication sign, whereas \verb|^{| indicates
- the beginning of a superscript. (The term has been edited by hand
- to provide for proper indentation.)\par
- % ----------------------------------------------------------------------
- \VFig
- ( x ^{ 1 2 }
- - 1 2 \cdot x ^{ 1 1 } \cdot y
- + 6 6 \cdot x ^{ 1 0 } \cdot y ^{ 2 }
- - 2 2 0 \cdot x ^{ 9 } \cdot y ^{ 3 }
- + 4 9 5 \cdot x ^{ 8 } \cdot y ^{ 4 }
- - 7 9 2 \cdot x ^{ 7 } \cdot y ^{ 5 }
- + 9 2 4 \cdot x ^{ 6 } \cdot y ^{ 6 }
- - 7 9 2 \cdot x ^{ 5 } \cdot y ^{ 7 }
- + 4 9 5 \cdot x ^{ 4 } \cdot y ^{ 8 }
- - 2 2 0 \cdot x ^{ 3 } \cdot y ^{ 9 }
- + 6 6 \cdot x ^{ 2 } \cdot y ^{ 1 0 }
- - 1 2 \cdot x \cdot y ^{ 1 1 }
- + y ^{ 1 2 } )
- \endverbatim
- \endVFig A \TeX-item list: A \TeX-item is either a letter, a digit or
- another plain character, or it is a \TeX-command. Every \TeX-item
- belongs to one out of eight \TeX-item-classes.\par
- % ----------------------------------------------------------------------
- The last box in this chapter (i.e. figure 6) is a verbatim copy of the
- output from TRI for our example.
- Because our example will be used to demonstrate
- line-breaking, too, some additional commands appear which won't occur
- in normal \TeX-mode. These additional commands you find at the beginning
- and ending of the output and as \verb|\nl|-commands within the output.
- Nevertheless, the structure of the output would be much the same with
- our normal \TeX-mode.
- % ----------------------------------------------------------------------
- \VFig
- $$\displaylines{\qdd
- x^{12}
- -12\cdot x^{11}\cdot y
- +66\cdot x^{10}\cdot y^{2}
- -220\cdot x^{9}\cdot y^{3}
- +495\cdot x^{8}\cdot y^{4}
- -792\cdot x^{7}\cdot y^{5}\nl
- +924\cdot x^{6}\cdot y^{6}
- -792\cdot x^{5}\cdot y^{7}
- +495\cdot x^{4}\cdot y^{8}
- -220\cdot x^{3}\cdot y^{9}
- +66\cdot x^{2}\cdot y^{10}
- -12\cdot x\cdot y^{11}
- +y^{12}
- \Nl}$$
- \endverbatim
- \endVFig Output produced by the TRI: This \TeX-code has to be postprocessed
- by \TeX. This example includes commands for line-breaking as produced
- with the second level of TRI.\par
- % ----------------------------------------------------------------------
- The actual printing of TRI output in this example is easily readable
- since the expression is not deeply nested. Complications arise if
- expressions to be printed are deeply nested, use many subscripts
- and superscripts, have fractions and large operators and the like.
- Then output structure is worsened, especially if the whole expression
- extends over several lines. We provide a ``cheap'' way of indentation
- to retain some of the structure, but our solution is far from perfect.
- As the need for post-TRI-editing rises the output from TRI should be
- made better. However, our quick-and-dirty solution should suffice.
- % ----------------------------------------------------------------------
- \sec Breaking REDUCE expressions into lines\par
- % ----------------------------------------------------------------------
- As mentioned earlier, there are a few properties bound to each
- \TeX-item, two of them dealing with line-breaking.
- The following list gives you a survey of these two properties and
- the values they can take:\par
- \smallskip\itemize{17mm}
- \litem{\t{'CLASS}}one of the following class specifiers
- \itemitem{\t{'ORD\ }}ordinary symbols
- \itemitem{\t{'LOP\ }}large operators, such as integrals
- \itemitem{\t{'BIN\ }}binary operators
- \itemitem{\t{'REL\ }}relational operators
- \itemitem{\t{'OPN\ }}opening symbols (left parentheses)
- \itemitem{\t{'CLO\ }}closing symbols (right parentheses)
- \itemitem{\t{'PCT\ }}punctuation symbols
- \itemitem{\t{'INN\ }}inner \TeX\ group delimiters
- \litem{\t{'TEXTAG}}this is either an atom describing an \t{'INN} class
- or a list of widths defining the width of a \TeX-item, where
- succeeding elements of the list will be used depending on the
- \TeX\ inner group level (i.e. the nesting of subscripts or superscripts)
- \par\enditemize\smallskip\noindent
- Glue items are to be inserted between consecutive \TeX-items (similar to
- what \TeX\ does with its items). The following table specifies for
- each left and right class of a \TeX-item the corresponding glue measure.
- The glue item values have following meanings: 0 = no space,
- 1 = thin space, 2 = medium space, and 3 = thick space.
- An asterisk means that this case never arises, and
- values put in brackets indicate no space in the case of sub- or
- superscripts.\par
- %
- \midinsert
- \def\tablerule{\noalign{\hrule}}
- $$\vbox{\offinterlineskip
- \halign{&\vrule#&\quad\hfil\tt#\hfil\quad\cr
- \tablerule
- &\strut\rm Left&&\multispan{15}\hfil\rm Right Class\hfil&\cr
- &&&\multispan{15}\hrulefill&\cr
- &\strut\rm Class&&ORD&&LOP&&BIN&&REL&&OPN&&CLO&&PCT&&INN&\cr
- \tablerule
- &\strut ORD&&0&&1&&(2)&&(3)&&0&&0&&0&&0&\cr
- &\strut LOP&&1&&1&&*&&(3)&&0&&0&&0&&(1)&\cr
- &\strut BIN&&(2)&&(2)&&*&&*&&(2)&&*&&*&&(2)&\cr
- &\strut REL&&(3)&&(3)&&*&&0&&(3)&&0&&0&&(3)&\cr
- &\strut OPN&&0&&0&&*&&0&&0&&0&&0&&0&\cr
- &\strut CLO&&0&&1&&(2)&&(3)&&0&&0&&0&&0&\cr
- &\strut PCT&&(1)&&(1)&&*&&(1)&&(1)&&(1)&&(1)&&(1)&\cr
- &\strut INN&&0&&1&&(2)&&(3)&&(1)&&0&&(1)&&0&\cr
- \tablerule}}$$
- \endinsert
- Actually, a glue item is a list consisting of two elements --- a width
- info characterizing the width of this item (in scaled points)
- and a ``penalty'' to be used if a line should be broken at
- this point.
- The algorithm for inserting glue items is easily described:
- for every consecutive pair of \TeX-items, get their classes and create
- a glue item according to the value found in the glue item table.
- For some special \TeX-items use special penalties instead of the default
- values. That's all.\par
- Let us return to our example from the last chapter. When the functions
- \t{insertglue} and \t{interglue} have finished, the \TeX-item list
- will be left (temporarily) extended with glue items. You can find
- them as the two-element lists in the example. All glue items there
- have (by chance) the same width 163840. But they have different
- penalties 0, 50 and -390. The latter therefore indicates a very good breaking
- point because it is a negative penalty, i.e. a bonus.
- See the following figure 7 for the changes made to the \TeX-item list.
- % ----------------------------------------------------------------------
- \VFig
- ( x ^{ 1 2 } (163840 0)
- - 1 2 \cdot (163840 50) x ^{ 1 1 } \cdot (163840 50) y %
- (163840 -390)
- + 6 6 \cdot (163840 50) x ^{ 1 0 } \cdot (163840 50) y ^{ 2 } %
- (163840 0)
- - 2 2 0 \cdot (163840 50) x ^{ 9 } \cdot (163840 50) y ^{ 3 } %
- (163840 -390)
- + 4 9 5 \cdot (163840 50) x ^{ 8 } \cdot (163840 50) y ^{ 4 } %
- (163840 0)
- - 7 9 2 \cdot (163840 50) x ^{ 7 } \cdot (163840 50) y ^{ 5 } %
- (163840 -390)
- + 9 2 4 \cdot (163840 50) x ^{ 6 } \cdot (163840 50) y ^{ 6 } %
- (163840 0)
- - 7 9 2 \cdot (163840 50) x ^{ 5 } \cdot (163840 50) y ^{ 7 } %
- (163840 -390)
- + 4 9 5 \cdot (163840 50) x ^{ 4 } \cdot (163840 50) y ^{ 8 } %
- (163840 0)
- - 2 2 0 \cdot (163840 50) x ^{ 3 } \cdot (163840 50) y ^{ 9 } %
- (163840 -390)
- + 6 6 \cdot (163840 50) x ^{ 2 } \cdot (163840 50) y ^{ 1 0 } %
- (163840 0)
- - 1 2 \cdot (163840 50) x \cdot (163840 50) y ^{ 1 1 } %
- (163840 -390)
- + y ^{ 1 2 } )
- \endverbatim
- \endVFig A \TeX-item list extended with glue items: \par
- %
- %
- Setting break points requires the creation of a ``breaklist''.
- A breaklist is a sequence of passive and active nodes, where each
- active node is followed by a passive node and vice versa.
- Active nodes represent glue items.
- Passive nodes are integer atoms which represent the width of a sequence
- of ordinary \TeX-items which must not be interspersed with glue
- items. Each breaklist consists of (at least one) passive nodes surrounded
- by delta nodes representing the beginning and ending of the list.
- \medskip
- \settabs\+\indent&passive-node\quad&\cr
- \+&\i{breaklist} &::= ( \i{delta-node} \i{inner-list} \i{delta-node} )\cr
- \+&\i{inner-list} &::= \i{passive-node} \i{active-node} \dots
- \i{passive-node}\cr
- \+&\i{active-node} &::= ( \i{width} \i{penalty} \i{offset} )\cr
- \+&\i{passive-node} &::= \i{width}\cr
- \+&\i{delta-node} &::= \i{active-node} $+$ \i{appendix}\cr
- \+&\i{appendix} &::= ( \i{id-number} \i{ptr} \i{demerits}
- \i{indentation} )\cr
- \medskip
- The breaklist will be created using the function \t{breaklist}.
- line breaking is performed with this list only; the \TeX-item list
- becomes modified only indirectly since the active nodes are shared.
- That means that the active nodes aren't copied while creating the breaklist.
- Instead, their memory addresses are put into the breaklist as a reference.
- This is both memory saving and necessary, since later we deal
- with the \TeX-item list itself again in order to insert \verb|\nl|-commands.
- So remember there exist two lists sharing all the active nodes
- (and hence all the delta nodes). Figure 8 contains
- the breaklist from our $(x-y)^{12}$ example. Bear in mind that
- passive nodes are sums of widths. The first line and the last line contain
- the beginning and ending delta nodes, respectively.
- By default, their \i{id-numbers} are 0 and -1, respectively.
- %
- % ----------------------------------------------------------------------
- \VFig
- ((0 0 0 0 0 0 0)
- 915227 (163840 0 0) 1347128 (163840 50 0) 1097271 (163840 50 0)
- 321308 (163840 -390 0) 1347128 (163840 50 0) 1097271 (163840 50 0)
- 598015 (163840 0 0) 1674808 (163840 50 0) 820564 (163840 50 0)
- 598015 (163840 -390 0) 1674808 (163840 50 0) 820564 (163840 50 0)
- 598015 (163840 0 0) 1674808 (163840 50 0) 820564 (163840 50 0)
- 598015 (163840 -390 0) 1674808 (163840 50 0) 820564 (163840 50 0)
- 598015 (163840 0 0) 1674808 (163840 50 0) 820564 (163840 50 0)
- 598015 (163840 -390 0) 1674808 (163840 50 0) 820564 (163840 50 0)
- 598015 (163840 0 0) 1674808 (163840 50 0) 820564 (163840 50 0)
- 598015 (163840 -390 0) 1347128 (163840 50 0) 820564 (163840 50 0)
- 874722 (163840 0 0) 1347128 (163840 50 0) 543857 (163840 50 0)
- 874722 (163840 -390 0) 1384446
- (0 0 41140184 -1 0 2147483647 0))
- \endverbatim
- \endVFig A breaklist: Three types of objects are included in a breaklist.
- Active nodes are the lists with three elements. Delta nodes contain
- exactly seven elements. Passive nodes are integer atoms representing
- a width.\par
- % ----------------------------------------------------------------------
- %
- The task of setting the break points (i.e. break items) in the breaklist
- is up to the function \t{trybreak}. During this phase, some active nodes
- are selected as ``feasible'' break points. Thus, they will be extended and
- called ``delta nodes'' furtheron. By default, the first and last node in a
- breaklist are delta nodes. When trybreak has finished, the \i{ptr}'s of
- the delta nodes point back to the best preceding delta node
- in terms of minimal total demerits. So, by stepping through this pointer
- list, it is easy to find the best path for breaking the whole breaklist
- apart. We use some terminology we'd like to explain:
- \itemize{27mm}\medskip
- \litem{\i{width}}width of this item (both active and passive nodes)
- \litem{\i{penalty}}a numeric value which prohibits line breaking (if
- negative, line breaking will be merited)
- \litem{\i{offset}}distance to the most recent opening bracket
- \litem{\i{id-number}}the identification number of this delta node (1,2,3,...)
- \litem{\i{ptr}}pointer to the best delta node to come from with
- respect to the minimal demerits path. (Note: a zero
- pointer indicates the very beginning of the breaklist)
- \litem{\i{demerits}}total demerits accumulated so far
- \litem{\i{indentation}}amount of indentation when breaking at this point
- \par\enditemize\medskip
- The algorithm itself will be described now.
- To determine the ``quality'' of a line we introduce a value called
- ``badness''. It simply is a heuristic describing how good-looking a
- line comes out. This concept is due to Knuth/Plass(1981) and is a major
- concept
- of \TeX. We use a slightly different heuristic here. We do not measure
- badness in terms of ``stretchability'' and ``shrinkability''.
- Instead we measure how ``full'' a line is, where ``full''
- means that three quarters of the page width are optimal.
- Furthermore we add a surplus badness for the indentation: the less
- indentation the better.
- The badness is a value between 0 and 10000 and is calculated with
- the following code (displayed in figure 9).
- Surprisingly, we got a higher speed with floating point arithmetic
- here than with integer arithmetic.
- % ----------------------------------------------------------------------
- \DOC
- \&function& \\badnessof/(\\length/,\\indentation/);
- \&begin&
- @ \\temp/\gets\&abs&(\\length/$-{3\over4}*$\\pagewidth/)/(${1\over6}*$%
- \\pagewidth/);
- @ \&return min&($10000,100*temp^3+2500*$\\indentation/$/$\\pagewidth/)
- \&end&;
- \endDOC The badness function: ``Badness'' is just a heuristic to compute
- a numerical value describing how ``good-looking'' a line comes out.
- A correction term is applied to provide for indentation.\par
- % ----------------------------------------------------------------------
- Figure 10 summarizes the line breaking algorithm. The code
- is part of the function \t{trybreak} and describes the ``heart'' of
- our algorithm.
- Basically, it consists of two loops: the outer loop steps through
- the breaklist considering each delta node as a potential start of a
- new line while the inner loop looks ahead exactly one line (bounded
- by the \i{page-width} or by the rightmost delta-node) checking each
- active node if it is a feasible breakpoint, and if so, saving it as the best
- path of breaking. Or to put it in another way, simply imagine a
- window as wide as a page which moves over the unbroken expression
- from the very left to the very right. The left end of the window
- is put on every feasible breakpoint determined earlier. The right
- end of the window just defines the border of the search for feasible
- breakpoints within the window.
- % ----------------------------------------------------------------------
- \DOC
- \\bottom/\gets\\breaklist/;\quad\\pagewidth/\gets\ %
- \!user defined page width!;
- \!set all variables not mentioned explicitly to zero or nil!;
- \&while& \\bottom/ \&do&
- \&begin& \[try a new line starting at this delta node]
- @ \\base/\gets\&car& \\bottom/; \\top/\gets\&cdr& \\bottom/;
- @ \\baseid/\gets\\idof/ \\base/; \\baseptr/\gets\\ptrof/ \\base/;
- @ \\basedemerits/\gets\\demeritsof/ \\base/;
- @ \\baseoffset/\gets\\offsetof/ \\base/;
- @ \\baseindent/\gets\\length/\gets\\indentof/ \\base/;
- @ \\total/\gets\\total/+\\widthof/ \\base/;
- @ \&while& \\top/ \&and& \\length$<$pagewidth/ \&do&
- @ \&begin& \[consider this node for end of the line]
- @ @ \\node/\gets\&car& \\top/;
- @ @ \\penalty/\gets\\penaltyof/ \\node/;
- @ @ \&if& \!node is a passive node!
- @ @ \&then& \\len/\gets\\len/+\\node/
- @ @ \&else begin& \[node is an active node]
- @ @ @ \\badness/\gets\ \!compute current badness from \\length/ and%
- \\baseindent/!
- @ @ @ \\penalty/\gets\\penaltyof/ \\node/; \\offset/\gets\\offsetof/%
- \\node/;
- @ @ @ \&if& \\badness $<$ tolerance/
- @ @ @ \&or& \\badness $< 1-$penalty/
- @ @ @ \&or& \!this is the rightmost delta node!
- @ @ @ \&then begin& \[we have a feasible breakpoint]
- @ @ @ @ \\demerits/\gets\\basedemerits/+\\badness/$^2+$\\penalty/$*$%
- \&abs&(\\penalty/);
- @ @ @ @ \&if& \!node is a delta node!
- @ @ @ @ \&then begin&
- @ @ @ @ @ \&if& \\demerits$<$demeritsof node/ \[better path found?]
- @ @ @ @ @ \&then begin&
- @ @ @ @ @ @ \!save current \\demerits/ and \\baseid/ to \\node/!;
- @ @ @ @ @ @ \!compute amount of indentation!
- @ @ @ @ @ \&end&
- @ @ @ @ \&end&
- @ @ @ @ \&else begin&
- @ @ @ @ @ \\feasible/\gets\\feasible/+1;
- @ @ @ @ @ \!create new delta node with \\feasible, baseid, demerits/!;
- @ @ @ @ @ \!compute amount of indentation!
- @ @ @ @ \&end&;
- @ @ @ @ \&if& \\penalty/$=-10000$ \&then& \\top/\gets\&nil&%
- \[must break here]
- @ @ @ \&end;&
- @ @ @ \\length/\gets\\length/+\\wdithof node/
- @ @ \&end&;
- @ @ \&if& \\top/ \&then& \\top/\gets\&cdr& \\top/
- @ \&end&;
- @ \!save the total length so far to the delta node!;
- @ \!step ahead to next delta node and count total length!
- \&end&;
- \endDOC The code segment from {\smalltt trybreak} dealing with line-breaking:
- \par
- % ----------------------------------------------------------------------
- Earlier we introduced the concept of ``badness'' derived from \TeX.
- But actually this is not the only measure answering the question whether
- a certain point in the breaklist is feasible or not. There are three
- conditions which decide whether a breakpoint is feasible or not.
- The first condition requires the badness to be smaller than the value
- of \i{tolerance} as specified by the user. This condition can be overridden
- if the active node under consideration has a negative penalty whose
- (absolute, i.e. positive) amount is greater than the badness.
- That means you can buy a breakpoint if you've got enough money
- (i.e. a bonus = negative penalty) to pay the price (i.e. the badness).
- The third condition just forces the rightmost delta node to be
- considered feasible anyway.\note{This is necessary since the end
- of the expression is naturally a breakpoint even if it is a bad one,
- and the last delta node is needed for accounting purposes as well as
- for storing the pointer to the preceding breakpoints.}
- At this point we introduce a second measure called ``demerits'' which
- is defined as the sum of the demerits so far (i.e. up to the
- beginning of the line currently under consideration), the squared
- badness and the sign-propagated square of the penalty.\note{The
- latter is evaluated as the product of the value (which can
- be positive or negative) and the absolute value (which can be
- positive only).} Now we have a measure which not only refers to
- the current line but to the previous lines, too. Therefore, our
- modified {\caps Knuth}-algorithm ``optimizes'' not only over
- \i{one} line but over \i{all} lines.\par
- Figure 11 should make clear what is happening to the breaklist
- and the \TeX-item list. For readability purposes we display the latter,
- but really it is the breaklist under consideration within \t{trybreak}.
- As in the previous display of our example, you can identify the
- active-nodes. These are the three element number lists. The third
- element which is zero here is used as an offset width to the last
- opening bracket. This information is used for indentation.
- The delta-nodes are remarkable. These are the number lists with seven
- elements. Count them by their fourth element. They run 0, 1, 2
- through 8, 9, -1. The fifth element gives you the way back through the
- list. Start at the last delta-node. There the best way to come from
- is 1. So go to delta-node 1 where you find 0 as the best way to come
- from. Delta-node 0 is the beginning, so you're finished. The sixth element
- stands for the total demerits so far. The seventh element stands for
- the amount of indentation. Here it is a zero because the term isn't
- nested in our example.
- % ----------------------------------------------------------------------
- \VFig
- ( ( 0 0 0 0 0 0 0)
- x ^{ 1 2 } (163840 0 0)
- - 1 2 \cdot (163840 50 0) x ^{ 1 1 }
- \cdot (163840 50 0) y (163840 -390 0)
- + 6 6 \cdot (163840 50 0) x ^{ 1 0 }
- \cdot (163840 50 0) y ^{ 2 } (163840 0 0)
- - 2 2 0 \cdot (163840 50 0) x ^{ 9 }
- \cdot (163840 50 0) y ^{ 3 } (163840 -390 0)
- + 4 9 5 \cdot (163840 50 0) x ^{ 8 }
- \cdot (163840 50 0) y ^{ 4 } (163840 0 0)
- - 7 9 2 \cdot (163840 50 0) x ^{ 7 }
- \cdot (163840 50 0) y ^{ 5 } (163840 18624949 0 1 0 -151875 0)
- + 9 2 4 \cdot (163840 20463597 0 2 0 2500 0)
- x ^{ 6 }
- \cdot (163840 21448001 0 3 0 2500 0)
- y ^{ 6 } (163840 22209856 0 4 0 1 0)
- - 7 9 2 \cdot (163840 50 0) x ^{ 5 }
- \cdot (163840 50 0) y ^{ 7 } (163840 25794763 0 5 0 -142299 0)
- + 4 9 5 \cdot (163840 50 0) x ^{ 4 }
- \cdot (163840 50 0) y ^{ 8 } (163840 0 0)
- - 2 2 0 \cdot (163840 50 0) x ^{ 3 }
- \cdot (163840 50 0) y ^{ 9 } (163840 32964577 0 6 1 -207875 0)
- + 6 6 \cdot (163840 50 0) x ^{ 2 }
- \cdot (163840 50 0) y ^{ 1 0 } (163840 0 0)
- - 1 2 \cdot (163840 38009479 0 7 1 -149350 0)
- x
- \cdot (163840 38717176 0 8 1 -149374 0)
- y ^{ 1 1 } (163840 39755738 0 9 1 -303975 0)
- + y ^{ 1 2 } ( 0 41140184 ?-1 1 -151866 ?)
- \endverbatim
- \endVFig A \TeX-item list extended with delta-nodes: From this list
- the line-breaking way can be derived. Start with node --1, go to node
- 1 and from there to node 0. That makes one break point at node 1.\par
- We haven't mentioned how we generate indentation yet. Generally speaking,
- indentation is entirely directed by brackets, either round, curly, or
- dummy brackets. But how do we compute the amount of indentation?
- First let's turn to the code segment which deals with this problem
- within the big line-braking algorithm shown before. The contents of
- figure 12 explains what happens to the amount of indentation.
- % ----------------------------------------------------------------------
- \DOC
- \!compute amount of indentation! ::=
- \&begin&
- @ \&if& \\offset/$>$\\total/
- @ \&then& \\indent/\gets\\offset$-$total$+$baseindent/ \ \ %
- \[opening bracket case]
- @ \&else if& \\offset$<$baseoffset/
- @ @ \&then& \\indent/\gets\\findindent/() \ \ \ \ \ \ \ \ %
- \ \ \ \[closing bracket case]
- @ @ \&else& \\indent/\gets\\baseindent/; \ \ \ \ \ \ \ \ \ %
- \ \ \ \ \[no change case]
- @ \!save \\indent/ to delta-node!
- \&end&;
- \endDOC The code segment from {\smalltt trybreak} dealing with indentation:
- \par
- % ----------------------------------------------------------------------
- The logic of this code segment is easily summarized. The \i{offset}
- is a measure of how distant the last opening bracket is from the beginning
- of the whole expression. So in the case where \i{offset} is greater than
- the total width accumulated until the very beginning of the line, the
- indentation is just the difference between \i{total}
- and the sum of \i{offset}
- and the amount of indentation \i{baseindent} for the currently line.
- That'll work if the line currently under consideration contains at least
- one opening bracket which hasn't become closed in the same line.
- This case may be labelled the ``opening bracket case''.
- But what shall we do in the other cases? We have to decide if we've got
- a ``closing bracket case'', i.e. if we have at least one more closing
- bracket than we have opening brackets, or if we've got a ``no change
- case'', i.e. the number of opening brackets in the current line matches
- the number of closing brackets in this line. This decision is made by
- comparing \i{offset}$<$\i{baseoffset}. If the \i{baseoffset}, i.e.
- the offset at the beginning of the line, is greater than \i{offset},
- i.e. the offset at the current point, then we've got the ``closing
- bracket case'', otherwise we've got the ``no change case''.
- In the latter, the amount of indentation for the next line is just
- the amount of indentation for the current line. But the ``closing
- bracket case'' causes us much trouble. So we need an extra function dealing
- with this case, as displayed in figure 13.
- % ----------------------------------------------------------------------
- \DOC
- \¯o function& \\findindent/;
- \[macro functions share all variables of outer code blocks]
- \&begin& \[first check if we can save search time for equal destination]
- @ \&if& \\offset/$=$\\lastoffset/ \&and& \\baseptr/$=$\\lastbaseptr/
- @ \&then return& \\lastindent/
- @ \&else begin& \[search the delta-node-stack for previous indentation]
- @ @ \\stack/\gets\\deltastack/; \\lastoffset/\gets\\offset/;
- @ @ \\p/\gets\\lastbaseptr/\gets\\baseptr/;
- @ @ \&while& \\stack/ \&do& \[as long as we have a delta-node ahead]
- @ @ \&begin&
- @ @ @ \\node/\gets\&car& \\stack/; \[current delta-node]
- @ @ @ \&if& \\p$=$idof node/ \&then begin&
- @ @ @ @ \\p/\gets\\ptrof node/; \\local/\gets\\totalof node/;
- @ @ @ @ \&if& \\local$<$offset/ \&then& \\stack/\gets\&nil&
- @ @ @ \&end&;
- @ @ @ \&if& \\stack/ \&then& \\stack/\gets\&cdr& \\stack/
- @ @ \&end&;
- @ @ \\lastindent/\gets\\offset$-$local$+$indentof node/;
- @ @ \&return& \\lastindent/
- @ \&end&
- \&end&;
- \endDOC The macro function findindent: This macro is used to compute the
- amount of indentation in the ``closing bracket case''. It causes some
- trouble since we have to travel back to previous delta nodes.\par
- % ----------------------------------------------------------------------
- This macro\note{Macros become expanded where they are called and thus
- share all variable names defined in the code block where they are called.
- So, there is no need for argument passing if certain variable names in
- the code block don't differ from call to call.} searches the list
- of delta-nodes previously created until it reaches a delta-node (at
- least the very first delta-node in the breaklist) where the total
- width accumulated so far, i.e. the variable \i{local}, is less than
- \i{offset}, i.e. the offset at the end of the line under consideration,
- and computes the amount of indentation from the difference of
- \i{offset} and \i{local} plus the amount of indentation so far.
- Plainly speaking, we go back the lines until we find a line where
- we find the opening parenthesis matching the closing parenthesis
- in the current line. When we've found it, we compute the amount of
- indentation as described in the ``opening bracket case'', but with
- \i{local} instead of \i{total}.
- % ----------------------------------------------------------------------
- \sec Postprocessing with the \TeX\ module ``tridefs.tex''\par
- % ----------------------------------------------------------------------
- When a \TeX-output-file has been created with the TRI it has to be
- processed by \TeX\ itself. But before you run \TeX\ you should make sure
- the file looks the way you want it. Sometimes you will
- find it necessary to add some \TeX-code of your own or delete some
- other \TeX-code. This job is up to you before you finally run \TeX.\par
- During the \TeX-run the sizes of brackets are determined. This task is
- not done by the TRI. In order to produce proper sized brackets
- we put some \verb|\left(| and \verb|\right)| \TeX-commands
- where brackets are opened or closed. A new problem arises when
- an expression has been broken up into several lines. Since, for every
- line, the number of \verb|\left(| and \verb|\right)| \TeX-commands must
- match but bracketed expressions may start in one line and end in another,
- we have to insert the required number of ``dummy'' parentheses
- (i.e. \verb|\right.| and \verb|\left.| \TeX-commands)
- at the end of the current line and the beginning of the following line.
- Therefore, we have to keep track of the depth of bracketing.
- See the following figure 14 for the \TeX-code actually applied.\par
- There is a caveat against this method. Since opening and closing brackets
- needn't lie in the same line, it is possible that the height of the
- brackets can differ although they should correspond in height. That will
- happen if the height of the text in the opening line has a height
- different from the text in the closing line. We haven't found a
- way of tackling this problem yet, but we think it is possible to program
- a little \TeX-macro for this task.
- Furthermore, some macros deal with tricks we had to use in order to
- provide for indentation, fraction handling and the like.
- \VVFig
- \def\qdd{\quad\quad} % simply a double quad
- \def\frac#1#2{{#1\over#2}} % fractions from prefix notation
- \newcount\parenthesis % nesting of brackets
- \parenthesis=0 % intialize
- \newcount\n % a temporary variable
- % ---- round and curly brackets ----
- \def\({\global\advance\parenthesis by1\left(}
- \def\){\global\advance\parenthesis by-1\right)}
- \def\{{\global\advance\parenthesis by1\left\lbrace}
- \def\}{\global\advance\parenthesis by-1\right\rbrace}
- \def\[{\relax} % dummy parenthesis
- \def\]{\relax} % dummy parenthesis
- % ---- provide for looping using tail recursion ----
- % \loop ...what... \repeat
- \def\loop#1\repeat{\global\n=0\global\let\body=#1\iterate}
- \def\iterate{\body\let\next=\iterate\else\let\next=\relax\fi\next}
- % ---- conditions and statements for loop interior
- \def\ldd{\ifnum\n<\parenthesis\global\advance\n by1
- \left.\nulldelimiterspace=0pt\mathsurround=0pt}
- \def\rdd{\ifnum\n<\parenthesis\global\advance\n by1
- \right.\nulldelimiterspace=0pt\mathsurround=0pt}
- % ---- newline statement as issued by TRI ----
- \def\nl{\loop\rdd\repeat\hfill\cr\quad\quad\loop\ldd\repeat{}}
- % ---- indentation statement as issued by TRI ----
- \def\OFF#1{\hskip#1sp\relax}
- % ---- last newline statement before end of math group ----
- \def\Nl{\hfill\cr}
- \endverbatim
- \endVFig The file ``tridefs.tex'': This is the code you have
- to use on the \TeX\ side in order to typeset output produced by our
- TRI.\par
- \noindent There is at least one more line of \TeX-code you have to
- insert by hand into the \TeX-input-file produced by TRI. This line runs
- \verbatim
- \input tridefs
- \endverbatim\noindent
- and inputs the module \t{tridefs.tex} into the file. This is necessary
- because otherwise \TeX\ won't know how to deal with our macro calls.
- If you use the \TeX-input-file as a ``stand-alone'' file, don't
- forget a final \verb|\bye| at the end of the text. If you use
- code produced by TRI as part of a larger text then simply put
- the input-line just once at the beginning of your text.
- % ----------------------------------------------------------------------
- \sec Experiments\par
- % ----------------------------------------------------------------------
- We measured performance using the TIME-facility of REDUCE, which can be
- switched on and off with the two commands
- \example
- ON TIME;
- OFF TIME;
- \endexample
- We have tested our TRI on a \VAX\ operating under VAX/VMS,
- with no other users operating during this phase in order to minimize
- interference with other processes, e.g. caused by paging.
- The TRI code has been compiled with the PSL~3.2a-Compiler.
- The following table presents results obtained with a small number of
- different terms. All data were measured in CPU-seconds
- as displayed by LISP's TIME-facility.
- For expressions where special packages such as \t{solve} and \t{int}
- were involved we have taken only effective output-time, i.e. the time
- consumption caused by producing the output and not by evaluating
- the algebraic result.\note{That means we assigned the result of an
- evaluation to an itermediate variable, and then we printed this
- intermediate variable. Thus we could eliminate the time overhead
- produced by ``pure'' evaluation. Nevertheless, in terms of effective
- interactive answering time, the sum of evaluation and printing time
- might be much more interesting than the ``pure'' printing time.
- In such a context the percentage overhead caused by printing is
- the critical point. But since we talk about printing we decided
- to document the ``pure'' printing time.}\par
- \def\strut{\vrule height8pt depth4pt width0pt}
- \def\tablerule{\noalign{\hrule}}
- \def\hdbox#1{\hbox to 12truemm{\small\hfil#1\hfil}}
- \def\[#1]{$\scriptstyle#1$\hfil}
- $$\vbox{
- \offinterlineskip
- \halign{&\strut\vrule#&\quad\hfil\smalltt#\quad\cr
- \tablerule
- &{\smallbf REDUCE-}\hfil&&\hdbox{\small nor-}&&
- \hdbox{TeX}&&\hdbox{\small TeX-}&&\hdbox{\small TeX-}&\cr
- &{\smallbf Expression}\hfil&&\hdbox{\small mal}&&
- &&\hdbox{\small Break}&&\hdbox{\small Indent}&\cr
- \tablerule
- &\[(x+y)^{12}]&& 0.82&& 0.75&& 3.42&& 3.47&\cr
- &\[(x+y)^{24}]&& 2.00&& 2.22&&12.52&&12.41&\cr
- &\[(x+y)^{36}]&& 4.40&& 4.83&&21.48&&21.44&\cr
- &\[(x+y)^{16}/(v-w)^{16}]&& 2.27&& 2.38&&12.18&&12.19&\cr
- &\[solve((1+\xi)x^2-2\xi x+\xi,x)]&& 0.41&& 0.62&& 0.89&& 0.87&\cr
- &\[solve(x^3+x^2\mu+\nu,x)]&& 4.21&&20.84&&31.82&&40.43&\cr
- \tablerule
- }}$$\vskip5pt
- \noindent This short table should give you an impression of the
- performance of TRI. It goes without saying that on other machines
- results may turn out which are quite different from our results. But our
- intention is to show the relative and not the absolute performance.
- Note that printing times are a function of expression complexity,
- as shown by rows three and six.
- % ----------------------------------------------------------------------
- \sec User's Guide to the REDUCE-\TeX-Interface\par
- % ----------------------------------------------------------------------
- If you intend to use the TRI you are required to load the compiled code.
- This can be performed with the command
- \example
- load!-package 'tri;
- \endexample
- During the load, some default initializations are performed. The
- default page width is set to 15 centimeters, the tolerance for
- page breaking is set to 20 by default. Moreover, TRI is enabled
- to translate greek names, e.g. TAU or PSI, into equivalent \TeX\
- symbols, e.g. $\tau$ or $\psi$, respectively. Letters are printed
- lowercase as defined through assertion of the set LOWERCASE. The whole
- operation produces the following lines of output
- \example
- *** Function TEXVARPRI redefined
- \% set GREEK asserted
- \% set LOWERCASE asserted
- \% \B hsize=150mm
- \% \B tolerance 20
- \endexample
- Now you can switch on and off the three TRI modes as you like.
- You can use the switches alternatively and incrementally.
- That means you have to switch on TeX for receiving standard
- \TeX-output, or TeXBreak to receive broken \TeX-output, or
- TeXIndent to receive broken \TeX-output plus indentation.
- Thus, the three levels of TRI are enabled or disabled according to:
- \example
- On TeX; \% switch TeX is on
- On TeXBreak; \% switches TeX and TeXBreak are on
- On TeXIndent; \% switches TeX, TeXBreak and TeXIndent are on
- Off TeXIndent; \% switch TeXIndent is off
- Off TeXBreak; \% switches TeXBreak and TeXIndent are off
- Off TeX; \% all three switches are off
- \endexample
- More specifically, if you switch off {\tt TeXBreak} you implicitly quit
- {\tt TeXIndent}, too, or, if you switch off {\tt TeX} you implicitly quit
- {\tt TeXBreak} and, consequently, {\tt TeXIndent}.\par
- The most crucial point in defining how TRI breaks multiple lines
- of \TeX-code is your choice of the page width and the tolerance.
- As mentioned earlier, ``tolerance'' is related to \TeX's famous
- line-breaking algorithm. The value of ``tolerance'' determines which
- potential breakpoints are considered feasible and which not. The
- higher the tolerance, the more breakpoints become feasible as determined
- by the value of ``badness'' associated with each breakpoint. Breakpoints
- are considered feasible if the badness is less than the tolerance.
- You can easily set values for page width and tolerance using
- \example
- TeXsetbreak(\i{page-width},\i{tolerance});
- \endexample
- where \i{page-width} is measured in millimeters\note{You can
- also specify page width in scaled points (sp).
- Note: 1~pt = 65536~sp = 1/72.27~inch. The function automatically chooses
- the appropiate dimension according to the size: all values greater than
- 400 are considered to be scaled points.} and the \i{tolerance} is
- a positive integer in the closed interval $[0\ldots10000]$.
- You should choose a page width according to your purposes,
- but allow a few centimeters for errors in TRI's metric.
- For example, specify 140 millimeters for an effective 150 or 160
- millimeter wide page. That way you have a certain safety-margin to
- the borders of the page. Now let's turn to the tolerance.
- A tolerance of 0 means that actually no breakpoint will be considered
- feasible (except those carrying a negative penalty), while a value
- of 10000 allows any breakpoint to be considered feasible.
- Obviously, the choice of a tolerance has a great impact on the time
- consumption of our line-breaking algorithm since time consumption
- increases in proportion to the number of feasible breakpoints.
- So, the question is what values to choose. For line-breaking without
- indentation, suitable values for the tolerance lie between 10 and 100.
- As a rule of thumb, you should use higher values the deeper the term
- is nested --- if you can estimate. If you use indentation, you have to
- use much higher tolerance values. This is necessary because badness
- is worsened by indentation. So, TRI has to try harder to find
- suitable places where to break. Reasonable values for tolerance
- here lie between 700 and 1500. A value of 1000 should be your first
- guess. That'll work for most expressions in a reasonable amount of
- time.\par
- Sometimes you want to add your own REDUCE-symbol-to-\TeX-item
- translations. For such a task, TRI provides a function named
- \t{TeXlet} which binds any REDUCE-symbol to one of the predefined
- \TeX-items. A call to this function has the following syntax:
- \example
- TeXlet(\i{REDUCE-symbol},\i{\TeX-item})
- \endexample
- Three examples show how to do it right:
- \example
- TeXlet('velocity,'!v);
- TeXlet('gamma,\verb|'!\!G!a!m!m!a! |);
- TeXlet('acceleration,\verb|'!\!v!a!r!t!h!e!t!a! |);
- \endexample
- Besides this method of single assertions you can choose to assert
- one of (currently) two standard sets providing substitutions
- for lowercase and greek letters. These sets are loaded by default.
- You can switch these sets on or off using the functions
- \example
- TeXassertset \i{setname};
- TeXretractset \i{setname};
- \endexample
- where the setnames currently defined are \t{'GREEK} and \t{'LOWERCASE}.
- So far you have learned only how to connect REDUCE-atoms with predefined
- \TeX-items but not how to create new \TeX-items itself. We provide a
- way for adding standard \TeX-items of any class \t{'ORD, 'BIN, 'REL,
- 'OPN, 'CLO, 'PCT} and \t{LOP} except for class \t{'INN} which is
- reserved for internal use by TRI only. You can call the function
- \example
- TeXitem(\i{item},\i{class},\i{list-of-widths})
- \endexample
- e.g. together with a binding
- \example
- TeXitem(\verb|'!\!n!a!b!l!a! |,'ORD,'(655360 327680 163840))
- TeXlet('NABLA,\verb|'!\!n!a!b!l!a! |);
- \endexample
- where \i{item} is a legal \TeX-code name\note{Please note that
- any \TeX-name ending with a letter must be followed by a blank
- to prevent from interference with letters of following \TeX-items.
- Note also that you can legalize a name by defining it as a \TeX-macro.},
- \i{class} is one of seven classes (see above) and \i{list-of-width}
- is a non-empty list of elements each one representing the width of
- the item in successive super-/subscript depth levels. That means that the
- first entry is the breadth in display mode, the second stands for
- scriptstyle and the third stands for scriptscriptstyle in \TeX-%
- terminology. But how can you retrieve the width information required?
- For this purpose we provide the following small interactive \TeX\ facility
- called \t{redwidth.tex} documented in figure 15. Simply call
- \example
- tex redwidth
- \endexample
- on your local machine. Then you are prompted for the \TeX-item
- you want the width information for. Type ``end'' when you
- want to finish the session.
- \VVFig
- \newbox\testbox\newcount\xxx\newif\ifOK\def\endloop{end }
- \def\widthof#1{\message{width is: }\wwidthof{$\displaystyle#1$}
- \wwidthof{$\scriptstyle#1$}\wwidthof{$\scriptscriptstyle#1$}}
- \def\wwidthof#1{\setbox\testbox=\hbox{#1}\xxx=\wd\testbox
- \message{[\the\wd\testbox=\the\xxx sp]}}
- \loop\message{Type in TeX item or say 'end': }\read-1 to\answer
- \ifx\answer\endloop\OKfalse\else\OKtrue\fi
- \ifOK\widthof{\answer}
- \repeat
- \end
- \endverbatim
- \endVFig The file ``redwidth.tex'': This \TeX\ code you can use to
- determine the width of specific \TeX-items.\par
- Finally let us discuss how you can compile the TRI into a binary.
- (We refer to PSL, but other LISP versions work quite similar.)
- First of all start REDUCE. Than type in\par
- \verbatim
- on comp;
- symbolic;
- faslout "tri";
- in "tri.red";
- faslend;
- bye;
- \endverbatim\noindent
- We stress the fact that this procedure is definitely LISP dependent.
- Ask your local REDUCE or LISP wizards how to adapt to it.
- % ----------------------------------------------------------------------
- \sec Examples\par
- % ----------------------------------------------------------------------
- Some examples --- which we think might be representative ---
- shall demonstrate the capabilities of our TRI.
- For each example we state (a) the REDUCE command (i.e.
- the input), (b) the tolerance if it differs from the default, and
- (c) the output as produced in a \TeX\ run.\par
- \newcount\exacount\exacount=0
- \def\strut{\vrule height11pt depth4pt width0pt}
- \def\exa#1 \mod#2 \tol#3 \cod#4 \^^M{\global\advance\exacount by1\par
- {\offinterlineskip
- \vbox{
- \hrule
- \line{\strut\vrule
- \hbox to 8mm{\hfil\caps\the\exacount\hfil}\vrule
- \quad\rm#1\hfill\vrule
- \hbox to 32mm{\hfill{\smallcaps Mode: }{\tt #2}\hfill}\vrule
- \hbox to 32mm{\hfill{\smallcaps Tolerance: }{\tt #3}\hfill}\vrule}
- \hrule
- \line{\strut\vrule\hfill\tt#4\hfill\vrule}
- \hrule}
- }\nobreak}
- \bigskip\input tridefs
- % ------------------------------ Examples ------------------------------
- \exa Standard
- \mod TeXindent
- \tol 250
- \cod (x+y){*}{*}16{/}(v-w){*}{*}16;
- \
- $$\displaylines{\qdd
- \(x^{16}
- +16\cdot x^{15}\cdot y
- +120\cdot x^{14}\cdot y^{2}
- +560\cdot x^{13}\cdot y^{3}\nl
- \OFF{327680}
- +1820\cdot x^{12}\cdot y^{4}
- +4368\cdot x^{11}\cdot y^{5}
- +8008\cdot x^{10}\cdot y^{6}\nl
- \OFF{327680}
- +11440\cdot x^{9}\cdot y^{7}
- +12870\cdot x^{8}\cdot y^{8}
- +11440\cdot x^{7}\cdot y^{9}\nl
- \OFF{327680}
- +8008\cdot x^{6}\cdot y^{10}
- +4368\cdot x^{5}\cdot y^{11}
- +1820\cdot x^{4}\cdot y^{12}\nl
- \OFF{327680}
- +560\cdot x^{3}\cdot y^{13}
- +120\cdot x^{2}\cdot y^{14}
- +16\cdot x\cdot y^{15}
- +y^{16}
- \)
- /\nl
- \(v^{16}
- -16\cdot v^{15}\cdot w
- +120\cdot v^{14}\cdot w^{2}
- -560\cdot v^{13}\cdot w^{3}\nl
- \OFF{327680}
- +1820\cdot v^{12}\cdot w^{4}
- -4368\cdot v^{11}\cdot w^{5}
- +8008\cdot v^{10}\cdot w^{6}
- -11440\cdot v^{9}\cdot w^{7}\nl
- \OFF{327680}
- +12870\cdot v^{8}\cdot w^{8}
- -11440\cdot v^{7}\cdot w^{9}
- +8008\cdot v^{6}\cdot w^{10}
- -4368\cdot v^{5}\cdot w^{11}\nl
- \OFF{327680}
- +1820\cdot v^{4}\cdot w^{12}
- -560\cdot v^{3}\cdot w^{13}
- +120\cdot v^{2}\cdot w^{14}
- -16\cdot v\cdot w^{15}
- +w^{16}
- \)
- \Nl}$$
- \exa Integration
- \mod TeX
- \tol -;
- \cod int(1/(x{*}{*}3+2),x)
- \
- $$
- -
- \(\frac{2^{\frac{1}{
- 3}}\cdot
- \(2\cdot
- \sqrt{3}\cdot
- \arctan
- \(\frac{2^{\frac{1}{
- 3}}
- -2\cdot x}{
- 2^{\frac{1}{
- 3}}\cdot
- \sqrt{3}}
- \)
- +
- \ln
- \(2^{\frac{2}{
- 3}}
- -2^{\frac{1}{
- 3}}\cdot x
- +x^{2}
- \)
- -2\cdot
- \ln
- \(2^{\frac{1}{
- 3}}
- +x
- \)
- \)
- }{
- 12}
- \)
- $$
- \exa Integration
- \mod TeXindent
- \tol 1000
- \cod int(1/(x{*}{*}4+3*x{*}{*}2-1,x);
- \
- $$\displaylines{\qdd
- \(\sqrt{2}\cdot
- \(3\cdot
- \sqrt{
- \sqrt{13}
- -3}\cdot
- \sqrt{13}\cdot
- \ln
- \(-
- \(\sqrt{
- \sqrt{13}
- -3}\cdot
- \sqrt{2}
- \)
- +2\cdot x
- \)
- \nl
- \OFF{2260991}
- -3\cdot
- \sqrt{
- \sqrt{13}
- -3}\cdot
- \sqrt{13}\cdot
- \ln
- \(\sqrt{
- \sqrt{13}
- -3}\cdot
- \sqrt{2}
- +2\cdot x
- \)
- \nl
- \OFF{2260991}
- +13\cdot
- \sqrt{
- \sqrt{13}
- -3}\cdot
- \ln
- \(-
- \(\sqrt{
- \sqrt{13}
- -3}\cdot
- \sqrt{2}
- \)
- +2\cdot x
- \)
- \nl
- \OFF{2260991}
- -13\cdot
- \sqrt{
- \sqrt{13}
- -3}\cdot
- \ln
- \(\sqrt{
- \sqrt{13}
- -3}\cdot
- \sqrt{2}
- +2\cdot x
- \)
- \nl
- \OFF{2260991}
- +6\cdot
- \sqrt{
- \sqrt{13}
- +3}\cdot
- \sqrt{13}\cdot
- \arctan
- \(\frac{2\cdot x}{
- \sqrt{
- \sqrt{13}
- +3}\cdot
- \sqrt{2}}
- \)
- \nl
- \OFF{2260991}
- -26\cdot
- \sqrt{
- \sqrt{13}
- +3}\cdot
- \arctan
- \(\frac{2\cdot x}{
- \sqrt{
- \sqrt{13}
- +3}\cdot
- \sqrt{2}}
- \)
- \)
- \)
- /104
- \Nl}$$
- \exa Solving Equations
- \mod TeXindent
- \tol 1000
- \cod solve(x{*}{*}3+x{*}{*}2*mu+nu=0,x);
- \
- $$\displaylines{\qdd
- \{x=
- \[-
- \(\(\(9\cdot
- \sqrt{4\cdot \mu ^{3}\cdot \nu
- +27\cdot \nu ^{2}}
- -2\cdot
- \sqrt{3}\cdot \mu ^{3}
- -27\cdot
- \sqrt{3}\cdot \nu
- \)
- ^{\frac{2}{
- 3}}\cdot
- \sqrt{3}\cdot i\nl
- \OFF{3675021}
- +
- \(9\cdot
- \sqrt{4\cdot \mu ^{3}\cdot \nu
- +27\cdot \nu ^{2}}
- -2\cdot
- \sqrt{3}\cdot \mu ^{3}
- -27\cdot
- \sqrt{3}\cdot \nu
- \)
- ^{\frac{2}{
- 3}}\nl
- \OFF{3675021}
- +2\cdot
- \(9\cdot
- \sqrt{4\cdot \mu ^{3}\cdot \nu
- +27\cdot \nu ^{2}}
- -2\cdot
- \sqrt{3}\cdot \mu ^{3}
- -27\cdot
- \sqrt{3}\cdot \nu
- \)
- ^{\frac{1}{
- 3}}\cdot \nl
- \OFF{3675021}
- 2^{\frac{1}{
- 3}}\cdot 3^{\frac{1}{
- 6}}\cdot
- \mu
- -2^{\frac{2}{
- 3}}\cdot
- \sqrt{3}\cdot 3^{\frac{1}{
- 3}}\cdot
- i\cdot \mu ^{2}
- +2^{\frac{2}{
- 3}}\cdot 3^{\frac{1}{
- 3}}\cdot
- \mu ^{2}
- \)
- /\nl
- \OFF{3347341}
- \(6\cdot
- \(9\cdot
- \sqrt{4\cdot \mu ^{3}\cdot \nu
- +27\cdot \nu ^{2}}
- -2\cdot
- \sqrt{3}\cdot \mu ^{3}
- -27\cdot
- \sqrt{3}\cdot \nu
- \)
- ^{\frac{1}{
- 3}}\cdot 2^{\frac{1}{
- 3}}\cdot
- 3^{\frac{1}{
- 6}}
- \)
- \)
- \]
- \,\nl
- \OFF{327680}
- x=
- \[\(\(9\cdot
- \sqrt{4\cdot \mu ^{3}\cdot \nu
- +27\cdot \nu ^{2}}
- -2\cdot
- \sqrt{3}\cdot \mu ^{3}
- -27\cdot
- \sqrt{3}\cdot \nu
- \)
- ^{\frac{2}{
- 3}}\cdot
- \sqrt{3}\cdot i\nl
- \OFF{2837617}
- -
- \(9\cdot
- \sqrt{4\cdot \mu ^{3}\cdot \nu
- +27\cdot \nu ^{2}}
- -2\cdot
- \sqrt{3}\cdot \mu ^{3}
- -27\cdot
- \sqrt{3}\cdot \nu
- \)
- ^{\frac{2}{
- 3}}\nl
- \OFF{2837617}
- -2\cdot
- \(9\cdot
- \sqrt{4\cdot \mu ^{3}\cdot \nu
- +27\cdot \nu ^{2}}
- -2\cdot
- \sqrt{3}\cdot \mu ^{3}
- -27\cdot
- \sqrt{3}\cdot \nu
- \)
- ^{\frac{1}{
- 3}}\cdot \nl
- \OFF{2837617}
- 2^{\frac{1}{
- 3}}\cdot 3^{\frac{1}{
- 6}}\cdot \mu
- -2^{\frac{2}{
- 3}}\cdot
- \sqrt{3}\cdot 3^{\frac{1}{
- 3}}\cdot i\cdot
- \mu ^{2}
- -2^{\frac{2}{
- 3}}\cdot 3^{\frac{1}{
- 3}}\cdot
- \mu ^{2}
- \)
- /\nl
- \OFF{2509937}
- \(6\cdot
- \(9\cdot
- \sqrt{4\cdot \mu ^{3}\cdot \nu
- +27\cdot \nu ^{2}}
- -2\cdot
- \sqrt{3}\cdot \mu ^{3}
- -27\cdot
- \sqrt{3}\cdot \nu
- \)
- ^{\frac{1}{
- 3}}\cdot 2^{\frac{1}{
- 3}}\cdot 3^{
- \frac{1}{
- 6}}
- \)
- \]
- \,\nl
- \OFF{327680}
- x=
- \[\(\(9\cdot
- \sqrt{4\cdot \mu ^{3}\cdot \nu
- +27\cdot \nu ^{2}}
- -2\cdot
- \sqrt{3}\cdot \mu ^{3}
- -27\cdot
- \sqrt{3}\cdot \nu
- \)
- ^{\frac{2}{
- 3}}\nl
- \OFF{2837617}
- -
- \(9\cdot
- \sqrt{4\cdot \mu ^{3}\cdot \nu
- +27\cdot \nu ^{2}}
- -2\cdot
- \sqrt{3}\cdot \mu ^{3}
- -27\cdot \nl
- \OFF{3675021}
- \sqrt{3}\cdot \nu
- \)
- ^{\frac{1}{
- 3}}\cdot 2^{\frac{1}{
- 3}}\cdot 3^{
- \frac{1}{
- 6}}\cdot \mu
- +2^{\frac{2}{
- 3}}\cdot 3^{\frac{1}{
- 3}}\cdot
- \mu ^{2}
- \)
- /\nl
- \OFF{2509937}
- \(3\cdot
- \(9\cdot
- \sqrt{4\cdot \mu ^{3}\cdot \nu
- +27\cdot \nu ^{2}}
- -2\cdot
- \sqrt{3}\cdot \mu ^{3}
- -27\cdot
- \sqrt{3}\cdot \nu
- \)
- ^{\frac{1}{
- 3}}\cdot 2^{\frac{1}{
- 3}}\cdot 3^{
- \frac{1}{
- 6}}
- \)
- \]
- \}
- \Nl}$$
- \exa Matrix Printing
- \mod TeX
- \tol --
- \cod mat((1,a-b,1/(c-d)),(a*{*}2-b*{*}2,1,sqrt(c)),((a+b)/(c-d),sqrt(d),1));
- \
- $$
- \pmatrix{1&a
- -b&
- \frac{1}{
- c
- -d}\cr
- a^{2}
- -b^{2}&1&
- \sqrt{c}\cr
- \frac{a
- +b}{
- c
- -d}&
- \sqrt{d}&1\cr
- }
- $$
- % ----------------------------------------------------------------------
- \sec Caveats\par
- % ----------------------------------------------------------------------
- Techniques for printing mathematical expressions are available
- everywhere. This TRI adds only a highly specialized version for
- most REDUCE output. The emphasis is on the word \i{most}.
- One major caveat is that we cannot print SYMBOLIC-mode output
- from REDUCE. This could be done best in a WEB-like programming-plus-%
- documentation style. Nevertheless, as Knuth's WEB is already available
- for PASCAL and C, hopefully someone will write a LISP-WEB or a
- REDUCE-WEB as well.\par
- Whenever you discover a bug in our program please let us
- know. Send us a short report accompanied by an output listing.\note{You
- can reach us with e-mail at the following addresses:
- Werner Antweiler: antweil\@epas.utoronto.ca, Andreas Strotmann:
- strotmann@rrz.uni-koeln.de and Volker Winkelmann:
- winkelmann@rrz.uni-koeln.de.} We'll try to fix the error.
- The whole TRI package consists of following files:\par
- \itemize{3cm}
- \litem{\tt tri.tex}This text as a \TeX-input file.\par
- \litem{\tt tri.red}The REDUCE-LISP source code for the TRI.\par
- \litem{\tt tridefs.tex}The \TeX-input file to be used together with
- output from the TRI.\par
- \litem{\tt redwidth.tex}The \TeX-input file for interactive determination
- of \TeX-item widths.\par
- \litem{\tt tritest.red}Run this REDUCE file to check if
- TRI works correctly.\par
- \litem{\tt tritest.tex}When you have run {\tt tritest.red} just make a
- \TeX\ run with this file to see all the nice things TRI is able
- to produce.\par
- \enditemize
- % ----------------------------------------------------------------------
- \sec References\par
- % ----------------------------------------------------------------------
- \aut Antweiler, W.; Strotmann, A.; Pfenning, Th.; Winkelmann, V.
- \ttl Zwischenbericht "uber den Status der Arbeiten am
- REDUCE-\TeX-Anschlu\3
- \pub Internal Paper, Rechenzentrum der Universit"at zu K"oln
- \ref \\
- \dat November 1986
- \inx 1986
- \
- \aut Fateman, Richard J.
- \ttl \TeX\ Output from MACSYMA-like Systems
- \pub ACM SIGSAM Bulletin, Vol. 21, No. 4, Issue \#82
- \ref pp. 1--5
- \dat November 1987
- \inx 1987
- \
- \aut Knuth, Donald E.; Plass, Michael F.
- \ttl Breaking Paragraphs into Lines
- \pub Software---Practice and Experience, Vol. 11
- \ref pp. 1119--1184
- \dat 1981
- \inx 1981
- \
- \aut Knuth, Donald E.
- \ttl The \TeX book
- \pub Addison-Wesley, Readings/Ma.
- \ref \\
- \dat sixth printing, 1986
- \inx 1986
- \
- \aut Hearn, Anthony C.
- \ttl REDUCE User's Manual, Version 3.3
- \pub The RAND Corporation, Santa Monica, Ca.
- \ref \\
- \dat July 1987
- \inx 1987
- \
- \bye
|