1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690 |
- % ----------------------------------------------------------------------
- % $Id: tmprint.red,v 1.10 2004/11/20 20:50:14 seidl Exp $
- % ----------------------------------------------------------------------
- % Copyright (c) 2003-2004 A. Dolzmann, A. Seidl, and T. Sturm
- % changes by A C Norman, 2005
- % ----------------------------------------------------------------------
- %
- %
- % $Log: tmprint.red,v $
- % Revision 1.11 2005/05/02 09:35:13 acn1
- % This represents working through the whole code trying to tidy it
- % up and remove all the parts that were to do with making this REDUCE
- % code take responsibility for line-breaks. As a result so much has been
- % changed that the bulk of the change-log information here becomes
- % irrelevant for a support basis, so I have removed the bits of change
- % log that represent earlier ACN changes, and abbreviated some of the
- % earlier ones when they involve adjustments that are either now very
- % stable or that have now vanished in more recent re-writes. But I will
- % preserve the information about who made changes and when to keep a track
- % of credit for work here.
- %
- % Revision 1.10 2004/11/20 20:50:14 seidl
- % Linelength hack established again, only if Texmacs runs. Removed
- % centering and curly brackets from fancy-out-header and -trailer.
- % New switch promptnumbers, turned off only if Texmacs is running.
- %
- % Revision 1.9 2004/11/19 00:52:26 seidl )
- % Revision 1.8 2004/11/18 20:44:16 seidl )
- % Revision 1.7 2004/11/09 01:11:17 seidl ) loads of good updates that
- % Revision 1.6 2004/09/24 10:42:41 seidl ) made this a working system!
- % Revision 1.5 2004/08/12 13:04:23 seidl )
- % Revision 1.4 2003/11/20 13:10:44 sturm )
- % Revision 1.3 2003/11/20 12:23:01 sturm )
- % Revision 1.2 2003/11/20 11:06:12 sturm )
- % Texmacs now basically runs.
- % Revision 1.1 2003/11/11 11:08:57 sturm
- % Inital check-in.
- % This is the original version by Andrey Grozin as obtained from fmprint.red
- % via patching.
- %
- % ----------------------------------------------------------------------
- module tmprint; % Output module for TeXmacs interface
- % Fancy output package for symbolic expressions.
- % using TEX as intermediate language. The exact details here are tuned
- % to work with TeXmacs, which reuires something close to but not 100%
- % identical to standard LaTeX.
- % Author: Herbert Melenk, using ideas of maprin.red (A.C.H, A.C.N).
-
- % Copyright (c) 1993 RAND, Konrad-Zuse-Zentrum. All rights reserved.
- % Significant subsequent updates by A Grozin, T Sturm,
- % A Dolzman, A Seidl and A Norman, 2003-2005
- % Updates made: 8-Sep-94 12-Apr-94 17_Mar-94
- % switches
- %
- % ON FANCY enable algebraic output processing by this module
- % ON PROMPTNUMBER enable the default REDUCE prompt scheme. This
- % switch is so that numbering can be disabled.
- % ON REDFRONT_MODE adjustments that help with the REDFRONT interface
- %
- % properties used in this module:
- %
- % fancy-prifn print function for an operator
- %
- % fancy-pprifn print function for an operator including current
- % operator precedence for infix printing
- %
- % fancy-prtch string for infix printing of an operator
- %
- % fancy-special-symbol
- % print expression for a non-indexed item
- % string with TEX expression "\alpha"
- %
- % fancy-infix-symbol special-symbol for infix operators
- %
- % fancy-prefix-symbol special symbol for prefix operators
- %
- % Updates made: 94-Jan-26 94-Jan-17 93-Dec-22
- create!-package('(tmprint),nil);
- fluid '(
- !*nat
- !*revpri
- outputhandler!*
- outputhandler!-stack!*
- posn!*
- );
- global '(charassoc!* ofl!*);
- switch revpri;
- % Global variables initialized in this section.
- fluid '(
- fancy!-switch!-on!*
- fancy!-switch!-off!*
- !*fancy!-mode
- fancy!-line!*
- fancy!-bstack!*
- !*fancy!-lower);
- fancy!-switch!-on!* := int2id 16$
- fancy!-switch!-off!* := int2id 17$
- !*fancy!-lower := nil; % case fold things to lower case if TRUE
- 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)) ));
- global '(lispsystem!*);
- switch promptnumbers;
- symbolic procedure fmp!-switch mode;
- if mode then
- <<if outputhandler!* neq 'fancy!-output then
- <<outputhandler!-stack!* :=
- outputhandler!* . outputhandler!-stack!*;
- outputhandler!* := 'fancy!-output;
- >>;
- % with CSL I want to be able to switch texmacs mode on and off dynamically,
- % so I switch off prompt numbering as I enter texmacs mode and put it
- % back on on the way out.
- if member('csl,lispsystem!*) and
- member('texmacs,lispsystem!*) then
- off1 'promptnumbers
- >>
- else
- <<if outputhandler!* = 'fancy!-output then
- <<outputhandler!* := car outputhandler!-stack!*;
- outputhandler!-stack!* := cdr outputhandler!-stack!*;
- >> else
- % With CSL I want to have tmprint loaded as part of the initial lisp image,
- % and I want to call fmp!-switch early on based on whether I believe I should
- % use the CSL internal display mode or an external viewer such as Texmacs.
- % I thus want to be able to say "do not use fancy mode" rather explicitly
- % from there whether or not it happened to be enabled in the system that
- % saved the image file. So I really do not want this rederr call! I switch
- % promptnumbers back on here for the case when Texmacs fancy printing is
- % not wanted but the prompt colouring stuff from this file is activated (eg
- % because redfront is in use, or Texmacs but without the fancy option?). I
- % believe that mostly with CSL prompts are handled by CSL itself and so
- % the promptnumbering flag is not relevant uless it has been set up for
- % external Texmacs use...
- if not member('csl, lispsystem!*) then
- rederr "FANCY is not current output handler";
- if member('csl, lispsystem!*) then on1 'promptnumbers
- >>;
- % The following procedure is applicable in the PSL version of REDUCE. The
- % CSL interface to TeXmacs uses a different scheme (reduce is launched
- % as "r38 --texmacs" and then a flag 'texmacs is put on the variable
- % lispsystem!*).
- % Texmacs predicate. Returns [t] iff Texmacs is running.
- procedure texmacsp;
- if getenv("TEXMACS_REDUCE_PATH") then t;
- % The next two functions provide abstraction for conversion between
- % strings and lists of character objects.
- !#if (memq 'csl lispsystem!*)
- % Convert a list of character objects into a string.
- % (The function list!-to!-string already exists...)
- % Convert a string into a list of character objects.
- smacro procedure string!-to!-list a;
- explode2 a;
- % Print a string without ANY conversion or adjustment, so if the string
- % has control characters etc in it they get transmitted unchanged. Well
- % let me express some reservations about what might happen if the string
- % contains tabs and newlines - the lower level system IO code might
- % interpret same...
- smacro procedure raw!-print!-string s;
- prin2 s;
- % Print the character whose code is n.
- smacro procedure writechar n;
- tyo n; % Like "prin2 int2id n"
- % Convert a symbol or string to characters but ensure that all
- % output characters are folded to lower case.
- % CSL already has explode2lc;
- !#else
- smacro procedure list!-to!-string a;
- compress ('!" . append(a, '(!")));
- smacro procedure string!-to!-list a;
- explode2 a;
- % I do not know if this has to be like this in PSL, but it reflects
- % what was in the code.
- symbolic procedure raw!-print!-string s;
- for each x in string!-to!-list s do prin2 x;
- % writechar already exists in PSL.
- symbolic procedure explode2lc s;
- explode2 s where !*lower = t;
- !#endif
- symbolic procedure fancy!-tex s;
- % test output: print tex string.
- << prin2 fancy!-switch!-on!*;
- raw!-print!-string s;
- 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 l then prin2 "\left" else prin2 "\right";
- 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!-line!*:=nil;
- fancy!-line!*:= '((tab . 1)) >>;
- symbolic procedure fancy!-output(mode,l);
- % Interface routine.
- if ofl!* or (mode='maprin and posn!*>2) or not !*nat then <<
- 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!-out!-header();
- <<
- if posn()>0 then terpri();
- prin2 int2id 2;
- prin2 "latex:\black$\displaystyle "
- >>;
- symbolic procedure fancy!-out!-trailer();
- <<
- prin2 "$";
- prin2 int2id 5
- >>;
-
- symbolic procedure fancy!-flush();
- begin
- scalar !*lower; % Rebinding *lower is needed for PSL here
- if fancy!-line!* and not eqcar(car fancy!-line!*,'tab) then <<
- fancy!-out!-header();
- for each it in reverse fancy!-line!* do fancy!-out!-item it;
- fancy!-out!-trailer() >>;
- fancy!-line!*:= {'tab . 1};
- set!-fancymode nil
- end;
-
- %---------------- primitives -----------------------------------
- % This one prints its argument without any adjustment at all
- symbolic procedure fancy!-princ u;
- fancy!-line!* := u . fancy!-line!*;
- % This prints an item, but it adds \mathrm() around it at times,
- % maps special symbols, converts a21 to a_{21} and sticks in some
- % backslashes where it thinks they are needed...
- symbolic procedure fancy!-prin2 u;
- begin scalar str,id, longname;
- if atom u and eqcar(explode2 u,'!\) then <<
- fancy!-line!* := u . fancy!-line!*;
- return >>
- else if numberp u then <<
- % The behaviour here seems really odd to me but appears to match what the
- % version of tmprint in the development tree at the end of April 2005
- % does... I suspect that either ALL numbers should be set in \mathrm or
- % none should be.
- if u >= 10 or u < 0 then
- fancy!-line!* := '!} . u . '!\mathrm!{ . fancy!-line!*
- else fancy!-line!* := u . fancy!-line!*;
- return >>;
- str := stringp u;
- id := idp u and not digit u;
- u:= if atom u then <<
- if !*fancy!-lower then explode2lc u
- else explode2 u >>
- else {u};
- if id then <<
- u:=fancy!-lower!-digits fancy!-esc u;
- if car u = '!\mathrm!{ then longname := t >>
- else if car u neq '!\ and cdr u then <<
- fancy!-line!* := '!\mathrm!{ . fancy!-line!*;
- longname := t >>;
- 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!*;
- >>;
- if longname then fancy!-line!* := "}" . fancy!-line!*;
- end;
- 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!*);
- % Take any sequence of chars and stick "\" in front of any "_".
- 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;
- % This is going to split a name of the form abc123 into
- % something like abc_{123}. Well it takes a list of characters
- % as its argument and any string of digits within that should be
- % lowered, so eg abc123xyz789 becomes abc_{123}xyz_{789}
- % however as a yet more messy step, if a string of non-digits is a
- % special word it gets mapped onto the corresponding symbol, so
- % eg alpha, infinity etc het mapped onto \alpha, \infty...
- symbolic procedure fancy!-lower!-digits1 u;
- begin
- scalar r, w, w1, longname;
- u := reverse u;
- while u do <<
- % Collect the next word (without any digits in it)
- while u and not digit car u do <<
- w := car u . w;
- u := cdr u >>;
- if w then <<
- w1 := intern compress w;
- if stringp (w1 := get(w1, 'fancy!-special!-symbol)) then
- w := explode2 w1;
- longname := car w neq '!\ and cdr w;
- r := append(w, r) >>;
- % now process and string of digits
- if u and digit car u then <<
- r := '!} . r;
- while u and digit car u do <<
- r := car u . r;
- u := cdr u >>;
- r := '!_ . '!{ . r >> >>;
- % Each time around the loop the next character must be either
- % a digit or not a digit, and in either case I make progress.
- if longname then r := '!\mathrm!{ . r;
- return r;
- end;
- % This procedure judges whether to rewrite a symbol as a susbcripted
- % item. It will detect cases of a name that starts with one or more
- % non-digits, has at least one digit, and from the location onwards
- % consists only of digits. It is used in the default case when
- % fancy_lower_digits is neither NIL nor ALL.
- symbolic procedure fancy!-lower!-digitstrail u;
- begin
- % an empty name or one starting with a digit should not be lowered
- if null u or digit car u then return nil;
- u := cdr u;
- % trim any initial non-digits
- while u and not digit car u do u := cdr u;
- % if nothing is left we do not have even a potential subscript
- if null u then return nil;
- % scan to check that all the rest is made up of digits, and if so
- % declare TRUE.
- while u and digit car u do u := cdr u;
- return null u
- end;
- symbolic procedure fancy!-lower!-digits u;
- (if null m then u
- else if m = 'all or
- fancy!-lower!-digitstrail u then
- fancy!-lower!-digits1 u
- else if null cdr u then u
- else '!\mathrm!{ . u
- ) where m=fancy!-mode fancy_lower_digits;
- symbolic procedure fancy!-mode u;
- if eqcar(u,'!*sq) then reval u
- else u;
- %---------------- central formula converter --------------------
- % This is just used at the top level, and it arranges that a number
- % printed there is never put as \mathrm even though it might be anywhere
- % else!
- % The behaviour here seems really odd to me but appears to match what the
- % version of tmprint in the development tree at the end of April 2005
- % does... I suspect that either ALL numbers should be set in \mathrm or
- % none should be.
- symbolic procedure fancy!-maprin0 u;
- if numberp u then fancy!-princ u
- else fancy!-maprint(u,0) where !*lower=nil;
- symbolic procedure fancy!-maprin1 u;
- 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 x,pos;
- if null l then return nil;
- if atom l then return fancy!-maprint!-atom(l,p);
-
- 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)) then return apply2(x,l,p)
- else if (x := get(car l,'fancy!-prifn)) then return apply1(x,l)
- else if get(car l,'print!-format) then
- return fancy!-print!-format(l,p);
- % 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);
- fancy!-print!-indexlist cdr l
- >>
-
- else if x := get(car l,'infix) then
- << p := not(x>p);
- 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!-pprifn)) then return apply2(x,l,0)
- else if (x := get(car l,'fancy!-prifn)) then return apply1(x,l)
- else <<
- fancy!-prefix!-operator(car l);
- fancy!-print!-function!-arguments cdr l >>
- end;
- 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);
- begin scalar x;
- if (x:=get(l,'fancy!-special!-symbol)) then fancy!-prin2 x
- else if vectorp l then <<
- fancy!-princ "[";
- l:=for i:=0:upbv l collect getv(l,i);
- fancy!-inprint(",",0,l);
- fancy!-princ "]";
- return nil>>
- else if not numberp l or
- l >= 0 or
- p <= get('minus,'infix) then fancy!-prin2 l
- else fancy!-in!-brackets({'fancy!-prin2,mkquote l}, '!(,'!));
- return 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.
- begin
- fancy!-prin2 op;
- fancy!-princ "{";
- fancy!-inprint(sep or 'times,0,l);
- fancy!-princ "}";
- end;
- symbolic procedure fancy!-print!-one!-index i;
- begin
- fancy!-princ "_{";
- fancy!-inprint('times,0,{i});
- fancy!-princ "}";
- 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.
- (begin scalar fp,r1,r2,rec;
- rec := {0};
- fancy!-bstack!* := rec . fancy!-bstack!*;
- fancy!-adjust!-bkt!-levels fancy!-bstack!*;
- fancy!-prin2 (r1:='bkt.nil.l.rec);
- eval u;
- fancy!-prin2 (r2:='bkt.nil.r.rec);
- car cdr r1:= t;
- car cdr r2:= t;
- return nil;
- 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 pp,q,w1,w2;
- pp := not((q:=get('expt,'infix))>p); % Need to parenthesize
- w1 := cadr l; w2 := caddr l;
- 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;
- fancy!-maprint(w1,q);
- fancy!-princ "^";
- if eqcar(w2,'quotient) and fixp cadr w2 and fixp caddr w2 then <<
- fancy!-princ "{";
- fancy!-inprint('!/,0,cdr w2);
- fancy!-princ "}" >>
- else fancy!-maprint!-tex!-bkt(w2,0,nil);
- end;
- put('expt,'fancy!-pprifn,'fancy!-exptpri);
- symbolic procedure fancy!-inprint(op,p,l);
- begin scalar x,y;
- % 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) then <<
- % to avoid mix up of indices and exponents.
- fancy!-in!-brackets(
- {'fancy!-maprint,mkquote car l,p}, '!(,'!)) >>;
- fancy!-maprint(car l, p);
- l := cdr l >>;
- fancy!-inprint2(op,p,l);
- end;
-
- symbolic procedure fancy!-inprint2(op,p,l);
- % second line
- begin scalar lop;
- for each v in l do
- <<lop:=op;
- if op='plus and eqcar(v,'minus) then
- <<lop := 'minus; v:= cadr v>>;
- fancy!-oprin lop;
- fancy!-maprint(negnumberchk v,p)
- >>
- end;
- symbolic procedure fancy!-inprintlist(op,p,l);
- % inside algebraic list
- begin scalar fst,v;
- loop:
- if null l then return nil;
- v := car l; l:= cdr l;
- if fst then
- << fancy!-princ "\,";
- fancy!-oprin op;
- fancy!-princ "\,";
- >>;
- fancy!-maprint(v,0);
- fst := t;
- goto loop;
- end;
- put('times,'fancy!-prtch,"\*");
- symbolic procedure fancy!-oprin op;
- begin scalar x;
- if (x:=get(op,'fancy!-prtch)) then fancy!-prin2 x
- else if (x:=get(op,'fancy!-infix!-symbol)) then fancy!-prin2 x
- else if null(x:=get(op,'prtch)) then fancy!-prin2 op
- else fancy!-prin2 x
- 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,"\varepsilon");
- 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,"\varkappa");
- 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 (memq 'csl lispsystem!*)
- deflist('(
- % Many of these are just the same glyphs as ordinary upper case letters,
- % and so for compatibility with external viewers I map those ones onto
- % letters with the "\mathit" qualifier to force the font.
- (!Alpha "\mathit{A}") (!Beta "\mathit{B}") (!Chi "\Chi ")
- (!Delta "\Delta ") (!Epsilon "\mathit{E}") (!Phi "\Phi ")
- (!Gamma "\Gamma ") (!Eta "\mathit{H}") (!Iota "\mathit{I}")
- (!vartheta "\vartheta") (!Kappa "\Kappa ") (!Lambda "\Lambda ")
- (!Mu "\mathit{M}") (!Nu "\mathit{N}") (!O "\mathit{O}")
- (!Pi "\Pi ") (!Theta "\Theta ") (!Rho "\mathit{R}")
- (!Sigma "\Sigma ") (!Tau "\Tau ") (!Upsilon "\Upsilon ")
- (!Omega "\Omega ") (!Xi "\Xi ") (!Psi "\Psi ")
- (!Zeta "\mathit{Z}") (!varphi "\varphi ")
- ),'fancy!-special!-symbol);
- !#else
- if 'a neq '!A then deflist('(
- (!Alpha "A") (!Beta "B") (!Chi "\Chi") (!Delta "\Delta")
- (!Epsilon "E")(!Phi "\Phi") (!Gamma "\Gamma")(!Eta "H")
- (!Iota "I") (vartheta "\vartheta")(!Kappa "K")(!Lambda "\Lambda")
- (!Mu "M")(!Nu "N")(!O "O")(!Pi "\Pi")(!Theta "\Theta")
- (!Rho "R")(!Sigma "\Sigma")(!Tau "\Tau")(!Upsilon "\Upsilon")
- (!Omega "\Omega") (!Xi "\Xi")(!Psi "\Psi")(!Zeta "Z")
- (varphi "\varphi")
- ),'fancy!-special!-symbol);
- !#endif
- put('infinity,'fancy!-special!-symbol,"\infty ");
- put('partial!-df,'fancy!-special!-symbol,"\partial ");
- put('empty!-set,'fancy!-special!-symbol,"\emptyset ");
- put('not,'fancy!-special!-symbol,"\neg ");
- put('not,'fancy!-infix!-symbol,"\neg ");
- put('leq,'fancy!-infix!-symbol,"\leq ");
- put('geq,'fancy!-infix!-symbol,"\geq ");
- put('neq,'fancy!-infix!-symbol,"\neq ");
- put('intersection,'fancy!-infix!-symbol,"\cap ");
- put('union,'fancy!-infix!-symbol,"\cup ");
- put('member,'fancy!-infix!-symbol,"\in ");
- put('and,'fancy!-infix!-symbol,"\wedge ");
- put('or,'fancy!-infix!-symbol,"\vee ");
- put('when,'fancy!-infix!-symbol,"|");
- put('!*wcomma!*,'fancy!-infix!-symbol,",\,");
- put('replaceby,'fancy!-infix!-symbol,"\Rightarrow ");
- put('!~,'fancy!-functionsymbol,"\forall ");
- % The following definitions allow for more natural printing of
- % conditional expressions within rule lists.
- symbolic procedure fancy!-condpri(u,p);
- begin
- if p>0 then fancy!-princ "\left(";
- while (u := cdr u) do <<
- if not(caar u eq 't) then <<
- fancy!-princ "if\ ";
- fancy!-maprin1 caar u;
- fancy!-princ "\,then\," >>;
- fancy!-maprin1 cadar u;
- if cdr u then <<
- fancy!-princ "\,";
- fancy!-princ "else\," >> >>;
- if p>0 then fancy!-prin2 "\right)";
- end;
- put('cond,'fancy!-pprifn,'fancy!-condpri);
- symbolic procedure fancy!-revalpri u;
- fancy!-maprin1 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!-maprin1 p;
- end;
- symbolic procedure fancy!-boolvalpri u;
- fancy!-maprin1 cadr u;
- put('boolvalue!*,'fancy!-prifn,'fancy!-boolvalpri);
- symbolic procedure fancy!-quotpri u;
- begin
- fancy!-princ "\frac";
- fancy!-maprint!-tex!-bkt(cadr u,0,t);
- fancy!-maprint!-tex!-bkt(caddr u,0,nil);
- 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 fl;
- if not m and (numberp u and 0<=u and u <=9 or liter u) then
- << fancy!-prin2 u;
- return nil;
- >>;
- fancy!-princ "{";
- fancy!-maprint(u,p);
- fancy!-princ "}"
- end;
-
- put('quotient,'fancy!-prifn,'fancy!-quotpri);
- %-----------------------------------------------------------
- %
- % 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);
- begin scalar fmt,fmtl,a;
- fmtl:=get(car u,'print!-format);
- l:
- 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 x,y,pl,bkt,obkt,q;
- if eqcar(u,'list) then u:= cdr u;
- while u do
- <<x:=car u; u:=cdr u;
- if eqcar(x,'list) then x:=cdr x;
- obkt := bkt; bkt:=nil;
- if obkt then fancy!-princ "{";
- 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 >>
- else if x eq '!_ or x eq '!^ then <<bkt:=t;fancy!-prin2 x>>
- else if q:=assoc(x,a) then fancy!-maprint(cdr q,p)
- else fancy!-maprint(x,p);
- if obkt then fancy!-princ "}"
- >>
- 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!-prin2 sy
- else fancy!-prin2 u
- end;
- put('sqrt,'fancy!-prifn,'fancy!-sqrtpri);
- symbolic procedure fancy!-sqrtpri(u);
- fancy!-sqrtpri!*(cadr u,2);
-
- symbolic procedure fancy!-sqrtpri!*(u,n);
- begin
- fancy!-princ "\sqrt";
- if n neq 2 then <<
- fancy!-princ "[\,";
- fancy!-prin2 n;
- fancy!-princ "]" >>;
- 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
- begin scalar eqs;
- l:=cdr l;
- while cdr l do <<eqs:=append(eqs,{car l}); l:=cdr l>>;
- l:=car l;
- fancy!-maprint(l,get('expt,'infix));
- fancy!-princ "|_{";
- fancy!-inprint('!*comma!*,0,eqs);
- fancy!-princ "}"
- end;
- put('sub,'fancy!-pprifn,'fancy!-sub);
-
- put('factorial,'fancy!-pprifn,'fancy!-factorial);
- symbolic procedure fancy!-factorial(u,n);
- begin
- if atom cadr u then fancy!-maprint(cadr u,9999)
- else fancy!-in!-brackets({'fancy!-maprint,mkquote cadr u,0},
- '!(,'!));
- fancy!-princ "!";
- end;
- put('binomial,'fancy!-prifn,'fancy!-binomial);
- symbolic procedure fancy!-binomial u;
- begin
- fancy!-princ "\left(\begin{matrix}";
- fancy!-maprint(cadr u,0);
- fancy!-princ "\\";
- fancy!-maprint(caddr u,0);
- fancy!-princ "\end{matrix}\right)";
- end;
- symbolic procedure fancy!-intpri(u,p);
- if p>get('times,'infix) then
- fancy!-in!-brackets({'fancy!-intpri,mkquote u,0},'!(,'!))
- else
- begin
- if fancy!-height(cadr u,1.0) > 3 then fancy!-princ "\Int "
- else fancy!-princ "\int ";
- fancy!-maprint(cadr u,0);
- fancy!-princ "\,d\,";
- fancy!-maprint(caddr u,0)
- end;
- % It may well be that if TeXmacs does all the layout that this is no longer
- % needed.
- 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
- begin scalar w,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!-princ "\sum" % big SIGMA
- else if mode = 'prod then
- fancy!-princ "\prod"; % big PI
- fancy!-princ "_{";
- if w then fancy!-maprint(w,0);
- fancy!-princ "}";
- if hi then <<
- fancy!-princ "^";
- fancy!-maprint!-tex!-bkt(hi,0,nil) >>;
- fancy!-princ "\,";
- fancy!-maprint(cadr u,0);
- 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
- begin scalar lo,var;
- var := caddr u;
- if cdddr u then lo:=cadddr u;
- fancy!-princ "\lim";
- fancy!-princ "_{";
- fancy!-maprint(var,0);
- fancy!-princ "\rightarrow";
- fancy!-maprint(lo,0);
- fancy!-princ "}";
- fancy!-maprint(cadr u,0);
- end;
- put('limit,'fancy!-pprifn,'fancy!-limpri);
- symbolic procedure fancy!-listpri(u);
- (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('!*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!-maprin1 {'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
- 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!-maprin1
- {'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!-maprin1{'times,'partial!-df,cadr u}
- else <<
- fancy!-maprin1 cadr u;
- fancy!-print!-indexlist fancy!-dfpriindexedx(cddr u,nil) >>;
- 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);
- symbolic procedure fancy!-rdprin u;
- 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>>;
- for each c in reversip str do fancy!-prin2 c
- 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.
- 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!-matpri2(u,x);
- begin scalar fl,fmat,row,elt;
- integer cols,rows,rw,maxpos;
- rows := length u;
- cols := length car u;
- % I can and will re-write all of this when I have the rest working again...
- if x then <<
- fancy!-maprint(x,0);
- % I think I might use princ on the next line, but the current code renders
- % ":=" within \mathrm... ???
- fancy!-prin2 ":=" >>;
- fl := fancy!-line!*;
- fmat := for each row in u collect
- for each elt in row collect
- <<fancy!-line!*:=nil;
- fancy!-maprint(elt,0);
- fancy!-line!* >>;
- % restore output line.
- fancy!-line!* := fl;
- % TEX header
- fancy!-princ "\left(\begin{matrix}";
- % join elements.
- while fmat do
- <<row := car fmat; fmat:=cdr fmat;
- while row do
- <<elt:=car row; row:=cdr row;
- fancy!-line!* := append(elt,fancy!-line!*);
- if row then fancy!-line!* :='!& . fancy!-line!*
- else if fmat then
- fancy!-line!* := "\\". fancy!-line!* >> >>;
- fancy!-princ "\end{matrix}\right)"
- end;
- 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.
- fancy!-matpri2(u,x);
- put('taylor!*,'fancy!-reform,'Taylor!*print1);
- endmodule;
- module fancy_specfn;
- put('sin,'fancy!-prifn,'fancy!-sin);
- put('cos,'fancy!-prifn,'fancy!-cos);
- put('tan,'fancy!-prifn,'fancy!-tan);
- put('cot,'fancy!-prifn,'fancy!-cot);
- put('sec,'fancy!-prifn,'fancy!-sec);
- put('csc,'fancy!-prifn,'fancy!-csc);
- put('asin,'fancy!-prifn,'fancy!-asin);
- put('acos,'fancy!-prifn,'fancy!-acos);
- put('atan,'fancy!-prifn,'fancy!-atan);
- put('sinh,'fancy!-prifn,'fancy!-sinh);
- put('cosh,'fancy!-prifn,'fancy!-cosh);
- put('tanh,'fancy!-prifn,'fancy!-tanh);
- put('coth,'fancy!-prifn,'fancy!-coth);
- put('exp,'fancy!-prifn,'fancy!-exp);
- put('log,'fancy!-prifn,'fancy!-log);
- put('ln,'fancy!-prifn,'fancy!-ln);
- put('max,'fancy!-prifn,'fancy!-max);
- put('min,'fancy!-prifn,'fancy!-min);
- %put('repart,'fancy!-prifn,'fancy!-repart);
- %put('impart,'fancy!-prifn,'fancy!-impart);
- symbolic procedure fancy!-sin(u);
- begin
- fancy!-princ "\sin";
- fancy!-print!-function!-arguments cdr u;
- end;
- symbolic procedure fancy!-cos(u);
- begin
- fancy!-princ "\cos";
- fancy!-print!-function!-arguments cdr u;
- end;
- symbolic procedure fancy!-tan(u);
- begin
- fancy!-princ "\tan";
- fancy!-print!-function!-arguments cdr u;
- end;
- symbolic procedure fancy!-cot(u);
- begin
- fancy!-princ "\cot";
- fancy!-print!-function!-arguments cdr u;
- end;
- symbolic procedure fancy!-sec(u);
- begin
- fancy!-princ "\sec";
- fancy!-print!-function!-arguments cdr u;
- end;
- symbolic procedure fancy!-csc(u);
- begin
- fancy!-princ "\csc";
- fancy!-print!-function!-arguments cdr u;
- end;
- symbolic procedure fancy!-asin(u);
- begin
- fancy!-princ "\arcsin";
- fancy!-print!-function!-arguments cdr u;
- end;
- symbolic procedure fancy!-acos(u);
- begin
- fancy!-princ "\arccos";
- fancy!-print!-function!-arguments cdr u;
- end;
- symbolic procedure fancy!-atan(u);
- begin
- fancy!-princ "\arctan";
- fancy!-print!-function!-arguments cdr u;
- end;
- symbolic procedure fancy!-sinh(u);
- begin
- fancy!-princ "\sinh";
- fancy!-print!-function!-arguments cdr u;
- end;
- symbolic procedure fancy!-cosh(u);
- begin
- fancy!-princ "\cosh";
- fancy!-print!-function!-arguments cdr u;
- end;
- symbolic procedure fancy!-tanh(u);
- begin
- fancy!-princ "\tanh";
- fancy!-print!-function!-arguments cdr u;
- end;
- symbolic procedure fancy!-coth(u);
- begin
- fancy!-princ "\coth";
- fancy!-print!-function!-arguments cdr u;
- end;
- symbolic procedure fancy!-exp(u);
- begin
- fancy!-princ "\exp";
- fancy!-print!-function!-arguments cdr u;
- end;
- symbolic procedure fancy!-log(u);
- begin
- fancy!-princ "\log";
- fancy!-print!-function!-arguments cdr u;
- end;
- symbolic procedure fancy!-ln(u);
- begin
- fancy!-princ "\ln";
- fancy!-print!-function!-arguments cdr u;
- end;
- symbolic procedure fancy!-max(u);
- begin
- fancy!-princ "\max";
- fancy!-print!-function!-arguments cdr u;
- end;
- symbolic procedure fancy!-min(u);
- begin
- fancy!-princ "\min";
- fancy!-print!-function!-arguments cdr u;
- end;
- symbolic procedure fancy!-repart(u);
- begin
- fancy!-princ "\Re";
- fancy!-print!-function!-arguments cdr u;
- end;
- symbolic procedure fancy!-impart(u);
- begin
- fancy!-princ "\Im";
- fancy!-print!-function!-arguments cdr u;
- end;
- 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);
- begin
- fancy!-prefix!-operator car u;
- fancy!-print!-one!-index cadr u;
- fancy!-print!-function!-arguments cddr u;
- end;
- % Hypergeometric functions.
- put('hypergeometric,'fancy!-prifn,'fancy!-hypergeometric);
- symbolic procedure fancy!-hypergeometric u;
- begin scalar a1,a2,a3;
- a1 :=cdr cadr u;
- a2 := cdr caddr u;
- a3 := cadddr u;
- fancy!-princ "{}";
- fancy!-print!-one!-index length a1;
- fancy!-princ "F";
- fancy!-print!-one!-index length a2;
- fancy!-princ "\left(\left.";
- fancy!-print!-indexlist1(a1,'!^,'!*comma!*);
- fancy!-print!-indexlist1(a2,'!_,'!*comma!*);
- fancy!-princ "\,\right|\,";
- fancy!-maprint(a3,0);
- fancy!-princ "\right)";
- end;
-
- % hypergeometric({1,2,u/w,v},{5,6},sqrt x);
- put('meijerg,'fancy!-prifn,'fancy!-meijerG);
- symbolic procedure fancy!-meijerG u;
- begin scalar 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!-princ "G";
- fancy!-print!-indexlist1({m,n},'!^,nil);
- fancy!-print!-indexlist1({p,q},'!_,nil);
- fancy!-princ "\left(";
- fancy!-maprint(a3,0);
- fancy!-princ "\left|";
- fancy!-print!-indexlist1(a1,'!^,'!*comma!*);
- fancy!-print!-indexlist1(a2,'!_,'!*comma!*);
- fancy!-princ "\right.\right)";
- end;
- % meijerg({{},1},{{0}},x);
-
- % Now a few things that can be useful for testing this code...
- algebraic operator texsym, texbox, texfbox, texstring;
- % texsym(!Longleftarrow) should generate \Longleftarrow (etc). This
- % might plausibly be useful while checking that the interface can render
- % all TeX built-in keywords properly. Furthermore I allow extra args, so
- % that eg texsym(stackrel,f,texsym(longrightarrow)) turns into
- % \stackrel{f}{\longrightarrow}
- put('texsym,'fancy!-prifn,'fancy!-texsym);
- symbolic procedure fancy!-texsym u;
- begin
- if null u then return;
- fancy!-prin2 list!-to!-string ('!\ . explode2 cadr u);
- u := cddr u;
- while u do <<
- fancy!-line!* := "{" . fancy!-line!*;
- fancy!-maprint(car u, 0);
- fancy!-line!* := "}" . fancy!-line!*;
- u := cdr u >>
- end;
- % texstring("arbitrary tex stuff",...)
- % where atoms (eg strings and words) are just passed to tex but
- % more complicated items go through fancy!-maprint.
- put('texstring,'fancy!-prifn,'fancy!-texstring);
- symbolic procedure fancy!-texstring u;
- for each s in cdr u do <<
- if not atom s then fancy!-maprint(s, 0)
- else <<
- if not stringp s then s := list!-to!-string explode2 s;
- fancy!-line!* := s . fancy!-line!* >> >>;
- % texbox(h) is a box of given height (in points)
- % texbox(h, d) is a box of given height and depth
- % height is amount above the reference line, depth is amount
- % below.
- % textbox(h, d, c) is a box of given size with some specified content
- % All these draw a frame around the space used so you can see what is
- % goin on.
- % The idea that this may be useful when checking how layouts cope with
- % various sizes of content, eg big delimiters, square root signs etc. So I
- % can test with "for i := 10:40 do write sqrt(texbox(i))" etc.
- % to test sqrt with arguments of height 10, 11, ... to 40 points. Note that
- % certainly with the CSL version the concept of a "point" is a bit vauge!
- % However if I were to imagine that my screen was at 75 pixels per inch I
- % could with SOME reason interpret point as meaning pixel, and that is
- % what I will do. At present what I might do about hard-copy output is
- % pretty uncertain. If height and depth are given as 0 and there is a
- % content them the content will define the box size.
- put('texbox,'fancy!-prifn,'fancy!-texbox);
- symbolic procedure fancy!-texbox u;
- begin
- scalar height, depth, contents;
- contents := nil;
- u := cdr u;
- height := car u;
- u := cdr u;
- if u then <<
- depth := car u;
- u := cdr u;
- if u then contents := car u >>;
- if not numberp height then height:=0;
- if not numberp depth then depth:=0;
- if height=0 and depth=0 and null content then height:=10;
- fancy!-princ "\fbox{";
- if height neq 0 or depth neq 0 then << % insert a rule
- fancy!-line!* := "\rule" . fancy!-line!*;
- if depth neq 0 then <<
- fancy!-line!* := "[-" . fancy!-line!*;
- fancy!-line!* := depth . fancy!-line!*;
- fancy!-line!* := "pt]" . fancy!-line!* >>;
- fancy!-line!* := "{0pt}{" . fancy!-line!*;
- fancy!-line!* := (height+depth) . fancy!-line!*;
- fancy!-line!* := "pt}" . fancy!-line!* >>;
- if contents then fancy!-maprint(contents, 0)
- else fancy!-line!* := "\rule{10pt}{0pt}" . fancy!-line!*;
- fancy!-princ "}"
- end;
- % texfbox is a simplified version of texbox, and just draws a box around the
- % expression it is given.
- put('texfbox,'fancy!-prifn,'fancy!-texfbox);
- symbolic procedure fancy!-texfbox u;
- begin
- fancy!-princ "\fbox{";
- fancy!-maprint(cadr u, 0);
- fancy!-princ "}"
- end;
- endmodule;
- module promptcolor;
- % Adapted from Prompt coloring for redfront.
- global '(lispsystem!*);
- fluid '(promptstring!* tm_switches!* tm_switches!-this!-sl!* lessspace!*);
- fluid '(!*promptnumbers);
- switch promptnumbers;
- !#if (member 'csl lispsystem!*)
- % With CSL I want tmprint loaded all the time and so making this decision
- % when texmacs is LOADED is not useful.
- !#else
- if texmacsp() then % We don't want prompt numbers in a Texmacs worksheet
- off1 'promptnumbers
- else
- on1 'promptnumbers;
- !#endif
- tm_switches!* := {!*msg,!*output};
- off1 'msg;
- off1 'output;
- procedure tm_bprompt();
- % Begin of prompt.
- {int2id 2,'c,'h,'a,'n,'n,'e,'l,'!:,'p,'r,'o,'m,'p,'t,int2id 5,
- int2id 2,'l,'a,'t,'e,'x,'!:,'!\,'b,'r,'o,'w,'n,'! ,
- '!R,'e,'d,'u,'c,'e};
- procedure tm_eprompt();
- % End of prompt
- {'!\ ,int2id 5};
- % This always gets a list of the characters that make up the prompt...
- procedure tm_coloredp(ec);
- eqcar(ec, car tm_bprompt());
- procedure tm_nconcn(l);
- % Taken from rltools.
- if cdr l then nconc(car l,tm_nconcn cdr l) else car l;
- symbolic procedure tm_prunelhead(l, l1);
- if null l or null l1 then l else tm_prunelhead(cdr l, cdr l1);
- procedure tm_pruneltail(l,l1);
- reversip tm_prunelhead(reversip l,l1);
- procedure tm_pslp();
- 'psl memq lispsystem!*;
- if tm_pslp() then <<
- tm_switches!-this!-sl!* := {!*usermode};
- off1 'usermode
- >>;
- procedure tm_color(c);
- % Color prompt. This will handle EITHER an identifier OR a string, and
- % it returns the same sort of object. It wraps tm_bprompt() and
- % tm_eprompt() around the text it is passed.
- begin scalar ec, sf;
- if stringp c then <<
- ec := string!-to!-list c;
- sf := t >>
- else ec := explode2 c; % Original code has explode not explode2 here.
- ec := '! . ec; % add space
- if not !*promptnumbers then % strip numbers from prompt
- while memq(car ec,'(! !0 !1 !2 !3 !4 !5 !6 !7 !8 !9)) do
- ec := cdr ec;
- ec := append(tm_bprompt(), append(ec, tm_eprompt()));
- ec := list!-to!-string ec;
- if sf then return ec
- else return intern ec
- end;
-
- procedure tm_uncolor(c);
- % Uncolor prompt.
- begin scalar ec, sf;
- if stringp c then <<
- ec := string!-to!-list c;
- sf := t >>
- else ec := explode2 c; % cf explode?
- if not tm_coloredp ec then return c;
- ec := tm_prunelhead(ec, tm_bprompt());
- if car ec eq '! then ec := cdr ec; % strip space
- ec := tm_pruneltail(ec, tm_eprompt());
- ec := list!-to!-string ec;
- if sf then return ec
- else return intern ec
- end;
- procedure tm_setpchar!-psl(c);
- begin scalar w;
- w := tm_setpchar!-orig c;
- promptstring!* := tm_color promptstring!*;
- return tm_uncolor w
- end;
- !#if (memq 'csl lispsystem!*)
- switch redfront_mode;
- % I do not think there is any merit in even defining this if I am not
- % using CSL.
- procedure tm_setpchar!-csl(c);
- % With CSL in many cases the system does prompt colouring at a lower level
- % in the code, so the stuff here is not necessary. However if CSL is used
- % with an external redfront of texmacs interface I will want to activate
- % this special stuff. So I provide a switch redfront_mode that controls
- % what I do. I expect to run with this module loaded almost all of the time
- % which is why I want a control via switch rather than through just
- % "load tmprint". I note that if CSL is loaded from a script that attaches it
- % to redfront of som eother interface that the invocation can use
- % -D*redfront_mode
- % to preset the switch, which ought to be a small enough burden to be
- % tolerable!
- if !*redfront_mode or
- member('texmacs, lispsystem!*) then
- tm_uncolor tm_setpchar!-orig tm_color c
- else tm_setpchar!-orig c;
- !#endif
- copyd('tm_setpchar!-orig,'setpchar);
- if tm_pslp() then
- copyd('setpchar,'tm_setpchar!-psl)
- else
- copyd('setpchar,'tm_setpchar!-csl);
- procedure tm_yesp!-psl(u);
- begin scalar ifl,ofl,x,y;
- if ifl!* then <<
- ifl := ifl!* := {car ifl!*,cadr ifl!*,curline!*};
- rds nil
- >>;
- if ofl!* then <<
- ofl:= ofl!*;
- wrs nil
- >>;
- if null !*lessspace then
- terpri();
- if atom u then
- prin2 u
- else
- lpri u;
- if null !*lessspace then
- terpri();
- y := setpchar "?";
- x := yesp1();
- setpchar y;
- if ofl then wrs cdr ofl;
- if ifl then rds cadr ifl;
- cursym!* := '!*semicol!*;
- return x
- end;
- if tm_pslp() then <<
- remflag('(yesp),'lose);
- copyd('tm_yesp!-orig,'yesp);
- copyd('yesp,'tm_yesp!-psl);
- flag('(yesp),'lose)
- >>;
- % Color PSL prompts, in case user falls through:
- procedure tm_compute!-prompt!-string(count,level);
- tm_color tm_compute!-prompt!-string!-orig(count,level);
- if tm_pslp() then <<
- copyd('tm_compute!-prompt!-string!-orig,'compute!-prompt!-string);
- copyd('compute!-prompt!-string,'tm_compute!-prompt!-string)
- >>;
-
- procedure tm_break_prompt();
- <<
- prin2 "break["; prin2 breaklevel!*; prin2 "]";
- promptstring!* := tm_color promptstring!*
- >>;
- if tm_pslp() then <<
- remflag('(break_prompt),'lose);
- copyd('break_prompt,'tm_break_prompt);
- flag('(break_prompt),'lose);
- >>;
- if tm_pslp() then
- onoff('usermode,car tm_switches!-this!-sl!*);
- onoff('msg,car tm_switches!*);
- onoff('output,cadr tm_switches!*);
- crbuf!* := nil;
- inputbuflis!* := nil;
- lessspace!* := t;
- statcounter := 0;
- endmodule;
-
- end;
|