123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515 |
- module fmprint; % Fancy output package for symbolic expressions.
- % using TEX as intermediate language.
-
- % Author: Herbert Melenk, using ideas of maprin.red (A.C.H, A.C.N).
-
- % Modifications:
- % fancy!-mode!* commented out, since it applies only to
- % very old versions. /
- % Copyright (c) 2003 Anthony C. Hearn, Konrad-Zuse-Zentrum.
- % All rights reserved.
- % 8-Sep-94
- % introduced data driven formatting (print-format)
- % 12-Apr-94
- % removed print function for dfp
- % removed some unused local variables
- % corrected output for conditional expressions and
- % aeval/aeval* forms
- % 17_Mar-94 corrected line breaks in Taylor expressions
- % rational exponents use /
- % vertical bar for SUB expressions
- % explicit * for product of two quotients (Taylor)
- % switches
- %
- % ON FANCY enable algebraic output processing by this module
- %
- % ON FANCY_TEX under ON FANCY: display TEX equivalent
- %
- % properties used in this module:
- %
- % fancy-prifn print function for an operator
- %
- % fancy-pprifn print function for an oeprator including current
- % operator precedence for infix printing
- %
- % fancy!-flatprifn print function for objects which require
- % special printing if prefix operator form
- % would have been used, e.g. matrix, list
- %
- % fancy-prtch string for infix printing of an operator
- %
- % fancy-special-symbol
- % print expression for a non-indexed item
- % string with TEX expression "\alpha"
- % or
- % number referring ASCII symbol code
- %
- % fancy-infix-symbol special-symbol for infix operators
- %
- % fancy-prefix-symbol special symbol for prefix operators
- %
- % fancy!-symbol!-length the number of horizontal units needed for
- % the symbol. A standard character has 2 units.
- % 94-Jan-26 - Output for Taylor series repaired.
- % 94-Jan-17 - printing of index for Bessel function repaired.
- % - New functions for local encapsulation of printing
- % independent of smacro fancy!-level.
- % - Allow printing of upper case symbols locally
- % controlled by *fancy-lower
- % 93-Dec-22 Vectors printed with sqare brackets.
- create!-package('(fmprint),nil);
- fluid '(
- !*list
- !*nat
- !*nosplit
- !*ratpri
- !*revpri
- overflowed!*
- p!*!*
- testing!-width!*
- tablevel!*
- sumlevel!*
- outputhandler!*
- outputhandler!-stack!*
- posn!*
- obrkp!* % outside-brackets-p
- );
- global '(!*eraise charassoc!* initl!* nat!*!* spare!* ofl!*);
- switch list,ratpri,revpri,nosplit;
- % Global variables initialized in this section.
- fluid '(
- fancy!-switch!-on!*
- fancy!-switch!-off!*
- !*fancy!-mode
- fancy!-pos!*
- fancy!-line!*
- fancy!-page!*
- fancy!-bstack!*
- !*fancy_tex
- !*fancy!-lower % control of conversion to lower case
- % fancy!-mode!*
- );
- switch fancy_tex; % output TEX equivalent.
- % fancy!-mode!* := if '!6 = car reverse explode2 getenv "reduce" then 36
- % else 35;
- % fancy!-mode!* := 36; % This needs to be more than 35.
- fancy!-switch!-on!* := int2id 16$
- fancy!-switch!-off!* := int2id 17$
- !*fancy!-lower := t;
- global '(fancy_lower_digits fancy_print_df);
- share fancy_lower_digits; % T, NIL or ALL.
- if null fancy_lower_digits then fancy_lower_digits:=t;
- share fancy_print_df; % PARTIAL, TOTAL, INDEXED.
- if null fancy_print_df then fancy_print_df := 'partial;
- switch fancy;
- put('fancy,'simpfg,
- '((t (fmp!-switch t))
- (nil (fmp!-switch nil)) ));
- symbolic procedure fmp!-switch mode;
- if mode then
- <<if outputhandler!* neq 'fancy!-output then
- <<outputhandler!-stack!* :=
- outputhandler!* . outputhandler!-stack!*;
- outputhandler!* := 'fancy!-output;
- >>
- >>
- else
- <<if outputhandler!* = 'fancy!-output then
- <<outputhandler!* := car outputhandler!-stack!*;
- outputhandler!-stack!* := cdr outputhandler!-stack!*;
- >> else
- rederr "FANCY is not current output handler"
- >>;
- symbolic procedure fancy!-out!-header();
- if not !*fancy_tex then prin2 fancy!-switch!-on!*;
- symbolic procedure fancy!-out!-trailer();
- <<if not !*fancy_tex then prin2 fancy!-switch!-off!*;
- terpri()>>;
- symbolic procedure fancy!-tex s;
- % test output: print tex string.
- <<prin2 fancy!-switch!-on!*;
- for each x in explode2 s do prin2 x;
- prin2t fancy!-switch!-off!*;
- >>;
- symbolic procedure fancy!-out!-item(it);
- if atom it then prin2 it else
- if eqcar(it,'ascii) then writechar(cadr it) else
- if eqcar(it,'tab) then
- for i:=1:cdr it do prin2 "\>"
- else
- if eqcar(it,'bkt) then
- begin scalar m,b,l; integer n;
- m:=cadr it; b:=caddr it; n:=cadddr it;
- l := b member '( !( !{ );
- % if m then prin2 if l then "\left" else "\right"
- % else
- if n> 0 then
- <<prin2 if n=1 then "\big" else if n=2 then "\Big" else
- if n=3 then "\bigg" else "\Bigg";
- prin2 if l then "l" else "r";
- >>;
- if b member '(!{ !}) then prin2 "\";
- prin2 b;
- end
- else
- rederr "unknown print item";
- symbolic procedure set!-fancymode bool;
- if bool neq !*fancy!-mode then
- <<!*fancy!-mode:=bool;
- fancy!-pos!*:=0;
- fancy!-page!*:=nil;
- fancy!-line!*:=nil;
- overflowed!* := nil;
- % new: with tab
- fancy!-line!*:= '((tab . 1));
- fancy!-pos!* := 10;
- sumlevel!* := tablevel!* := 1;
- >>;
- symbolic procedure fancy!-output(mode,l);
- % Interface routine.
- if ofl!* or posn!*>2 or not !*nat then
- % not terminal handler or current output line non-empty.
- <<if mode = 'maprin then maprin l
- else
- terpri!*(l)
- >> where outputhandler!* = nil
- else
- <<set!-fancymode t;
- if mode = 'maprin then fancy!-maprin0 l
- else
- fancy!-flush();
- >>;
- symbolic procedure fancy!-flush();
- << fancy!-terpri!* t;
- for each line in reverse fancy!-page!* do
- if line and not eqcar(car line,'tab) then
- <<fancy!-out!-header();
- for each it in reverse line do fancy!-out!-item it;
- fancy!-out!-trailer();
- >>;
- set!-fancymode nil;
- >> where !*lower=nil;
-
- %---------------- primitives -----------------------------------
- symbolic procedure fancy!-special!-symbol(u,n);
- if numberp u then
- <<fancy!-prin2!*("\symb{",n);
- fancy!-prin2!*(u,0);
- fancy!-prin2!*("}",0);
- >>
- else fancy!-prin2!*(u,n);
- symbolic procedure fancy!-prin2 u;
- fancy!-prin2!*(u,nil);
- symbolic procedure fancy!-prin2!*(u,n);
- if numberp u and not testing!-width!* then fancy!-prin2number u
- else
- (begin scalar str,id; integer l;
- str := stringp u; id := idp u and not digit u;
- u:= if atom u then explode2 u where !*lower=!*fancy!-lower
- else {u};
- l := if numberp n then n else 2*length u;
- if id and not numberp n then
- u:=fancy!-lower!-digits(fancy!-esc u);
- for each x in u do
- <<if str and (x='! or x='!_)
- then fancy!-line!* := '!\ . fancy!-line!*;
- fancy!-line!* :=
- (if id and !*fancy!-lower
- then red!-char!-downcase x else x) . fancy!-line!*;
- >>;
- fancy!-pos!* := fancy!-pos!* #+ l;
- if fancy!-pos!* #> 2 #* (linelength nil #+1 ) then overflowed!*:=t;
- end) where !*lower = !*lower;
- symbolic procedure fancy!-last!-symbol();
- if fancy!-line!* then car fancy!-line!*;
- charassoc!* :=
- '((!A . !a) (!B . !b) (!C . !c) (!D . !d) (!E . !e) (!F . !f)
- (!G . !g) (!H . !h) (!I . !i) (!J . !j) (!K . !k) (!L . !l)
- (!M . !m) (!N . !n) (!O . !o) (!P . !p) (!Q . !q) (!R . !r)
- (!S . !s) (!T . !t) (!U . !u) (!V . !v) (!W . !w) (!X . !x)
- (!Y . !y) (!Z . !z));
- symbolic procedure red!-char!-downcase u;
- (if x then cdr x else u) where x = atsoc(u,charassoc!*);
- symbolic procedure fancy!-prin2number u;
- % we print a number eventually causing a line break
- % for very big numbers.
- if testing!-width!* then fancy!-prin2!*(u,t) else
- fancy!-prin2number1 (if atom u then explode2 u else u);
- symbolic procedure fancy!-prin2number1 u;
- begin integer c,ll;
- ll := 2 #* (linelength nil #+1 );
- while u do
- <<c:=c+1;
- if c>10 and fancy!-pos!* #> ll then fancy!-terpri!*(t);
- fancy!-prin2!*(car u,2); u:=cdr u;
- >>;
- end;
-
- symbolic procedure fancy!-esc u;
- if not('!_ memq u) then u else
- (if car u eq '!_ then '!\ . w else w)
- where w = car u . fancy!-esc cdr u;
- symbolic procedure fancy!-lower!-digits u;
- (if null m then u else if m = 'all or
- fancy!-lower!-digitstrail(u,nil) then
- fancy!-lower!-digits1(u,nil)
- else u
- ) where m=fancy!-mode 'fancy_lower_digits;
- symbolic procedure fancy!-lower!-digits1(u,s);
- begin scalar c,q,r,w,x;
- loop:
- if u then <<c:=car u; u:=cdr u>> else c:=nil;
- if null s then
- if not digit c and c then w:=c.w else
- << % need to close the symbol w;
- w:=reversip w;
- q:=intern compress w;
- if stringp (x:=get(q,'fancy!-special!-symbol))
- then w:=explode2 x;
- r:=nconc(r,w);
- if digit c then <<s:=t; w:={c}>> else w:=nil;
- >>
- else
- if digit c then w:=c.w else
- << % need to close the number w.
- w:='!_ . '!{ . reversip('!} . w);
- r:=nconc(r,w);
- if c then <<s:=nil; w:={c}>> else w:=nil;
- >>;
- if w then goto loop;
- return r;
- end;
-
- symbolic procedure fancy!-lower!-digitstrail(u,s);
- if null u then s else
- if not s and digit car u then
- fancy!-lower!-digitstrail(cdr u,t) else
- if s and not digit car u then nil
- else fancy!-lower!-digitstrail(cdr u,s);
- symbolic procedure fancy!-terpri!* u;
- <<
- if fancy!-line!* then
- fancy!-page!* := fancy!-line!* . fancy!-page!*;
- fancy!-pos!* :=tablevel!* #* 10;
- fancy!-line!*:= {'tab . tablevel!*};
- overflowed!* := nil
- >>;
- symbolic macro procedure fancy!-level u;
- % unwind-protect for special output functions.
- {'prog,'(pos fl w),
- '(setq pos fancy!-pos!*),
- '(setq fl fancy!-line!*),
- {'setq,'w,cadr u},
- '(cond ((eq w 'failed)
- (setq fancy!-line!* fl)
- (setq fancy!-pos!* pos))),
- '(return w)};
- symbolic procedure fancy!-begin();
- % collect current status of fancy output. Return as a list
- % for later recovery.
- {fancy!-pos!*,fancy!-line!*};
- symbolic procedure fancy!-end(r,s);
- % terminates a fancy print sequence. Eventually resets
- % the output status from status record <s> if the result <r>
- % signals an overflow.
- <<if r='failed then
- <<fancy!-line!*:=car s; fancy!-pos!*:=cadr s>>;
- r>>;
- symbolic procedure fancy!-mode u;
- begin scalar m;
- m:= lispeval u;
- if eqcar(m,'!*sq) then m:=reval m;
- return m;
- end;
- %---------------- central formula converter --------------------
- symbolic procedure fancy!-maprin0 u;
- if not overflowed!* then fancy!-maprint(u,0) where !*lower=nil;
- symbolic procedure fancy!-maprint(l,p!*!*);
- % Print expression l at bracket level p!*!* without terminating
- % print line. Special cases are handled by:
- % pprifn: a print function that includes bracket level as 2nd arg.
- % prifn: a print function with one argument.
- (begin scalar p,x,w,pos,fl;
- p := p!*!*; % p!*!* needed for (expt a (quotient ...)) case.
- if null l then return nil;
- if atom l then return fancy!-maprint!-atom(l,p);
- pos := fancy!-pos!*; fl := fancy!-line!*;
-
- if not atom car l then return fancy!-maprint(car l,p);
- l := fancy!-convert(l,nil);
- if (x:=get(car l,'fancy!-reform)) then
- return fancy!-maprint(apply1(x,l),p);
- if ((x := get(car l,'fancy!-pprifn)) and
- not(apply2(x,l,p) eq 'failed))
- or ((x := get(car l,'fancy!-prifn)) and
- not(apply1(x,l) eq 'failed))
- or (get(car l,'print!-format)
- and fancy!-print!-format(l,p) neq 'failed)
- then return nil;
- if testing!-width!* and overflowed!*
- or w='failed then return fancy!-fail(pos,fl);
- % eventually convert expression to a different form
- % for printing.
- l := fancy!-convert(l,'infix);
- % printing operators with integer argument in index form.
- if flagp(car l,'print!-indexed) then
- << fancy!-prefix!-operator(car l);
- w :=fancy!-print!-indexlist cdr l
- >>
-
- else if x := get(car l,'infix) then
- << p := not(x>p);
- w:= if p then fancy!-in!-brackets(
- {'fancy!-inprint,mkquote car l,x,mkquote cdr l},
- '!(,'!))
- else
- fancy!-inprint(car l,x,cdr l);
- >>
- else if x:= get(car l,'fancy!-flatprifn) then
- w:=apply(x,{l})
- else
- <<
- w:=fancy!-prefix!-operator(car l);
- obrkp!* := nil;
- if w neq 'failed then
- w:=fancy!-print!-function!-arguments cdr l;
- >>;
-
- return if testing!-width!* and overflowed!*
- or w='failed then fancy!-fail(pos,fl) else nil;
- end ) where obrkp!*=obrkp!*;
- symbolic procedure fancy!-convert(l,m);
- % special converters.
- if eqcar(l,'expt) and cadr l= 'e and
- ( m='infix or treesizep(l,20) )
- then {'exp,caddr l}
- else l;
- symbolic procedure fancy!-print!-function!-arguments u;
- % u is a parameter list for a function.
- fancy!-in!-brackets(
- u and {'fancy!-inprint, mkquote '!*comma!*,0,mkquote u},
- '!(,'!));
- symbolic procedure fancy!-maprint!-atom(l,p);
- fancy!-level
- begin scalar x;
- if(x:=get(l,'fancy!-special!-symbol))
- then fancy!-special!-symbol(x,
- get(l,'fancy!-special!-symbol!-size) or 2)
- else
- if vectorp l then
- <<fancy!-prin2!*("[",0);
- l:=for i:=0:upbv l collect getv(l,i);
- x:=fancy!-inprint(",",0,l);
- fancy!-prin2!*("]",0);
- return x>>
- else
- if not numberp l or (not (l<0) or p<=get('minus,'infix))
- then fancy!-prin2!*(l,'index)
- else
- fancy!-in!-brackets(
- {'fancy!-prin2!*,mkquote l,t}, '!(,'!));
- return if testing!-width!* and overflowed!* then 'failed
- else nil;
- end;
- put('print_indexed,'psopfn,'(lambda(u)(flag u 'print!-indexed)));
- symbolic procedure fancy!-print!-indexlist l;
- fancy!-print!-indexlist1(l,'!_,nil);
- symbolic procedure fancy!-print!-indexlist1(l,op,sep);
- % print index or exponent lists, with or without separator.
- fancy!-level
- begin scalar w,testing!-width!*,obrkp!*;
- testing!-width!* :=t;
- fancy!-prin2!*(op,0);
- fancy!-prin2!*('!{,0);
- w:=fancy!-inprint(sep or 'times,0,l);
- fancy!-prin2!*("}",0);
- return w;
- end;
- symbolic procedure fancy!-print!-one!-index i;
- fancy!-level
- begin scalar w,testing!-width!*,obrkp!*;
- testing!-width!* :=t;
- fancy!-prin2!*('!_,0);
- fancy!-prin2!*('!{,0);
- w:=fancy!-inprint('times,0,{i});
- fancy!-prin2!*("}",0);
- return w;
- end;
- symbolic procedure fancy!-in!-brackets(u,l,r);
- % put form into brackets (round, curly,...).
- % u: form to be evaluated,
- % l,r: left and right brackets to be inserted.
- fancy!-level
- (begin scalar fp,w,r1,r2,rec;
- rec := {0};
- fancy!-bstack!* := rec . fancy!-bstack!*;
- fancy!-adjust!-bkt!-levels fancy!-bstack!*;
- fp := length fancy!-page!*;
- fancy!-prin2!* (r1:='bkt.nil.l.rec, 2);
- w := eval u;
- fancy!-prin2!* (r2:='bkt.nil.r.rec, 2);
- % no line break: use \left( .. \right) pair.
- if fp = length fancy!-page!* then
- <<car cdr r1:= t; car cdr r2:= t>>;
- return w;
- end)
- where fancy!-bstack!* = fancy!-bstack!*;
-
- symbolic procedure fancy!-adjust!-bkt!-levels u;
- if null u or null cdr u then nil
- else if caar u >= caadr u then
- <<car cadr u := car cadr u +1;
- fancy!-adjust!-bkt!-levels cdr u; >>;
- symbolic procedure fancy!-exptpri(l,p);
- % Prints expression in an exponent notation.
- (begin scalar !*list,pp,q,w,w1,w2,pos,fl;
- pos:=fancy!-pos!*; fl:=fancy!-line!*;
- pp := not((q:=get('expt,'infix))>p); % Need to parenthesize
- w1 := cadr l; w2 := caddr l;
- testing!-width!* := t;
- if eqcar(w2,'quotient) and cadr w2 = 1
- and (fixp caddr w2 or liter caddr w2) then
- return fancy!-sqrtpri!*(w1,caddr w2);
- if eqcar(w2,'quotient) and eqcar(cadr w2,'minus)
- then w2 := list('minus,list(car w2,cadadr w2,caddr w2))
- else w2 := negnumberchk w2;
- if fancy!-maprint(w1,q)='failed
- then return fancy!-fail(pos,fl);
- fancy!-prin2!*("^",0);
- if eqcar(w2,'quotient) and fixp cadr w2 and fixp caddr w2 then
- <<fancy!-prin2!*("{",0); w:=fancy!-inprint('!/,0,cdr w2);
- fancy!-prin2!*("}",0)>>
- else w:=fancy!-maprint!-tex!-bkt(w2,0,nil);
- if w='failed then return fancy!-fail(pos,fl) ;
- end) where !*ratpri=!*ratpri,
- testing!-width!*=testing!-width!*;
- put('expt,'fancy!-pprifn,'fancy!-exptpri);
- symbolic procedure fancy!-inprint(op,p,l);
- (begin scalar x,y,w, pos,fl;
- pos:=fancy!-pos!*;
- fl:=fancy!-line!*;
- % print product of quotients using *.
- if op = 'times and eqcar(car l,'quotient) and
- cdr l and eqcar(cadr l,'quotient) then
- op:='!*;
- if op eq 'plus and !*revpri then l := reverse l;
- if not get(op,'alt) then
- <<
- if op eq 'not then
- << fancy!-oprin op;
- return fancy!-maprint(car l,get('not,'infix));
- >>;
- if op eq 'setq and not atom (x := car reverse l)
- and idp car x and (y := getrtype x)
- and (y := get(get(y,'tag),'fancy!-setprifn))
- then return apply2(y,car l,x);
- if not atom car l and idp caar l
- and
- ((x := get(caar l,'fancy!-prifn))
- or (x := get(caar l,'fancy!-pprifn)))
- and (get(x,op) eq 'inbrackets)
- % to avoid mix up of indices and exponents.
- then<<
- fancy!-in!-brackets(
- {'fancy!-maprint,mkquote car l,p}, '!(,'!));
- >>
- else if !*nosplit and not testing!-width!* then
- fancy!-prinfit(car l, p, nil)
- else w:=fancy!-maprint(car l, p);
- l := cdr l
- >>;
- if testing!-width!* and (overflowed!* or w='failed)
- then return fancy!-fail(pos,fl);
- if !*list and obrkp!* and memq(op,'(plus minus)) then
- <<sumlevel!*:=sumlevel!*+1;
- tablevel!* := tablevel!* #+ 1>>;
- if !*nosplit and not testing!-width!* then
- % main line:
- fancy!-inprint1(op,p,l)
- else w:=fancy!-inprint2(op,p,l);
- if testing!-width!* and w='failed then return fancy!-fail(pos,fl);
- end
- ) where tablevel!*=tablevel!*, sumlevel!*=sumlevel!*;
-
- symbolic procedure fancy!-inprint1(op,p,l);
- % main line (top level) infix printing, allow line break;
- begin scalar lop,space;
- space := flagp(op,'spaced);
- for each v in l do
- <<lop := op;
- if op='plus and eqcar(v,'minus) then
- <<lop := 'minus; v:= cadr v>>;
- if space then fancy!-prin2!*("\,",1);
- if 'failed = fancy!-oprin lop then
- <<fancy!-terpri!* nil; fancy!-oprin lop>>;
- if space then fancy!-prin2!*("\,",1);
- fancy!-prinfit(negnumberchk v, p, nil)
- >>;
- end;
- symbolic procedure fancy!-inprint2(op,p,l);
- % second line
- begin scalar lop,space,w;
- space := flagp(op,'spaced);
- for each v in l do
- if not testing!-width!* or w neq 'failed then
- <<lop:=op;
- if op='plus and eqcar(v,'minus) then
- <<lop := 'minus; v:= cadr v>>;
- if space then fancy!-prin2!*("\,",1);
- fancy!-oprin lop;
- if space then fancy!-prin2!*("\,",1);
- if w neq 'failed then w:=fancy!-maprint(negnumberchk v,p)
- >>;
- return w;
- end;
- symbolic procedure fancy!-inprintlist(op,p,l);
- % inside algebraic list
- fancy!-level
- begin scalar fst,w,v;
- loop:
- if null l then return w;
- v := car l; l:= cdr l;
- if fst then
- << fancy!-prin2!*("\,",1);
- w:=fancy!-oprin op;
- fancy!-prin2!*("\,",1);
- >>;
- if w eq 'failed and testing!-width!* then return w;
- w:= if w eq 'failed then fancy!-prinfit(v,0,op)
- else fancy!-prinfit(v,0,nil);
- if w eq 'failed and testing!-width!* then return w;
- fst := t;
- goto loop;
- end;
- put('times,'fancy!-prtch,"\,");
- symbolic procedure fancy!-oprin op;
- fancy!-level
- begin scalar x;
- if (x:=get(op,'fancy!-prtch)) then fancy!-prin2!*(x,1)
- else
- if (x:=get(op,'fancy!-infix!-symbol))
- then fancy!-special!-symbol(x,get(op,'fancy!-symbol!-length)
- or 4)
- else
- if null(x:=get(op,'prtch)) then fancy!-prin2!*(op,t)
- else
- << if !*list and obrkp!* and op memq '(plus minus)
- and sumlevel!*=2
- then
- if testing!-width!* then return 'failed
- else fancy!-terpri!* t;
- fancy!-prin2!*(x,t);
- >>;
- if overflowed!* then return 'failed
- end;
- put('alpha,'fancy!-special!-symbol,"\alpha");
- put('beta,'fancy!-special!-symbol,"\beta");
- put('gamma,'fancy!-special!-symbol,"\gamma");
- put('delta,'fancy!-special!-symbol,"\delta");
- put('epsilon,'fancy!-special!-symbol,"\epsilon");
- put('zeta,'fancy!-special!-symbol,"\zeta");
- put('eta,'fancy!-special!-symbol,"\eta");
- put('theta,'fancy!-special!-symbol,"\theta");
- put('iota,'fancy!-special!-symbol,"\iota");
- put('kappa,'fancy!-special!-symbol,"\kappa");
- put('lambda,'fancy!-special!-symbol,"\lambda");
- put('mu,'fancy!-special!-symbol,"\mu");
- put('nu,'fancy!-special!-symbol,"\nu");
- put('xi,'fancy!-special!-symbol,"\xi");
- put('pi,'fancy!-special!-symbol,"\pi");
- put('rho,'fancy!-special!-symbol,"\rho");
- put('sigma,'fancy!-special!-symbol,"\sigma");
- put('tau,'fancy!-special!-symbol,"\tau");
- put('upsilon,'fancy!-special!-symbol,"\upsilon");
- put('phi,'fancy!-special!-symbol,"\phi");
- put('chi,'fancy!-special!-symbol,"\chi");
- put('psi,'fancy!-special!-symbol,"\psi");
- put('omega,'fancy!-special!-symbol,"\omega");
- if 'a neq '!A then deflist('(
- (!Alpha 65) (!Beta 66) (!Chi 67) (!Delta 68)
- (!Epsilon 69)(!Phi 70) (!Gamma 71)(!Eta 72)
- (!Iota 73) (!vartheta 74)(!Kappa 75)(!Lambda 76)
- (!Mu 77)(!Nu 78)(!O 79)(!Pi 80)(!Theta 81)
- (!Rho 82)(!Sigma 83)(!Tau 84)(!Upsilon 85)
- (!Omega 87) (!Xi 88)(!Psi 89)(!Zeta 90)
- (!varphi 106)
- ),'fancy!-special!-symbol);
- put('infinity,'fancy!-special!-symbol,"\infty");
- % some symbols form the upper ASCII part of the symbol font
- put('partial!-df,'fancy!-special!-symbol,182);
- put('partial!-df,'fancy!-symbol!-length,8);
- put('empty!-set,'fancy!-special!-symbol,198);
- put('not,'fancy!-special!-symbol,216);
- put('not,'fancy!-infix!-symbol,216);
- % symbols as infix opertors
- put('leq,'fancy!-infix!-symbol,163);
- put('geq,'fancy!-infix!-symbol,179);
- put('neq,'fancy!-infix!-symbol,185);
- put('intersection,'fancy!-infix!-symbol,199);
- put('union,'fancy!-infix!-symbol,200);
- put('member,'fancy!-infix!-symbol,206);
- put('and,'fancy!-infix!-symbol,217);
- put('or,'fancy!-infix!-symbol,218);
- put('when,'fancy!-infix!-symbol,239);
- put('!*wcomma!*,'fancy!-infix!-symbol,",\,");
- put('replaceby,'fancy!-infix!-symbol,222);
- put('replaceby,'fancy!-symbol!-length,8);
- % symbols as prefix functions
- % put('gamma,'fancy!-functionsymbol,71); % big Gamma
- %
- put('!~,'fancy!-functionsymbol,34); % forall
- put('!~,'fancy!-symbol!-length,8);
- % arbint, arbcomplex.
- put('arbcomplex,'fancy!-functionsymbol,227);
- put('arbint,'fancy!-functionsymbol,226);
- flag('(arbcomplex arbint),'print!-indexed);
- % flag('(delta),'print!-indexed); % Dirac delta symbol.
- % David Hartley voted against..
- % The following definitions allow for more natural printing of
- % conditional expressions within rule lists.
- symbolic procedure fancy!-condpri0 u;
- fancy!-condpri(u,0);
- symbolic procedure fancy!-condpri(u,p);
- fancy!-level
- begin scalar w;
- if p>0 then fancy!-prin2 "\bigl(";
- while (u := cdr u) and w neq 'failed do
- <<if not(caar u eq 't)
- then <<fancy!-prin2 'if; fancy!-prin2 " ";
- w:=fancy!-maprin0 caar u;
- fancy!-prin2 "\,"; fancy!-prin2 'then;
- fancy!-prin2 "\,">>;
- if w neq 'failed then w := fancy!-maprin0 cadar u;
- if cdr u then <<fancy!-prin2 "\,";
- fancy!-prin2 'else; fancy!-prin2 "\,">>>>;
- if p>0 then fancy!-prin2 "\bigr)";
- if overflowed!* or w='failed then return 'failed;
- end;
- put('cond,'fancy!-pprifn,'fancy!-condpri);
- put('cond,'fancy!-flatprifn,'fancy!-condpri0);
- symbolic procedure fancy!-revalpri u;
- fancy!-maprin0 fancy!-unquote cadr u;
- symbolic procedure fancy!-unquote u;
- if eqcar(u,'list) then for each x in cdr u collect
- fancy!-unquote x
- else if eqcar(u,'quote) then cadr u else u;
- put('aeval,'fancy!-prifn,'fancy!-revalpri);
- put('aeval!*,'fancy!-prifn,'fancy!-revalpri);
- put('reval,'fancy!-prifn,'fancy!-revalpri);
- put('reval!*,'fancy!-prifn,'fancy!-revalpri);
- put('aminusp!:,'fancy!-prifn,'fancy!-patpri);
- put('aminusp!:,'fancy!-pat,'(lessp !&1 0));
- symbolic procedure fancy!-patpri u;
- begin scalar p;
- p:=subst(fancy!-unquote cadr u,'!&1,
- get(car u,'fancy!-pat));
- return fancy!-maprin0 p;
- end;
- symbolic procedure fancy!-boolvalpri u;
- fancy!-maprin0 cadr u;
- put('boolvalue!*,'fancy!-prifn,'fancy!-boolvalpri);
- symbolic procedure fancy!-quotpri u;
- begin scalar n1,n2,fl,w,pos,testing!-width!*;
- if overflowed!* then return 'failed;
- testing!-width!*:=t;
- pos:=fancy!-pos!*;
- fl:=fancy!-line!*;
- fancy!-prin2!*("\frac",0);
- w:=fancy!-maprint!-tex!-bkt(cadr u,0,t);
- n1 := fancy!-pos!*;
- if w='failed
- then return fancy!-fail(pos,fl);
- fancy!-pos!* := pos;
- w := fancy!-maprint!-tex!-bkt(caddr u,0,nil);
- n2 := fancy!-pos!*;
- if w='failed
- then return fancy!-fail(pos,fl);
- fancy!-pos!* := max(n1,n2);
- return t;
- end;
- symbolic procedure fancy!-maprint!-tex!-bkt(u,p,m);
- % Produce expression with tex brackets {...} if
- % necessary. Ensure that {} unit is in same formula.
- % If m=t brackets will be inserted in any case.
- begin scalar w,pos,fl,testing!-width!*;
- testing!-width!*:=t;
- pos:=fancy!-pos!*;
- fl:=fancy!-line!*;
- if not m and (numberp u and 0<=u and u <=9 or liter u) then
- << fancy!-prin2!*(u,t);
- return if overflowed!* then fancy!-fail(pos,fl);
- >>;
- fancy!-prin2!*("{",0);
- w := fancy!-maprint(u,p);
- fancy!-prin2!*("}",0);
- if w='failed then return fancy!-fail(pos,fl);
- end;
-
- symbolic procedure fancy!-fail(pos,fl);
- <<
- overflowed!* := nil;
- fancy!-pos!* := pos;
- fancy!-line!* := fl;
- 'failed
- >>;
- put('quotient,'fancy!-prifn,'fancy!-quotpri);
- symbolic procedure fancy!-prinfit(u, p, op);
- % Display u (as with maprint) with op in front of it, but starting
- % a new line before it if there would be overflow otherwise.
- begin scalar pos,fl,w,ll,f;
- if pairp u and (f:=get(car u,'fancy!-prinfit)) then
- return apply(f,{u,p,op});
- pos:=fancy!-pos!*;
- fl:=fancy!-line!*;
- begin scalar testing!-width!*;
- testing!-width!*:=t;
- if op then w:=fancy!-oprin op;
- if w neq 'failed then w := fancy!-maprint(u,p);
- end;
- if w neq 'failed then return t;
- fancy!-line!*:=fl; fancy!-pos!*:=pos;
- if testing!-width!* and w eq 'failed then return w;
-
- if op='plus and eqcar(u,'minus) then <<op := 'minus; u:=cadr u>>;
- w:=if op then fancy!-oprin op;
- % if the operator causes the overflow, we break the line now.
- if w eq 'failed then
- <<fancy!-terpri!* nil;
- if op then fancy!-oprin op;
- return fancy!-maprint(u, p);>>;
- % if at least half the line is still free and the
- % object causing the overflow has been a number,
- % let it break.
- if fancy!-pos!* < (ll:=linelength(nil)) then
- if numberp u then return fancy!-prin2number u else
- if eqcar(u,'!:rd!:) then return fancy!-rdprin u;
- % generate a line break if we are not just behind an
- % opening bracket at the beginning of a line.
- if fancy!-pos!* > linelength nil #/ 2 or
- not eqcar(fancy!-last!-symbol(),'bkt) then
- fancy!-terpri!* nil;
- return fancy!-maprint(u, p);
- end;
- %-----------------------------------------------------------
- %
- % support for print format property
- %
- %-----------------------------------------------------------
- symbolic procedure print_format(f,pat);
- % Assign a print pattern p to the operator form f.
- put(car f, 'print!-format, (cdr f . pat) . get(car f, 'print!-format));
- symbolic operator print_format;
- symbolic procedure fancy!-print!-format(u,p);
- fancy!-level
- begin scalar fmt,fmtl,a;
- fmtl:=get(car u,'print!-format);
- l:
- if null fmtl then return 'failed;
- fmt := car fmtl; fmtl := cdr fmtl;
- if length(car fmt) neq length cdr u then goto l;
- a:=pair(car fmt,cdr u);
- return fancy!-print!-format1(cdr fmt,p,a);
- end;
- symbolic procedure fancy!-print!-format1(u,p,a);
- begin scalar w,x,y,pl,bkt,obkt,q;
- if eqcar(u,'list) then u:= cdr u;
- while u and w neq 'failed do
- <<x:=car u; u:=cdr u;
- if eqcar(x,'list) then x:=cdr x;
- obkt := bkt; bkt:=nil;
- if obkt then fancy!-prin2!*('!{,0);
- w:=if pairp x then fancy!-print!-format1(x,p,a) else
- if memq(x,'(!( !) !, !. !|)) then
- <<if x eq '!( then <<pl:=p.pl; p:=0>> else
- if x eq '!) then <<p:=car pl; pl:=cdr pl>>;
- fancy!-prin2!*(x,1)>> else
- if x eq '!_ or x eq '!^ then <<bkt:=t;fancy!-prin2!*(x,0)>> else
- if q:=assoc(x,a) then fancy!-maprint(cdr q,p) else
- fancy!-maprint(x,p);
- if obkt then fancy!-prin2!*('!},0);
- >>;
- return w;
- end;
-
- %-----------------------------------------------------------
- %
- % some operator specific print functions
- %
- %-----------------------------------------------------------
- symbolic procedure fancy!-prefix!-operator(u);
- % Print as function, but with a special character.
- begin scalar sy;
- sy :=
- get(u,'fancy!-functionsymbol) or get(u,'fancy!-special!-symbol);
- if sy
- then fancy!-special!-symbol(sy,get(u,'fancy!-symbol!-length) or 2)
- else fancy!-prin2!*(u,t);
- end;
- put('sqrt,'fancy!-prifn,'fancy!-sqrtpri);
- symbolic procedure fancy!-sqrtpri(u);
- fancy!-sqrtpri!*(cadr u,2);
-
- symbolic procedure fancy!-sqrtpri!*(u,n);
- fancy!-level
- begin
- if not numberp n and not liter n then return 'failed;
- fancy!-prin2!*("\sqrt",0);
- if n neq 2 then
- <<fancy!-prin2!*("[",0);
- fancy!-prin2!*("\,",1);
- fancy!-prin2!*(n,t);
- fancy!-prin2!*("]",0);
- >>;
- return fancy!-maprint!-tex!-bkt(u,0,t);
- end;
- symbolic procedure fancy!-sub(l,p);
- % Prints expression in an exponent notation.
- if get('expt,'infix)<=p then
- fancy!-in!-brackets({'fancy!-sub,mkquote l,0},'!(,'!))
- else
- fancy!-level
- begin scalar eqs,w;
- l:=cdr l;
- while cdr l do <<eqs:=append(eqs,{car l}); l:=cdr l>>;
- l:=car l;
- testing!-width!* := t;
- w := fancy!-maprint(l,get('expt,'infix));
- if w='failed then return w;
- fancy!-prin2!*("\bigl",0);
- fancy!-prin2!*("|",1);
- fancy!-prin2!*('!_,0);
- fancy!-prin2!*("{",0);
- w:=fancy!-inprint('!*comma!*,0,eqs);
- fancy!-prin2!*("}",0);
- return w;
- end;
- put('sub,'fancy!-pprifn,'fancy!-sub);
-
- put('factorial,'fancy!-pprifn,'fancy!-factorial);
- symbolic procedure fancy!-factorial(u,n);
- fancy!-level
- begin scalar w;
- w := (if atom cadr u then fancy!-maprint(cadr u,9999)
- else
- fancy!-in!-brackets({'fancy!-maprint,mkquote cadr u,0},
- '!(,'!))
- );
- fancy!-prin2!*("!",2);
- return w;
- end;
- put('binomial,'fancy!-prifn,'fancy!-binomial);
- symbolic procedure fancy!-binomial(u,n);
- fancy!-level
- begin scalar w1,w2;
- fancy!-prin2!*("\left(\begin{array}{c}",2);
- w1 := fancy!-maprint(cadr u,0);
- fancy!-prin2!*("\\",0);
- w2 := fancy!-maprint(caddr u,0);
- fancy!-prin2!*("\end{array}\right)",2);
- if w1='failed or w2='failed then return 'failed;
- end;
- symbolic procedure fancy!-intpri(u,p);
- if p>get('times,'infix) then
- fancy!-in!-brackets({'fancy!-intpri,mkquote u,0},'!(,'!))
- else
- fancy!-level
- begin scalar w1,w2;
- % if fancy!-mode!*>35 and fancy!-height(cadr u,1.0) > 3 then
- if fancy!-height(cadr u,1.0) > 3 then
- fancy!-prin2!*("\Int",0)
- else
- fancy!-prin2!*("\int",0);
- w1:=fancy!-maprint(cadr u,0);
- fancy!-prin2!*("\,d\,",2);
- w2:=fancy!-maprint(caddr u,0);
- if w1='failed or w2='failed then return 'failed;
- end;
- symbolic procedure fancy!-height(u,h);
- % estimate the height of an expression.
- if atom u then h
- else if car u = 'minus then fancy!-height(cadr u,h)
- else if car u = 'plus or car u = 'times then
- eval('max. for each w in cdr u collect fancy!-height(w,h))
- else if car u = 'expt then
- fancy!-height(cadr u,h) + fancy!-height(caddr u,h*0.8)
- else if car u = 'quotient then
- fancy!-height(cadr u,h) + fancy!-height(caddr u,h)
- else if get(car u,'simpfn) then fancy!-height(cadr u,h)
- else h;
- put('int,'fancy!-pprifn,'fancy!-intpri);
- symbolic procedure fancy!-sumpri!*(u,p,mode);
- if p>get('minus,'infix) then
- fancy!-in!-brackets({'fancy!-sumpri!*,mkquote u,0,mkquote mode},
- '!(,'!))
- else
- fancy!-level
- begin scalar w,w0,w1,lo,hi,var;
- var := caddr u;
- if cdddr u then lo:=cadddr u;
- if lo and cddddr u then hi := car cddddr u;
- w:=if lo then {'equal,var,lo} else var;
- if mode = 'sum then
- fancy!-prin2!*("\sum",0) % big SIGMA
- else if mode = 'prod then
- fancy!-prin2!*("\prod",0); % big PI
- fancy!-prin2!*('!_,0);
- fancy!-prin2!*('!{,0);
- if w then w0:=fancy!-maprint(w,0);
- fancy!-prin2!*('!},0);
- if hi then <<fancy!-prin2!*('!^,0);
- fancy!-maprint!-tex!-bkt(hi,0,nil);
- >>;
- fancy!-prin2!*('!\!, ,1);
- w1:=fancy!-maprint(cadr u,0);
- if w0='failed or w1='failed then return 'failed;
- end;
- symbolic procedure fancy!-sumpri(u,p); fancy!-sumpri!*(u,p,'sum);
- put('sum,'fancy!-pprifn,'fancy!-sumpri);
- put('infsum,'fancy!-pprifn,'fancy!-sumpri);
- symbolic procedure fancy!-prodpri(u,p); fancy!-sumpri!*(u,p,'prod);
- put('prod,'fancy!-pprifn,'fancy!-prodpri);
- symbolic procedure fancy!-limpri(u,p);
- if p>get('minus,'infix) then
- fancy!-in!-brackets({'fancy!-sumpri,mkquote u,0},'!(,'!))
- else
- fancy!-level
- begin scalar w,lo,var;
- var := caddr u;
- if cdddr u then lo:=cadddr u;
- fancy!-prin2!*("\lim",6);
- fancy!-prin2!*('!_,0);
- fancy!-prin2!*('!{,0);
- fancy!-maprint(var,0);
- fancy!-prin2!*("\to",0);
- fancy!-maprint(lo,0);
- fancy!-prin2!*('!},0);
- w:=fancy!-maprint(cadr u,0);
- return w;
- end;
- put('limit,'fancy!-pprifn,'fancy!-limpri);
- symbolic procedure fancy!-listpri(u);
- fancy!-level
- (if null cdr u then fancy!-maprint('empty!-set,0)
- else
- fancy!-in!-brackets(
- {'fancy!-inprintlist,mkquote '!*wcomma!*,0,mkquote cdr u},
- '!{,'!})
- );
- put('list,'fancy!-prifn,'fancy!-listpri);
- put('list,'fancy!-flatprifn,'fancy!-listpri);
- put('!*sq,'fancy!-reform,'fancy!-sqreform);
- symbolic procedure fancy!-sqreform u;
- prepsq!* sqhorner!* cadr u;
- put('df,'fancy!-pprifn,'fancy!-dfpri);
- % 9-Dec-93: 'total repaired
- symbolic procedure fancy!-dfpri(u,l);
- (if flagp(cadr u,'print!-indexed) or
- pairp cadr u and flagp(caadr u,'print!-indexed)
- then fancy!-dfpriindexed(u,l)
- else if m = 'partial then fancy!-dfpri0(u,l,'partial!-df)
- else if m = 'total then fancy!-dfpri0(u,l,'!d)
- else if m = 'indexed then fancy!-dfpriindexed(u,l)
- else rederr "unknown print mode for DF")
- where m=fancy!-mode('fancy_print_df);
- symbolic procedure fancy!-partialdfpri(u,l);
- fancy!-dfpri0(u,l,'partial!-df);
- symbolic procedure fancy!-dfpri0(u,l,symb);
- if null cddr u then fancy!-maprin0{'times,symb,cadr u} else
- if l >= get('expt,'infix) then % brackets if exponented
- fancy!-in!-brackets({'fancy!-dfpri0,mkquote u,0,mkquote symb},
- '!(,'!))
- else
- fancy!-level
- begin scalar x,d,q; integer n,m;
- u:=cdr u;
- q:=car u;
- u:=cdr u;
- while u do
- <<x:=car u; u:=cdr u;
- if u and numberp car u then
- <<m:=car u; u := cdr u>> else m:=1;
- n:=n+m;
- d:= append(d,{symb,if m=1 then x else {'expt,x,m}});
- >>;
- return fancy!-maprin0
- {'quotient, {'times,if n=1 then symb else
- {'expt,symb,n},q},
- 'times. d};
- end;
- symbolic procedure fancy!-dfpriindexed(u,l);
- if null cddr u then fancy!-maprin0{'times,'partial!-df,cadr u} else
- begin scalar w;
- w:=fancy!-maprin0 cadr u;
- if testing!-width!* and w='failed then return w;
- w :=fancy!-print!-indexlist fancy!-dfpriindexedx(cddr u,nil);
- return w;
- end;
- symbolic procedure fancy!-dfpriindexedx(u,p);
- if null u then nil else
- if numberp car u then
- append(for i:=2:car u collect p,fancy!-dfpriindexedx(cdr u,p))
- else
- car u . fancy!-dfpriindexedx(cdr u,car u);
- put('!:rd!:,'fancy!-prifn,'fancy!-rdprin);
- put('!:rd!:,'fancy!-flatprifn,'fancy!-rdprin);
- symbolic procedure fancy!-rdprin u;
- fancy!-level
- begin scalar digits; integer dotpos,xp;
- u:=rd!:explode u;
- digits := car u; xp := cadr u; dotpos := caddr u;
- return fancy!-rdprin1(digits,xp,dotpos);
- end;
- symbolic procedure fancy!-rdprin1(digits,xp,dotpos);
- begin scalar str;
- if xp>0 and dotpos+xp<length digits-1 then
- <<dotpos := dotpos+xp; xp:=0>>;
- % build character string from number.
- for i:=1:dotpos do
- <<str := car digits . str;
- digits := cdr digits; if null digits then digits:='(!0);
- >>;
- str := '!. . str;
- for each c in digits do str :=c.str;
- if not(xp=0) then
- <<str:='!e.str;
- for each c in explode2 xp do str:=c.str>>;
- if testing!-width!* and
- fancy!-pos!* + 2#*length str > 2 #* linelength nil then
- return 'failed;
- fancy!-prin2number1 reversip str;
- end;
- put('!:cr!:,'fancy!-pprifn,'fancy!-cmpxprin);
- put('!:cr!:,'fancy!-pprifn,'fancy!-cmpxprin);
- symbolic procedure fancy!-cmpxprin(u,l);
- begin scalar rp,ip;
- rp:=reval {'repart,u}; ip:=reval {'impart,u};
- return fancy!-maprint(
- if ip=0 then rp else
- if rp=0 then {'times,ip,'!i} else
- {'plus,rp,{'times,ip,'!i}},l);
- end;
- symbolic procedure fancy!-dn!:prin u;
- begin scalar lst; integer dotpos,ex;
- lst := bfexplode0x (cadr u, cddr u);
- ex := cadr lst;
- dotpos := caddr lst;
- lst := car lst;
- return fancy!-rdprin1 (lst,ex,dotpos)
- end;
- put ('!:dn!:, 'fancy!-prifn, 'fancy!-dn!:prin);
- fmp!-switch t;
- endmodule;
- %-------------------------------------------------------
- module f; % Matrix printing routines.
- fluid '(!*nat);
- fluid '(obrkp!*);
- symbolic procedure fancy!-setmatpri(u,v);
- fancy!-matpri1(cdr v,u);
- put('mat,'fancy!-setprifn,'fancy!-setmatpri);
- symbolic procedure fancy!-matpri u;
- fancy!-matpri1(cdr u,nil);
-
- put('mat,'fancy!-prifn,'fancy!-matpri);
- symbolic procedure fancy!-matpri1(u,x);
- % Prints a matrix canonical form U with name X.
- % Tries to do fancy display if nat flag is on.
- begin scalar w;
- w := fancy!-matpri2(u,x,nil);
- if w neq 'failed or testing!-width!* then return w;
- fancy!-matpri3(u,x);
- end;
- symbolic procedure fancy!-matpri2(u,x,bkt);
- % Tries to print matrix as compact block.
- fancy!-level
- begin scalar w,testing!-width!*,fl,fp,fmat,row,elt,fail;
- integer cols,rows,rw,maxpos;
- testing!-width!*:=t;
- rows := length u;
- cols := length car u;
- if cols*rows>400 then return 'failed;
-
- if x then
- << fancy!-maprint(x,0); fancy!-prin2!*(":=",4) >>;
- fl := fancy!-line!*; fp := fancy!-pos!*;
- % remaining room for the columns.
- rw := linelength(nil)-2 -(fancy!-pos!*+2);
- rw := rw/cols;
- fmat := for each row in u collect
- for each elt in row collect
- if not fail then
- <<fancy!-line!*:=nil; fancy!-pos!*:=0;
- w:=fancy!-maprint(elt,0);
- if fancy!-pos!*>maxpos then maxpos:=fancy!-pos!*;
- if w='failed or fancy!-pos!*>rw
- then fail:=t else
- (fancy!-line!*.fancy!-pos!*)
- >>;
- if fail then return 'failed;
- testing!-width!* := nil;
- % restore output line.
- fancy!-pos!* := fp; fancy!-line!* := fl;
- % TEX header
- fancy!-prin2!*(bldmsg("\left%w\begin{array}{",
- if bkt then car bkt else "("),0);
- for i:=1:cols do fancy!-prin2!*("c",0);
- fancy!-prin2!*("}",0);
- % join elements.
- while fmat do
- <<row := car fmat; fmat:=cdr fmat;
- while row do
- <<elt:=car row; row:=cdr row;
- fancy!-line!* := append(car elt,fancy!-line!*);
- if row then fancy!-line!* :='!& . fancy!-line!*
- else if fmat then
- fancy!-line!* := "\\". fancy!-line!*;
- >>;
- >>;
- fancy!-prin2!*(bldmsg("\end{array}\right%w",
- if bkt then cdr bkt else ")"),0);
- % compute total horizontal extent of matrix
- fancy!-pos!* := fp + maxpos*(cols+1);
- return t;
- end;
- symbolic procedure fancy!-matpri3(u,x);
- if null x then fancy!-matpriflat('mat.u) else
- begin scalar obrkp!*,!*list;
- integer r,c;
- obrkp!* := nil;
- if null x then x:='mat;
- fancy!-terpri!*;
- for each row in u do
- <<r:=r+1; c:=0;
- for each elt in row do
- << c:=c+1;
- if not !*nero then
- << fancy!-prin2!*(x,t);
- fancy!-print!-indexlist {r,c};
- fancy!-prin2!*(":=",t);
- fancy!-maprint(elt,0);
- fancy!-terpri!* t;
- >>;
- >>;
- >>;
- end;
- symbolic procedure fancy!-matpriflat(u);
- begin
- fancy!-oprin 'mat;
- fancy!-in!-brackets(
- {'fancy!-matpriflat1,mkquote '!*wcomma!*,0,mkquote cdr u},
- '!(,'!));
- end;
- symbolic procedure fancy!-matpriflat1(op,p,l);
- % inside algebraic list
- begin scalar fst,w;
- for each v in l do
- <<if fst then
- << fancy!-prin2!*("\,",1);
- fancy!-oprin op;
- fancy!-prin2!*("\,",1);
- >>;
- % if the next row does not fit on the current print line
- % we move it completely to a new line.
- if fst then
- w:= fancy!-level
- fancy!-in!-brackets(
- {'fancy!-inprintlist,mkquote '!*wcomma!*,0,mkquote v},
- '!(,'!)) where testing!-width!*=t;
- if w eq 'failed then fancy!-terpri!* t;
- if not fst or w eq 'failed then
- fancy!-in!-brackets(
- {'fancy!-inprintlist,mkquote '!*wcomma!*,0,mkquote v},
- '!(,'!));
- fst := t;
- >>;
- end;
- put('mat,'fancy!-flatprifn,'fancy!-matpriflat);
- symbolic procedure fancy!-matfit(u,p,op);
- % Prinfit routine for matrix.
- % a new line before it if there would be overflow otherwise.
- fancy!-level
- begin scalar pos,fl,fp,w,ll;
- pos:=fancy!-pos!*;
- fl:=fancy!-line!*;
- begin scalar testing!-width!*;
- testing!-width!*:=t;
- if op then w:=fancy!-oprin op;
- if w neq 'failed then w := fancy!-matpri(u);
- end;
- if w neq 'failed or
- (w eq 'failed and testing!-width!*) then return w;
- fancy!-line!*:=fl; fancy!-pos!*:=pos; w:=nil;
- fp := fancy!-page!*;
- % matrix: give us a second chance with a fresh line
- begin scalar testing!-width!*;
- testing!-width!*:=t;
- if op then w:=fancy!-oprin op;
- fancy!-terpri!* nil;
- if w neq 'failed then w := fancy!-matpri u;
- end;
- if w neq 'failed then return t;
- fancy!-line!*:=fl; fancy!-pos!*:=pos; fancy!-page!*:=fp;
- ll:=linelength nil;
- if op then fancy!-oprin op;
- if atom u or fancy!-pos!* > ll #/ 2 then fancy!-terpri!* nil;
- return fancy!-matpriflat(u);
- end;
- put('mat,'fancy!-prinfit,'fancy!-matfit);
- put('taylor!*,'fancy!-reform,'Taylor!*print1);
- endmodule;
- module fancy_specfn;
- put('besseli,'fancy!-prifn,'fancy!-bessel);
- put('besselj,'fancy!-prifn,'fancy!-bessel);
- put('bessely,'fancy!-prifn,'fancy!-bessel);
- put('besselk,'fancy!-prifn,'fancy!-bessel);
- put('besseli,'fancy!-functionsymbol,'(ascii 73));
- put('besselj,'fancy!-functionsymbol,'(ascii 74));
- put('bessely,'fancy!-functionsymbol,'(ascii 89));
- put('besselk,'fancy!-functionsymbol,'(ascii 75));
- symbolic procedure fancy!-bessel(u);
- fancy!-level
- begin scalar w;
- fancy!-prefix!-operator car u;
- w:=fancy!-print!-one!-index cadr u;
- if testing!-width!* and w eq 'failed then return w;
- return fancy!-print!-function!-arguments cddr u;
- end;
- % Hypergeometric functions.
- put('empty!*,'fancy!-special!-symbol,32);
- put('hypergeometric,'fancy!-prifn,'fancy!-hypergeometric);
- symbolic procedure fancy!-hypergeometric u;
- fancy!-level
- begin scalar w,a1,a2,a3;
- a1 :=cdr cadr u;
- a2 := cdr caddr u;
- a3 := cadddr u;
- fancy!-special!-symbol(get('empty!*,'fancy!-special!-symbol),nil);
- w:=fancy!-print!-one!-index length a1;
- if testing!-width!* and w eq 'failed then return w;
- fancy!-prin2!*("F",nil);
- w:=fancy!-print!-one!-index length a2;
- if testing!-width!* and w eq 'failed then return w;
- fancy!-prin2!*("(",nil);
- w := w eq 'failed or fancy!-print!-indexlist1(a1,'!^,'!*comma!*);
- w := w eq 'failed or fancy!-print!-indexlist1(a2,'!_,'!*comma!*);
- fancy!-prin2!*("\,",1);
- w := w eq 'failed or fancy!-special!-symbol(124,1); % vertical bar
- fancy!-prin2!*("\,",1);
- w := w eq 'failed or fancy!-prinfit(a3,0,nil);
- fancy!-prin2!*(")",nil);
- return w;
- end;
-
- % hypergeometric({1,2,u/w,v},{5,6},sqrt x);
- put('meijerg,'fancy!-prifn,'fancy!-meijerG);
- symbolic procedure fancy!-meijerG u;
- fancy!-level
- begin scalar w,a1,a2,a3;
- integer n,m,p,q;
- a1 :=cdr cadr u;
- a2 := cdr caddr u;
- a3 := cadddr u;
- m:=length cdar a2;
- n:=length cdar a1;
- a1 := append(cdar a1 , cdr a1);
- a2 := append(cdar a2 , cdr a2);
- p:=length a1; q:=length a2;
- fancy!-prin2!*("G",nil);
- w := w eq 'failed or
- fancy!-print!-indexlist1({m,n},'!^,nil);
- w := w eq 'failed or
- fancy!-print!-indexlist1({p,q},'!_,nil);
- fancy!-prin2!*("(",nil);
- w := w eq 'failed or fancy!-prinfit(a3,0,nil);
- w := w eq 'failed or fancy!-special!-symbol(124,1); % vertical bar
- w := w eq 'failed or fancy!-print!-indexlist1(a1,'!^,'!*comma!*);
- w := w eq 'failed or fancy!-print!-indexlist1(a2,'!_,'!*comma!*);
- fancy!-prin2!*(")",nil);
- return w;
- end;
-
- % meijerg({{},1},{{0}},x);
-
- endmodule;
-
- end;
|