%%% %%% File: mfpic.tex %%% % Preliminary version of macros. %%% %%% \immediate\write16 {mfpic version 0.2.10.9 alfa Sat 9 November 1996} %%% %%% Major contributions by Daniel H. Luecking (DHL), %%% 19 June 1995 and 28 Feb 1996. %%% \immediate\write16 {Transforms may now be used among figure modifiers.} \wlog {} %%% %%% \wlog {mfpic: check whether mfpic.tex already loaded} \expandafter\ifx\csname mfpic-package\endcsname\relax % DHL: \else \immediate\write16 {} \immediate\write16 {You have loaded mfpic more than once! Please load it only once!}% \immediate\write16 {} \expandafter \endinput % DHL: \fi \expandafter\xdef\csname mfpic-package\endcsname % DHL: (use load check) {\catcode`\string @=\the\catcode`\@ } % DHL: (to save @'s catcode) %%% %%% % DHL: This lets one keep multiple versions around with minimal changes: \def \grafbasename {grafbase} % DHL: %%% %%% \wlog {mfpic: local catcode change for `at' character} \catcode`@=11 %%% %%% % % Let TeX read mfpic.tex without accidentally introducing % spurious spaces into the DVI file produced from a TeX document % that uses mfpic. % \wlog {mfpic: font changed to nullfont while loading mfpic.tex} % Save old font. \global \font\@tcurr=\fontname\font\relax % Change to null font. \nullfont % %%% %%% % Test for (any release of) LaTeX. \wlog {mfpic: test for LaTeX} \newif\ifin@latex % GT: \UndEfInEd introduced by D.H. Luecking. \ifx \documentstyle\UndEfInEd \in@latexfalse \else \in@latextrue \fi %%% %%% \wlog {mfpic: defining test for previous definitions of macros} % (Cannot use \testdef to pre-test \testdef, without circular definition.) \ifx \testdef\UndEfInEd \else \immediate\write16 {Hey! How can testdef already be defined? I'll define it, anyway!} \fi % % Define the test for whether a macro name is already defined. \def\testdef#1{% \ifx #1\UndEfInEd \else \immediate\write16 {mfpic: BEWARE: \noexpand #1 is already defined!}% \fi} % Warn if macro defined, but `let' it anyway. \testdef\newlet \def\newlet#1=#2{\testdef#1\let#1=#2} % Simple definitions. \newlet\sim@def=\def \newlet\sim@gdef=\gdef % Is the proposed definer of new definitions itself not new? \testdef\newdef % Warn if macro previously defined, but still redefine it. \sim@def\newdef#1{\testdef#1\sim@def#1} \sim@def\newgdef#1{\testdef#1\sim@gdef#1} % Redefine macro. \newlet\redef=\sim@def %%% %%% Handle Optional Parameters in TeX macros: %%% \wlog {mfpic: handlers for optional parameters} \newdef\do@ptparam#1#2% {% \redef\@ptparami[##1]{\csname#1\endcsname[##1]}% \redef\@ptparamii{\csname#1\endcsname[#2]}% \redef\@ptparamiii {% \ifx [\nchr \expandafter\@ptparami \else \expandafter\@ptparamii \fi }% \futurelet\nchr\@ptparamiii }% %%% %%% End of Optional Parameters code. %%% % %%% %%% \wlog {mfpic: direct output to METAFONT file} % {\catcode`\^^M\active % \newgdef\mfpicobeylines{\catcode`\^^M=\active \let^^M=\endgraf}% \global\let^^M=\endgraf% } % % \newdef\preservelines{% \mfpicobeylines \newlinechar=`\^^M} % \newdef\mfsrc#1{% {\immediate\write\@outx{#1}}% \ignorespaces } %%% %%% Percent, Sharp and Backslash signs for METAFONT file: %%% \newdef\mf@gobble#1{} \newdef\mf@p{\expandafter\mf@gobble\string\%} \newdef\mf@s{\expandafter\mf@gobble\string\#} % % Works but conflicts with LaTeX: % \chardef\\=`\\ % \newdef\mf@bsl{\expandafter\mf@gobble\string\\} % % Doesn't work: % \chardef\my@bsl=`\\ % \newdef\mf@bsl{\expandafter\mf@gobble\string\my@bsl} %%% \wlog {mfpic: three local declarations used with graphs files} \newwrite\@outx \newread\@graphx \newcount\@gcode %%% %%% Open and Close METAFONT Graphs file: %%% %%% Use command names: \@gcode, \@outx, \@graphx, \@graphfont. %%% \wlog {mfpic: macros to open and close graphs files} % \newdef\opengraphsfile#1% {% \immediate\write16{}% \@gcode=0 \immediate\openout\@outx=#1.mf \openin\@graphx=#1.tfm \ifeof \@graphx \immediate\write16 {mfpic: No file #1.tfm.}% \font\@graphfont=dummy\relax \else \font\@graphfont=#1\relax \fi \closein\@graphx \immediate\write16 {mfpic: Don't forget to process #1.mf!}% \immediate\write16 {mfpic: (Apply metafont to #1.mf, then gftopk to the #1 gf file.)}% \immediate\write16 {mfpic: Then reprocess this file (\jobname.tex).}% \immediate\write16{}% \mfsrc {if unknown mode: mode:= localfont; fi}% \mfsrc {if unknown mag: mag:=\number\mag/1000; fi}% % DHL: See \def of \grafbasename: \mfsrc {if unknown grafbase: input \grafbasename; fi}% \mfsrc {gcode:=\number\@gcode;}% \mfsrc {}% } \newdef\closegraphsfile {% \mfsrc {}% \mfsrc {end.}% \immediate\closeout\@outx } %%% %%% \wlog {mfpic: using dummy font's dimensions, to spare TeX registers} % TRICK: Use font dimensions to spare TeX's dimension registers. % % Load dummy.tfm : most systems should have this, % but other fonts (such as cmr10) may suffice. % \font\@dummy=dummy \fontdimen100\@dummy=0pt % % Use an auxiliary count register: % \newcount\@fdc % % In the web2c METAFONT 2.71 implementation I use on unix, % each font initially has 22 dimensions. % This number can be increased only by using a higher font % dimension number immediately after the font is loaded. % Most fonts use only font dimensions 1 to 22; start new font % dimensions from number 23 to avoid mangling the font's typesetting. % (For dummy.tfm, this may not matter, as it has no characters.) % \@fdc=23 % % Rough equivalent of \newdimen, only for font dimensions. % Note: \newfdim defines a dimension globally, like \newdimen. % Must define carefully, to use the current font dimension number. % \newdef\newfdim#1{\xdef#1{\fontdimen\the\@fdc\@dummy}% \global \advance\@fdc by 1\relax} % % Now we can use \newfdim like this: % % \newfdim\bdim % \newfdim\cdim % \bdim=3pt % \cdim=\bdim % \show\the\cdim % % Drawback 1: Font dimension assignments seem always to have global % scope. % Drawback 2: Font dimensions cannot directly use \advance, \multiply % or \divide. One must copy to and from a temporary TeX dimension % register. % %%% %%% \wlog {mfpic: a box for whole labeled graph, and a temporary box} \newbox\@wholegraph \newbox\@textbox % \wlog {mfpic: internal dimension parameters for graph dimensions} \newfdim\@graphwd \newfdim\@graphright \newfdim\@graphleft \newfdim\@graphht \newfdim\@graphdp % \wlog {mfpic: user's dimension parameters, with default settings} \newfdim\mfpicunit \mfpicunit=1pt \newfdim\pointsize \pointsize=2pt \newfdim\shadespace \shadespace=1pt \newfdim\hatchspace \hatchspace=3pt \newfdim\headlen \headlen=3pt \newfdim\axisheadlen \axisheadlen=5pt \newfdim\hashlen \hashlen=4pt \newfdim\dashlen \dashlen=4pt \newfdim\dashspace \dashspace=4pt \newfdim\dotsize \dotsize=0.5pt \newfdim\dotspace \dotspace=3pt % % Note: Prof. D.E.~Knuth recommends dimension register 255 be reserved % as a scratch register. % % Advance a font dimension f (#1) by Dimension x (#2) : \newdef\d@adv#1#2{{% \dimen255 = #1\relax \advance\dimen255 by #2\relax \global #1 = \dimen255 }} % Multiply a font dimension f (#1) by Integer n (#2) : \newdef\i@mul#1#2{{% \dimen255 = #1\relax \multiply\dimen255 by #2\relax \global #1 = \dimen255 }} % Divide a font dimension f (#1) by Integer d (#2) : \newdef\i@div#1#2{{% \dimen255 = #1\relax \divide\dimen255 by #2\relax \global #1 = \dimen255 }} % Multiply a font dimension f (#1) by Rational q = n/d (#2 / #3) : \newdef\q@mul#1#2#3{{% \dimen255 = #1\relax \multiply\dimen255 by #2\relax \divide\dimen255 by #3\relax \global #1 = \dimen255 }} %%% %%% \wlog {mfpic: graphics macros} % % Standard shade setting macros: \newdef\darkershade{% \q@mul{\shadespace}{5}{6}% } \newdef\lightershade{% \q@mul{\shadespace}{6}{5}% } % Note: \dashlineset is same as initial setting: \newdef\dashlineset{% \dashlen=4pt \dashspace=4pt} \newdef\dotlineset{% \dashlen=1pt \dashspace=2pt} % User can choose subsequent points to be either filled or open: \newif\ifpointfill \pointfilltrue %%% %%% \wlog {mfpic: tests to control multiple prefix commands} % % Start of a complex drawing command (one that includes prefixes). % Figure macros close by setting it true; % Rendering and other prefix macros close by setting this false. % \newif\if@startfig \@startfigtrue % % Implicit Rendering: % Rendering macros close by setting this false; % Figure macros close by setting it true; % Other prefix macros (eg, \closed and \reverse) do not touch it. % \newif\if@imrend \@imrendtrue % % Storage of a path. \newdef\store@path{% \mfsrc {}% \mfsrc {store (curpath)}% } % % First stage of (rendering and path modification) prefix macros. % \newdef\@firststage {% \if@startfig \store@path \@imrendtrue \@startfigfalse \fi } % % Rendering macro specification. % \newdef\@rendmac#1{% \@firststage \mfsrc {#1}% \@imrendfalse } % % Path modification (eg, path reversal) macro specification. % \newdef\@modmac#1{% \@firststage \mfsrc {#1}% } % % Path closure macro specification. % \newdef\@closmac#1{% \@firststage \if@imrend \@render \fi \mfsrc {#1}% } % % % (Implicitly) Render current figure. % Initial default is to draw solid paths. % \newdef\@render{\draw} % % Redefine (implicit) Render command. % \newdef\setrender#1{\redef\@render{#1}} % % Figure macro specification. % \newdef\@figmac#1{% \@firststage \if@imrend \@render \fi \mfsrc {#1;}% \@startfigtrue \@imrendtrue } % % METAFONT title: \newdef\mftitle#1{\mfsrc {mftitle "#1";}}% % TeX text and METAFONT title: \newdef\tmtitle#1{#1\wlog {#1}\mftitle {#1}}% % % To turn off character shipping for duration of innermost % enclosing group (eg, mfpic environment) : \newdef\noship{% \mfsrc {save shipit; let shipit = relax;}% \advance\@gcode -1 \mfsrc {decr gcode;}} % % Pen size settings for drawing, shading and hatching: % % Drawing pen's width: \newdef\drawpen#1{% \mfsrc {}% \mfsrc {penwd := #1;}% \mfsrc {drawpen := pencircle scaled penwd yscaled aspect_ratio;}} \newlet\pen=\drawpen % % Shading dot's diameter: \newdef\shadewd#1{% \mfsrc {shadewd := ceiling (#1);}% \mfsrc {setdotpath (fullcircle, shadewd);}} % % Hatch line's thickness: \newdef\hatchwd#1{% \mfsrc {hatchwd := #1;}% \mfsrc {hatchpen := pencircle scaled hatchwd yscaled aspect_ratio;}} % % Arrowhead shape setting: \newdef\headshape#1#2#3{\mfsrc {headshape (#1, #2, #3);}} %%% %%% % Define mfpic graphics macros. \newdef\@mfpic@graf@macs {% %% %% The (METAFONT based) drawing macros: %% % Tiling environment: \newdef\tile##1{\mfsrc {tile (##1);}}% \newdef\endtile{\mfsrc {endtile;}}% % % Store all enclosed paths in METAFONT path array ##1. % The grouping is to localise the redefinition of \store@path. % \newdef\patharr##1{% \begingroup \mfsrc {hide (numeric ##1; path ##1[]; ##1 = 0;)}% \redef\store@path{\mfsrc {store (##1[incr ##1])}}}% \newdef\endpatharr{% \redef\store@path{\mfsrc {store (curpath)}}% \endgroup}% % % Prefix commands: % % Store following mfpic path in METAFONT path variable ##1: \newdef\store##1##2{\mfsrc {store (##1)}% \@startfigfalse \@imrendfalse ##2% \@imrendtrue \@startfigtrue}% % Allow METAFONT path ##1 to be shaded, connected, etc: \newdef\mfobj##1{\@figmac {##1}}% % Tesselation (tiling): \newdef\tess##1{\@rendmac {tess (##1)}}% % Shading: \newdef\@shade[##1]{\@rendmac {shade (##1)}}% \newdef\shade{\do@ptparam{@shade}{\the\shadespace}}% % Hatching: \newdef\@thatch[##1,##2]{\@rendmac {thatch (##1, ##2)}}% \newdef\thatch{\do@ptparam{@thatch}{\the\hatchspace, 0 deg}}% % Extra hatch macros, for convenience: \newdef\@lhatch[##1]{\@rendmac {thatch (##1, -45 deg)}}% \newdef\lhatch{\do@ptparam{@lhatch}{\the\hatchspace}}% \newdef\@rhatch[##1]{\@rendmac {thatch (##1, 45 deg)}}% \newdef\rhatch{\do@ptparam{@rhatch}{\the\hatchspace}}% \newdef\@xhatch[##1]{\@rendmac {thatch (##1, 45 deg) thatch (##1, -45 deg)}}% \newdef\xhatch{\do@ptparam{@xhatch}{\the\hatchspace}}% \newlet\hatch=\xhatch % Filling and Erasing: \newdef\gfill {\@rendmac {filled}}% \newdef\gclear{\@rendmac {unfilled}}% % Arrowhead: \newdef\@arrowoption##1##2% {% \ifx ##1l\gdef\@hlength{##2}\else \ifx ##1r\gdef\@hrotate{##2}\else \ifx ##1b\gdef\@hbackset{##2}\fi\fi\fi }% \newdef\@arrowthree[##1##2]% {% \@arrowoption{##1}{##2}% \@modmac {headpath (\@hlength, \@hrotate, \@hbackset)}% }% \newdef\@arrowtwo[##1##2]{% \@arrowoption{##1}{##2}% \do@ptparam{@arrowthree}{WW}}% \newdef\@arrowone[##1##2]% {% \gdef\@hlength{\the\headlen}% \gdef\@hrotate{0 deg}% \gdef\@hbackset{0pt}% \@arrowoption{##1}{##2}% \do@ptparam{@arrowtwo}{ZZ}% }% \newdef\arrow{\do@ptparam{@arrowone}{YY}}% % Solid path: \newdef\draw {\@rendmac {drawn}}% % Dashed path: \newdef\@dashed[##1,##2]{% \@rendmac {dashed (##1,##2)}}% \newdef\dashed{% \do@ptparam{@dashed}% {\the\dashlen,\the\dashspace}}% % Dotted path: \newdef\@dotted[##1,##2]{% \@rendmac {dotted (##1,##2)}}% \newdef\dotted{% \do@ptparam{@dotted}% {\the\dotsize,\the\dotspace}}% % Closed path: \newdef\lclosed{\@closmac {lclosed}}% \newdef\bclosed{\@closmac {bclosed}}% \newdef\sclosed{\@closmac {sclosed}}% \newdef\cbclosed{\@closmac {cbclosed}}% % % Reversing orientation of path: \newdef\reverse {\@modmac {reverse}}% % % Rotating a path: \newdef\rotatepath##1{\@modmac {rotatedpath (##1)}}% % % % Connecting two or more open figures: \newdef\connect{% \@figmac {begingroup}% \patharr {nexus}% }% \newdef\endconnect{% \endpatharr \mfsrc {mkpoly (false, nexus)}% \mfsrc {endgroup}% }% % % % Affine transforms of the METAFONT _coordinate system_ : % Grouping macros that enable nested coordinate systems: \newdef\coords{\mfsrc {}\mfsrc {bcoords}\mfsrc {}}% \newdef\endcoords{\mfsrc {}\mfsrc {ecoords}\mfsrc {}}% % Macro that applies a nominated METAFONT affine transformer: \newdef\applyT##1{\mfsrc {hide (apply_t (##1);)}}% % Specific transform macros for METAFONT coordinates; % See _The METAFONTbook_ for most of these. \newdef\rotate##1{\applyT {rotated ##1}}% degrees. \newdef\rotatearound##1##2{\applyT {rotatedaround (##1, ##2)}}% point, degrees. \newdef\@turn[##1]##2{\rotatearound{##1}{##2}}% point, degrees. \newdef\turn{\do@ptparam{@turn}{(0,0)}}% \newdef\reflectabout##1##2{\applyT {reflectedabout (##1,##2)}}% line ##1 -- ##2. \newlet\mirror=\reflectabout \newdef\shift##1{\applyT {shifted ##1}}% pair. \newdef\scale##1{\applyT {scaled ##1}}% same scaling in X and Y directions. \newdef\xscale##1{\applyT {xscaled ##1}}% scale only X. \newdef\yscale##1{\applyT {yscaled ##1}}% scale only Y. \newdef\zscale##1{\applyT {zscaled ##1}}% complex multiplication of points. \newdef\xslant##1{\applyT {xslant ##1}}% skew in X direction by a multiple of Y coord. \newdef\yslant##1{\applyT {yslant ##1}}% skew in Y direction by a multiple of X coord. \newdef\zslant##1{\applyT {zslant ##1}}% see `grafbase.mf'. \newdef\boost##1{\applyT {boost ##1}}% special relativity boost. \newdef\xyswap{\applyT {xyswap}}% reflect in line Y=X. % % End of Prefix commands. % % Axes and axis Marks: \newdef\@axes[##1]{% \mfsrc {axes (##1);}}% \newdef\axes{\do@ptparam{@axes}{\the\axisheadlen}}% \newdef\@xmarks[##1]##2{% \mfsrc {xmarks (##1,##2);}}% \newdef\xmarks{\do@ptparam{@xmarks}{\the\hashlen}}% \newdef\@ymarks[##1]##2{% \mfsrc {ymarks (##1,##2);}}% \newdef\ymarks{\do@ptparam{@ymarks}{\the\hashlen}}% % Points (filled disks of a given size) : \newdef\grid##1{% \mfsrc {grid (##1);}}% \newdef\@point[##1]##2{% \mfsrc {}% \mfsrc {pointd (##1, \ifpointfill true\else false\fi) (##2);}}% \newdef\point{\do@ptparam{@point}{\the\pointsize}}% % Polyline (open) : \newdef\polyline##1{% \@figmac {polyline (false) (##1)}}% \newlet\lines=\polyline % Polygon (closed) : \newdef\polygon##1{% \@figmac {polyline (true) (##1)}}% % Upright rectangle: \newdef\rect##1{% \@figmac {rect (##1)}}% % Curve (open) : \newdef\curve##1{% \@figmac {curve (false) (##1)}}% % Cyclic curve (closed) : \newdef\cyclic##1{% % BEGIN TEST: % \message {CYCLIC argument = ``##1''}% % END TEST. \@figmac {curve (true) (##1)}}% % Open Quadratic B-splines \newdef\qspline##1{% \@figmac {openqbs (##1)}}% % Closed Quadratic B-splines \newdef\closedqspline##1{% \@figmac {closedqbs (##1)}}% % Open Cubic B-splines \newdef\cspline##1{% \@figmac {opencbs (##1)}}% % Closed Cubic B-splines \newdef\closedcspline##1{% \@figmac {closedcbs (##1)}}% % Circle and Ellipse: \newdef\circle##1{\@figmac {circle (##1)}}% \newdef\@ellipse[##1]##2{% \@figmac {ellipse (##2, ##1)}}% \newdef\ellipse{\do@ptparam{@ellipse}{0 deg}}% % Circular Arc: \newdef\@arc[##1]##2{% \if ##1s\@figmac {arcpps (##2)}\else \if ##1p\@figmac {arcplr (##2)}\else \if ##1c\@figmac {arccps (##2)}\else \@figmac {arcppp (##2)}\fi\fi\fi}% \newdef\arc{\do@ptparam{@arc}{s}}% % Polar coordinates: \newdef\plr##1{map (polar) (##1)}% % `Turtle graphics': \newdef\turtle##1{% \@figmac {turtle (##1)}}% % Sector of a circular region: \newdef\sector##1{% \@figmac {sector (##1)}}% % Function Plots: \newdef\@function[##1]##2##3{% \@figmac {function (% \if ##1s true\else false\fi) (##2) (##3)}}% \newdef\function{\do@ptparam{@function}{s}}% \newdef\@parafcn[##1]##2##3{% \@figmac {parafcn (% \if ##1s true\else false\fi) (##2) (##3)}}% \newdef\parafcn{\do@ptparam{@parafcn}{s}}% \newdef\@plrfcn[##1]##2##3{% \@figmac {plrfcn (% \if ##1s true\else false\fi) (##2) (##3)}}% \newdef\plrfcn{\do@ptparam{@plrfcn}{s}}% \newdef\@btwnfcn[##1]##2##3##4{% \@figmac {((function ( \if ##1s true\else false\fi) (##2) (##3)) --(reverse function ( \if ##1s true\else false\fi) (##2) (##4)) --cycle)}}% \newdef\btwnfcn{\do@ptparam{@btwnfcn}{p}}% \newdef\@plrregion[##1]##2##3{% \@figmac {(plrfcn (\if ##1s true\else false\fi) (##2) (##3) --(0,0)--cycle)}}% \newdef\plrregion{\do@ptparam{@plrregion}{p}}% %% %% End of the (METAFONT based) drawing macros. %% }% %%% %%% End of \@mfpic@graf@macs Definition. %%% % %%% %%% Beginning mfpic environment: %%% \newdef\@mfpic#1#2#3#4#5#6% {% %%% %%% % Set up TeX % Must enter horizontal mode for LaTeX center environment to work. % \leavevmode \begingroup % Change to null font for duration of mfpic environment. % Advantage: Prevents errant spaces from spoiling the typesetting % of the graph. % Disadvantage: Also disallows typesetting of normal text, % unless one restricts that text to confined environments % such as those of mfpic's captions and labels. \nullfont % Plain TeX setting for paragraph's `finishing glue' (TeXbook, p 100). \parfillskip0pt plus1fil\relax % Define mfpic graphics macros. \@mfpic@graf@macs % Local conversion of a dimension control sequence ##1 : % (TeX won't \advance a font dimension, % so use dimen255 as local temporary.) \newdef\@xconv##1% {% {% \dimen255 = ##1\relax \advance\dimen255 by -#3\mfpicunit \dimen255 = #1\dimen255 \global ##1 = \dimen255 }% }% \newdef\@yconv##1% {% {% \dimen255=##1\relax \advance\dimen255 by -#5\mfpicunit \dimen255 = -#2\dimen255 \global ##1 = \dimen255 }% }% % Set up Graph Box: \global \advance\@gcode1 \@graphright=#4\mfpicunit \@xconv\@graphright \@graphht=#6\mfpicunit \@yconv\@graphht \@graphleft=0pt \@xconv\@graphleft \@graphdp=0pt \@yconv\@graphdp \global \@graphwd=\@graphright % % %%% Only Here Is \@graphfont Used. %%% % If the graphics font is undefined (ie, if user has forgotten to % open a graphs file) then COMPLAIN! {% \chardef\\=`\\% \newdef\mf@bsl{\expandafter\mf@gobble\string\\}% \ifx \@graphfont\UndEfInEd \immediate\write16 {} \immediate\write16 {mfpic: You must open a graphs file, using \mf@bsl opengraphsfile}% \immediate\write16 {mfpic: (and match that with a \mf@bsl closegraphsfile),}% \immediate\write16 {mfpic: otherwise this happens:}% \fi }% % Typeset METAFONT picture. \global \setbox\@wholegraph= \vtop to \@graphht % NOTE: was \vtop then \vbox. {% \hbox to \@graphwd {\noindent\@graphfont\char\@gcode\hss}% End hbox. \vss }% End vtop. % Set up METAFONT file: \mfsrc {}% \mfsrc {unitlen:=\the\mfpicunit\mf@s;}% \mfsrc {xscale:=#1; yscale:=#2;}% \mfsrc {xneg:=#3; xpos:=#4;}% \mfsrc {yneg:=#5; ypos:=#6;}% \mfsrc {beginmfpic (incr gcode);}% % % (TeX based) labels and caption: % % Label: % % Arg 1 literals: t c b % Arg 2 literals: t c r % Arg 3 meaning: x position. % Arg 4 meaning: y position. % Arg 5 meaning: label's text; must be horizontal material. % \newdef\@tlabel[##1##2](##3,##4)##5{% % Compute width of graph with label (arg 5), % and reset size if necessary: % \setbox\@textbox= \vbox{% DHL: \def\\{\egroup\hbox\bgroup\ignorespaces}% DHL: \hbox\bgroup\@tcurr ##5\egroup % End hbox. }% DHL: % \dimendef\@labeldim=255 % scratch register % % Stretch Graph Rightward: % \@labeldim=##3\mfpicunit \@xconv\@labeldim \if ##2l\advance\@labeldim by \wd\@textbox \else \if ##2c\advance\@labeldim by 0.5\wd\@textbox \fi\fi \ifdim \@labeldim>\@graphright \global \@graphright=\@labeldim \fi % % Stretch Graph Leftward: % \@labeldim=##3\mfpicunit \@xconv\@labeldim \if ##2r\advance\@labeldim by -\wd\@textbox \else \if ##2c\advance\@labeldim by -0.5\wd\@textbox \fi\fi \ifdim \@labeldim<\@graphleft \global \@graphleft=\@labeldim \fi % % Stretch Graph Upward: % \@labeldim=##4\mfpicunit \@yconv\@labeldim \if ##1b\advance\@labeldim by \ht\@textbox \else \if ##1c\advance\@labeldim by 0.5\ht\@textbox \fi\fi \ifdim \@labeldim>\@graphht \global \@graphht=\@labeldim \fi % % Stretch Graph Downward: % \@labeldim=##4\mfpicunit \@yconv\@labeldim \if ##1t\advance\@labeldim by -\dp\@textbox \else \if ##1c\advance\@labeldim by -0.5\dp\@textbox \fi\fi \ifdim \@labeldim<\@graphdp \global \@graphdp=\@labeldim \fi % % Set label onto graph: % \global \setbox\@wholegraph = \vtop{\unvbox\@wholegraph % NOTE: was \vtop then \vbox. \vbox to0pt{% \if ##1c\kern-0.5\ht\@textbox \else \if ##1b\kern-\ht\@textbox \fi\fi \@labeldim=##4\mfpicunit \@yconv\@labeldim \kern\@labeldim \hbox{% \@labeldim=##3\mfpicunit \@xconv\@labeldim \kern\@labeldim \if ##2c\kern-0.5\wd\@textbox \else \if ##2r\kern-\wd\@textbox \fi\fi \box\@textbox }% End hbox. \vss}% End vbox. \nointerlineskip}% End vtop. \ignorespaces }% -- End \@tlabel % % \tlabel[tr](x,y){text} : % \newdef\tlabel{\do@ptparam{@tlabel}{bl}}% % % Caption: % % \@docaption (called by \endmfpic) : \newdef\@docaption{\global \@graphleft=0pt \@xconv\@graphleft \relax}% % \newdef\@docaption{}% % % Arg 1 meaning: maxwd; see mfpicdoc.tex. % Arg 2 meaning: linewd; see mfpicdoc.tex. % Arg 3 meaning: caption's text. % \newdef\@tcaption[##1,##2]##3% {% % Redefine \@docaption to Set Caption: \redef\@docaption {% % Compute Adjustments to Center: % 1. Measure caption text. % GT: What if the caption's not horizontal material?) % GT: A long caption doesn't wrap inside an hbox! % \setbox\@textbox =% \hbox \bgroup \@tcurr \def\\{\hskip\@m pt\relax}% DHL: \\ forces width test to "true". ##3% \egroup % End hbox. % 2. If caption text is so much wider than graph, then % stretch graph box horizontally. \ifdim \wd\@textbox>##1\@graphwd % % \ifdim \wd\@textbox>\@graphwd % \@graphwd=\wd\@textbox % \@graphwd=##2\@graphwd \setbox\@textbox = \hbox \bgroup % \tolerance=500\relax % \hfuzz=100pt\relax \vbox{% % Prevent \leftskip and \rightskip from interfering with % caption: \leftskip=0pt \rightskip=0pt % 3. Here's where the graph box's width is adjusted. % \hsize=##2\@graphwd % \hsize=\@graphwd % % 4. Contribute the caption text, % in a nonindented paragraph below the graph. \def\\{\hfil\break\ignorespaces}% DHL: \noindent \@tcurr \unhbox\@textbox \relax }% End vbox. \egroup % End hbox. \fi \dimendef\@centerskip=255 % Scratch Register \@centerskip=\@graphwd \advance\@centerskip -\wd\@textbox \divide\@centerskip by 2 % Set Caption onto Picture: \global \setbox\@wholegraph = \vbox{% % Check whether Caption's Wider than Graph: \ifdim \@centerskip<0pt \global \@graphleft = -\@centerskip \moveright -\@centerskip \fi \vbox \bgroup \unvbox\@wholegraph \medskip \hbox {% \noindent \kern\@centerskip \box\@textbox }% End hbox. \egroup % End vbox. % \vss }% End vbox. }% -- End \@docaption. \ignorespaces }% -- End \@tcaption. % % \tcaption[maxwd,linewd]{text} : % \newdef\tcaption{\do@ptparam{@tcaption}{1.2, 1.0}}% % % End of Object Macros. % Skip spaces in TeX document after \mfpic command. \ignorespaces % Retain line separations when writing METAFONT file. % ALAS! \obeylines causes LaTeX center to write \@@par to MF file, % for each line break in \mfsrc calls. \preservelines }% %%% %% End of \@mfpic Definition. %%% %%% % Setting up optional arguments for \mfpic: \newdef\@pici[#1]#2#3#4#5{\@mfpic{\@param}{#1}{#2}{#3}{#4}{#5}} %%% %%% Definition of \mfpic Command. %%% \wlog {mfpic: definition of mfpic command} % % \mfpic[xscale][yscale]{xneg}{xpos}{yneg}{ypos} % % One of xscale, yscale must be present; % if only one is present, then xscale = yscale. % \newdef\mfpic[#1]{% \hbox{}% \redef\@param{#1}% \do@ptparam{@pici}{#1}} %%% %%% End of \mfpic Definition. %%% %%% %%% Definition of Closure of mfpic Environment: %%% \wlog {mfpic: definition of closure of mfpic environment} \newdef\endmfpic {% \wlog {}% \wlog {mfpic: ENTERED endmfpic.}% \wlog {}% \global \@graphwd=\@graphright % \d@adv{\@graphwd}{-\@graphleft}% % \wlog {mfpic: graphleft = \the\@graphleft}% \wlog {mfpic: graphright = \the\@graphright}% \wlog {mfpic: graphwd = \the\@graphwd}% \wlog {}% % % \@docaption \global \setbox\@wholegraph = \vbox {% \hbox to \@graphwd {% % \kern-\@graphleft \box\@wholegraph \hss }% End hbox. % \vss }% End vbox. % \@docaption % \mfsrc {}% \mfsrc {endmfpic;}% \mfsrc {}% % \wlog {mfpic: graphleft = \the\@graphleft}% \wlog {mfpic: graphright = \the\@graphright}% \wlog {mfpic: graphwd = \the\@graphwd}% \wlog {}% \wlog {mfpic: DONE endmfpic.}% \wlog {}% % % % Typesetting the graph, including labels and caption. % % DHL: \s@vemfpic is only defined if \savepic{\foo} was issued since % DHL: the last \endmfpic (UndEfInEd is presumably always UndEfInEd) \ifx\s@vemfpic\UndEfInEd % DHL: % \leavevmode % DHL: moved from start of \mfpic \box\@wholegraph \else % DHL: % DHL: ... in which case \s@vemfpic expands to \b\foo \global\setbox\s@vemfpic=\box\@wholegraph \fi % DHL: % \endgroup \global\let\s@vemfpic\UndEfInEd % DHL: previous line requires a new "\savepic\bar" % DHL: to save the next pic in box \b\bar \ignorespaces }% %%% %%% End of \endmfpic Definition. %%% % % DHL: \onelevel\mumble expands \mumble one level in an \edef: \newdef\onelevel#1{\expandafter\noexpand#1} % DHL: % % DHL: \savepic{\foo} allocates a box \b\foo % DHL: (the second \ is part of the name) % DHL: and defines \foo to expand to \box\b\foo \newdef\savepic#1{% DHL: % DHL: makes \s@vemfpic expand to \b\foo (which is one token!) : \xdef\s@vemfpic{\onelevel\csname b\string#1\endcsname}% DHL: % DHL: allocate the box \csname newbox\expandafter\endcsname\s@vemfpic % DHL: % DHL: defines \foo to place the box \xdef#1{\box\s@vemfpic}% DHL: } % DHL: % % DHL: \copypic\foo --> \copy\b\foo \newdef\copypic#1{% \leavevmode % DHL: \leavevmode moved from start of \mfpic \copy\csname b\string#1\endcsname} % DHL: %%% %%% % % Restore current Font after reading mfpic.tex file. % \@tcurr % %%% %%% % DHL use the loading check to restore \catcode (of @) \csname mfpic-package\endcsname % DHL: \wlog {mfpic: `@' character has reverted to old catcode} % \endinput % DHL: %%% %%% EOF mfpic.tex %%%