%%% %%% File: mfpic.tex %%% Version: 0.25 %%% %%% Principal Author: Thomas Leathrum %%% Assistants: Bryan Green, Geoffrey Tobin %%% % preliminary version of macros % save catcode, as Michael Downes of AMS recommends. \chardef\oldatcatcode=\catcode`@ \catcode`@=11 % letter \def\@wout{\immediate\write16\relax} \@wout {} \@wout {mfpic version 0.25 - 19:20 GMT +10:00 Wed 13 Oct 93} \@wout {fixes for TFM, LaTeX (picture), fractions, catcode, sharp.} \@wout {tests for bad label options, mf char codes out of range (0 - 255).} \@wout {localised short-range declarations.} \@wout {} % test whether mfpic is used in LaTeX. \newif\if@inlatex % idea from _The TeXbook_ (1986), p. 384: % \@mfundefined must remain undefined. \ifx\picture\@mfundefined \@inlatexfalse \@wout {MFPIC: not in latex} \else \@inlatextrue \@wout {MFPIC: in latex} \fi \@wout {} % local declarations \wlog {MFPIC: local declarations} \newwrite\@outx \newbox\@labeledgraph \newdimen\@graphwd \newcount\@code % dimension parameters \wlog {} \wlog {MFPIC: dimension parameters} \newdimen\mfpicunit \newdimen\pointsize \newdimen\shadespace \newdimen\headlen \newdimen\axisheadlen \newdimen\hashlen \newdimen\dashlen \newdimen\dashspace % default dimension settings \mfpicunit=1pt \pointsize=2pt \shadespace=1pt \headlen=3pt \axisheadlen=5pt \hashlen=4pt \dashlen=4pt \dashspace=4pt % standard setting macros \def\darkershade{% \multiply\shadespace by 5 \divide\shadespace by 6} \def\lightershade{% \multiply\shadespace by 6 \divide\shadespace by 5} \def\dashlineset{% \dashlen=4pt \dashspace=4pt} \def\dotlineset{% \dashlen=1pt \dashspace=2pt} % direct output to Metafont file % only valid b/w \open- and \close- graphsfile. \def\mfcmd#1{% \immediate\write\@outx{#1}} % pen size setting \def\@pickup{% \mfcmd{pickup pencircle scaled penwd;}} \def\pen#1{% \mfcmd{interim penwd:=#1;} \@pickup} % arrowhead shape setting \def\headshape#1#2{% \mfcmd{interim hdwdr:=#1; interim hdten:=#2;}} % open and close file \def\opengraphsfile#1% {% \@code33 % first graphic is `!' \immediate\openout\@outx=#1.mf \batchmode \font\@graph=#1 \errorstopmode \immediate\write16 {} \ifx\@graph\nullfont \font\@graph=dummy \immediate\write16 {MFPIC: ** Graphic's TFM file #1.tfm not found. **} \immediate\write16 {MFPIC: ** Process #1.mf! Then reprocess this file. **} \immediate\write16 {MFPIC: `Missing character' messages will log the graphic characters.} \else \immediate\write16 {MFPIC: Graphic's TFM file found.} \immediate\write16 {MFPIC: Nevertheless, if PK font's changed, reprocess #1.mf.} \immediate\write16 {MFPIC: If TFM's changed, reprocess #1.mf, and then this TeX file.} \fi \immediate\write16 {} \mfcmd{mag:=\number\mag/1000;} \mfcmd{input graphbase.mf;} % set global defaults \mfcmd{mfpicenv;} \headshape{1}{1} \pen{0.5 pt}% }% -- end \opengraphsfile \def\closegraphsfile {% \mfcmd{} \mfcmd{endmfpicenv;} \mfcmd{end.} \immediate\closeout\@outx }% -- end \closegraphsfile % a useful macro not in plain TeX. \def\mf@gobble#1{} % for output of # (c/o Donald Arseneau). \def\mf@s{\expandafter\mf@gobble\string\#} % beginning mfpicture environment \def\@mfpicture#1#2#3#4#5#6{% % dimension conversion: ##1 is a dimen. \def\@xconv##1{% \global\advance ##1 by -#3 \mfpicunit \global ##1 = #1 ##1} \def\@yconv##1{% \global\advance ##1 by -#5 \mfpicunit \global ##1 = -#2 ##1} % set up TeX \global\font\@tcurr=\fontname\font \relax \bgroup \nullfont \global\@graphwd = #4 \mfpicunit \@xconv\@graphwd \global\setbox\@labeledgraph=\vtop {\hbox{\@graph\char\@code}} % set up Metafont file \mfcmd{} \mfcmd{unitlen:=\the\mfpicunit\mf@s;} \mfcmd{xscale:=#1*unitlen; yscale:=#2*unitlen; xneg:=#3; xpos:=#4; yneg:=#5; ypos:=#6;} \mfcmd{beginchar (\the\@code, (xpos-xneg)*xscale, (ypos-yneg)*yscale, 0);} \mfcmd{setztr;} \@pickup % metafont drawing macros % points, lines, and arrows \def\point##1{% \mfcmd{pointd(##1, \the\pointsize);}} \def\line##1{% \mfcmd{line(##1);}} \def\arrow##1{% \mfcmd{arrow(##1, \the\headlen);}} \def\dottedline##1{% \mfcmd{dottedline(##1, \the\dashlen, \the\dashspace);}} \def\dottedarrow##1{% \mfcmd{dottedarrow(##1, \the\dashlen, \the\dashspace, \the\headlen);}} % axes and axis marks \def\axes {\mfcmd{axes(\the\axisheadlen);}} \def\xmarks##1{% \mfcmd{xmarks(\the\hashlen, ##1);}} \def\ymarks##1{% \mfcmd{ymarks(\the\hashlen, ##1);}} % polygons \def\rect##1{% \mfcmd{rect(##1);}} \def\dottedrect##1{% \mfcmd{dottedrect(##1, \the\dashlen, \the\dashspace);}} \def\block##1{% \mfcmd{block(##1);}} \def\rectshade##1{% \mfcmd{rectshade(\the\shadespace, ##1);}} \def\polygon##1{% \mfcmd{curve(false, true, ##1);}} \def\polyshade##1{% \mfcmd{cycleshade(\the\shadespace, false, ##1);}} \def\polyfill##1{% \mfcmd{cycleshade(0, false, ##1);}} % circles and ellipses \def\circle##1{% \mfcmd{circle(##1);}} \def\ellipse##1{% \mfcmd{ellipse(##1, 0);}} \def\rotatedellipse##1{% \mfcmd{ellipse(##1);}} \def\circshade##1{% \mfcmd{circshade(\the\shadespace, ##1);}} \def\ellshade##1{% \mfcmd{ellshade(\the\shadespace, ##1, 0);}} \def\rotatedellshade##1{% \mfcmd{ellshade(\the\shadespace, ##1);}} \def\cdisk##1{% \mfcmd{circshade(0, ##1);}} \def\edisk##1{% \mfcmd{ellshade(0, ##1, 0);}} \def\rotatededisk##1{% \mfcmd{ellshade(0, ##1);}} % circular arcs \def\arc##1{% \mfcmd{arc(##1);}} \def\arcarrow##1{% \mfcmd{arcarrow(\the\headlen, ##1);}} \def\arcshade##1{% \mfcmd{arcshade(\the\shadespace, ##1);}} \def\arcfill##1{% \mfcmd{arcshade(0, ##1);}} % polar coordinates \def\linedir##1{% \mfcmd{linedir(##1);}} \def\arrowdir##1{% \mfcmd{arrowdir(\the\headlen, ##1);}} \def\arcth##1{% \mfcmd{arcth(##1);}} \def\arctharrow##1{% \mfcmd{arctharrow(\the\headlen, ##1);}} \def\wedgeshade##1{% \mfcmd{wedgeshade(\the\shadespace, ##1);}} \def\wedgefill##1{% \mfcmd{wedgeshade(0, ##1);}} % curves \def\curve##1{% \mfcmd{curve(true, false, ##1);}} \def\polyline##1{% \mfcmd{curve(false, false, ##1);}} \let\polycurve=\polyline \def\curvedarrow##1{% \mfcmd{curvedarrow(true, \the\headlen, ##1);}} \def\polyarrow##1{% \mfcmd{curvedarrow(false, \the\headlen, ##1);}} % cyclic curves \def\cyclic##1{% \mfcmd{curve(true, true, ##1);}} \def\cycleshade##1{% \mfcmd{cycleshade(\the\shadespace, true, ##1);}} \def\cyclefill##1{% \mfcmd{cycleshade(0, true, ##1);}} % functions \def\function##1{% \mfcmd{function(true, ##1);}} \def\polyfunction##1{% \mfcmd{function(false, ##1);}} \def\parafcn##1{% \mfcmd{parafcn(true, ##1);}} \def\polyparafcn##1{% \mfcmd{parafcn(false, ##1);}} \def\shadefcn##1##2##3{% \mfcmd{shadefcn(\the\shadespace, ##1) (##2) (##3);}} % labels \def\@mflabel[##1##2]##3##4##5{% % compute width of graph with label % and reset size if necessary {% local env. for \@btemp. \chardef\@btemp=255\relax \setbox\@btemp=\hbox{\@tcurr##5} {% local env. for \@xtemp. \dimendef\@xtemp=0\relax \@xtemp = ##3 \mfpicunit \@xconv\@xtemp \advance\@xtemp by\wd\@btemp \ifdim\@xtemp>\@graphwd \global\@graphwd=\@xtemp\fi }% end local env. % set label onto picture \global\setbox\@labeledgraph= \vtop{\unvbox\@labeledgraph \vbox to 0 pt{% \if##1t\relax\else \if##1c\kern-0.5\ht\@btemp\else \if##1b\kern-\ht\@btemp\else \immediate\write16 {} \immediate\write16 {MFPIC: label: vertical option `##1' unknown, will treat as `b'} \immediate\write16 {} \kern-\ht\@btemp \fi\fi\fi {% local env. for \@ytemp. \dimendef\@ytemp=0\relax \@ytemp = ##4 \mfpicunit \@yconv\@ytemp \kern\@ytemp }% end local env. \hbox{% \if##2l\relax\else \if##2c\kern-0.5\wd\@btemp\else \if##2r\kern-\wd\@btemp\else \immediate\write16 {} \immediate\write16 {MFPIC: label: horizontal option `##2' unknown, will treat as `l'} \immediate\write16 {} \fi\fi\fi {% local env. for \@xtemp. \dimendef\@xtemp=0\relax \@xtemp = ##3 \mfpicunit \@xconv\@xtemp \kern\@xtemp }% end local env. \box\@btemp}% -- end \hbox \vss}% -- end \vbox \nointerlineskip}% -- end \vtop }% end local env. }% -- end \@mflabel \def\@labeldefault{\@mflabel[bl]} \def\@dolabel{% \if[\@nchr\expandafter\@mflabel \else\expandafter\@labeldefault\fi} \def\mflabel{\futurelet\@nchr\@dolabel} % captions % \@docaption is called by \endmfpicture \def\@docaption{} \def\mfcaption##1{% % redefine to set caption \def\@docaption{% % allow forced line breaks \def\\{% \global\font\@curr=\fontname\font \relax\egroup \hbox\bgroup\@curr} % compute adjustments to center \chardef\@btemp=255\relax \setbox\@btemp=\vbox {\hbox{\@tcurr##1}} \ifdim\wd\@btemp>\@graphwd \global\@graphwd=\wd\@btemp\fi % set caption onto picture \global\setbox\@labeledgraph=\vbox {\unvbox\@labeledgraph \medskip\hbox {\noindent \dimendef\@centerskip=0\relax \@centerskip=\@graphwd \advance\@centerskip -\wd\@btemp \divide\@centerskip by 2\relax \kern\@centerskip \box\@btemp }% -- end \hbox \vss }% -- end \vbox }% -- end \@docaption }% -- end \mfcaption % backward compatibility: \let\label=\mflabel \let\caption=\mfcaption % end of object macros }% -- end \@mfpicture % setting up optional arguments \def\@piciii#1#2#3#4{% \@mfpicture{\@param}{\@param}% {#1}{#2}{#3}{#4}} \def\@picii[#1]#2#3#4#5{% \@mfpicture{\@param}{#1}% {#2}{#3}{#4}{#5}} \def\@pici{% \if[\@nchr\expandafter\@picii \else\expandafter\@piciii\fi} \def\mfpicture [#1]{% {% local env. for \@outrange. \def\@outrange {% \immediate\write16 {} \immediate\write16 {MFPIC: ** Sorry, mfpic makes characters between 0 and 255, inclusive;} \immediate\write16 {MFPIC: ** if you want more, then I suggest you start another graphics font;} \immediate\write16 {MFPIC: * in the meantime mfpic will use the dummy font for new graphics.} \immediate\write16 {} \font\@graph=dummy\relax }% -- end \@outrange \ifx \@code < 0 \@outrange \else \ifx \@code > 255 \@outrange \fi\fi }% end local env. \def\@param{#1}% \futurelet\@nchr\@pici }% -- end \mfpicture % ending mfpicture environment: \def\endmfpicture{% \mfcmd{endchar;} \@docaption\egroup \hbox to\@graphwd{% \box\@labeledgraph\hss} \global\advance\@code1 }% -- end \endmfpicture % % Abbreviations: \let\mfpic=\mfpicture \let\endmfpic=\endmfpicture % \if@inlatex \relax \else % NOT in LaTeX. % backward compatibility: \let\picture=\mfpicture \let\endpicture=\endmfpicture \fi % restore catcode. \catcode`@=\oldatcatcode % % end mfpic.tex