rlfi.red 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  1. %***********************************************************************
  2. %***** ******
  3. %***** M O D U L E R L F I Ver. 1.1 27/05/1991 ******
  4. %***** Ver. 1.01 17/11/1989 ******
  5. %***** ******
  6. %***********************************************************************
  7. %***** Program for LATEX syntax of REDUCE output formulas, ******
  8. %***** to activate it, turn the LATEX switch ON. ******
  9. %***** Program can be used only on systems supporting lower ******
  10. %***** case characters through OFF RAISE. ******
  11. %***********************************************************************
  12. module rlfi;
  13. % Author: Richard Liska
  14. % Faculty of Nuclear Sciences and Physical Engineering
  15. % Czech Technical University in Prague
  16. % Brehova 7, 115 19 Prague 1, Czechoslovakia
  17. % E-mail: tjerl@cspuni12.bitnet (EARN)
  18. % Program RLFI, Version REDUCE 3.4 05/1991
  19. symbolic;
  20. % Global variables and their default values
  21. global '(mstyle!* nochar1!* laline!* ncharspr!* mstyles!*);
  22. nochar1!*:=nil; % List of identifiers longer than one character
  23. laline!*:=72; % Linelength of output file
  24. ncharspr!*:=0; % Position on output line
  25. off raise;
  26. MSTYLE!*:='displaymath; % Default mathematical style
  27. MSTYLES!*:= '(math displaymath equation); % Possible math. styles
  28. % Declaration of symbols and operators for LaTeX
  29. FLAG('(alpha beta gamma delta epsilon varepsilon zeta eta theta vartheta
  30. iota kappa lambda mu nu xi pi varpi rho varrho sigma varsigma tau
  31. upsilon phi varphi chi psi omega Gamma Delta Theta Lambda Xi Pi
  32. Sigma Upsilon Phi Psi Omega infty hbar nabla perp),'SYMBOL);
  33. FLAG('(hat check breve acute grave tilde bar vec dot ddot),'ACCDEF);
  34. DEFLIST('((bold !{!\bf! )(roman !{!\rm! )),'FONTDEF);
  35. DEFLIST('((!( !\left!()(!) !\right!))(PI !\pi! )(pi !\pi! )),'NAME);
  36. DEFLIST('((TIMES ! )(SETQ !=)(GEQ !\geq! )(LEQ !\leq! )),'LAPR);
  37. DEFLIST('((SIN !\sin)(sin !\sin)(COS !\cos)(cos !\cos)(TAN !\tan)
  38. (tan !\tan)(COT !\cot)(cot !\cot)(ASIN !\arcsin)
  39. (asin !\arcsin)(ACOS !\arccos) (acos !\arccos)(ATAN !\arctan)
  40. (atan !\arctan)(EXP !\exp)(exp !\exp) (LOG !\ln)(log !\log)
  41. (ln !\ln)(SUM !\sum)(PRODUCT !\prod)),'LAPOP);
  42. ON RAISE;
  43. symbolic procedure get!*(u,v);
  44. if numberp u then nil else get(u,v);
  45. fluid '(!*latex !*lasimp !*verbatim !*!*a2sfn);
  46. switch latex,lasimp,verbatim;
  47. !*lasimp := !*verbatim := t;
  48. symbolic put('latex,'simpfg,'((t (latexon)) (nil(latexoff)) ));
  49. symbolic put('verbatim,'simpfg,'((t (verbatimon)) (nil (verbatimoff))));
  50. symbolic procedure latexon;
  51. % Procedure called after ON LATEX
  52. <<!*!*a2sfn:='texaeval;
  53. !*raise:=nil;
  54. prin2t "\documentstyle{article}";
  55. prin2t "\begin{document}";
  56. if !*verbatim then prin2t "\begin{verbatim}";
  57. put('tex,'rtypefn,'(lambda(x) 'tex)) >>;
  58. symbolic procedure latexoff;
  59. % Procedure called after OFF LATEX
  60. <<!*!*a2sfn:='aeval;
  61. !*raise:=t;
  62. remprop('tex,'rtypefn);
  63. if !*verbatim then
  64. <<terpri();
  65. prin2t "\end{verbatim}" >>;
  66. prin2t "\end{document}";
  67. rmsubs() >>;
  68. procedure verbatimon;
  69. <<if !*latex and null !*verbatim then prin2t "\begin{verbatim}";
  70. !*echo:=t>>;
  71. procedure verbatimoff;
  72. <<if !*latex and !*verbatim then
  73. <<terpri();
  74. prin2t "\end{verbatim}">>;
  75. !*echo:=nil >>;
  76. symbolic procedure texaeval u;
  77. % Procedure replaces the AEVAL procedure in the LATEX mode
  78. if !*lasimp then list('tex,aeval u)
  79. else list('tex,u);
  80. % deklarace latex modu;
  81. put('tex,'tag,'tex);
  82. put('tex,'simpfn,'simp);
  83. put('tex,'typeletfn,'texlet);
  84. put('tex,'prifn,'latexprint);
  85. put('tex,'setprifn,'setlaprin);
  86. flag('(tex),'sprifn);
  87. symbolic procedure texlet(u,v,tu,b,tv);
  88. % Assignment procedure for LATEX mode
  89. % !!! match can be evaluated like let!!!!;
  90. if eqcar(v,'tex) then let2(u,cadr v,nil,b)
  91. else msgpri(" value for ",u," not assigned ",v,nil);
  92. symbolic procedure latexprint u;
  93. % Prints expression U in the LaTeX syntax
  94. <<prinlabegin();
  95. latexprin u;
  96. prinlaend() >>;
  97. symbolic procedure setlaprin(u,v);
  98. % Prints assignment command in LaTeX syntax
  99. <<prinlabegin();
  100. latexprin u;
  101. oprinla 'setq;
  102. latexprin v;
  103. prinlaend() >>;
  104. symbolic procedure mathstyle u;
  105. % Defines the output mathematical style
  106. if car u memq mstyles!* then <<mstyle!*:=car u;nil>>
  107. else msgpri(" mathematical style ",car u," not supported ",nil,nil);
  108. put('mathstyle,'stat,'rlis);
  109. symbolic procedure prinlabegin;
  110. % Initializes the output
  111. <<if !*verbatim then
  112. <<terpri();
  113. prin2t "\end{verbatim}">>;
  114. prin2 "\begin{";
  115. prin2 mstyle!*;
  116. prin2t "}" >>;
  117. symbolic procedure prinlaend;
  118. % Ends the output of one expression
  119. <<terpri();
  120. prin2 "\end{";
  121. prin2 mstyle!*;
  122. prin2t "}";
  123. if !*verbatim then prin2t "\begin{verbatim}";
  124. ncharspr!*:=0;
  125. if nochar1!*
  126. then msgpri(" Longer than one character identifiers used ",
  127. nil,nochar1!*,nil,nil);
  128. nochar1!*:=nil >>;
  129. symbolic procedure latexprin u;
  130. % Prints expression U in the LaTeX syntax
  131. if eqcar(u,'tex) then maprintla(cadr u,0)
  132. else maprintla(u,0);
  133. symbolic procedure texprla(u,p);
  134. maprintla(car u,p);
  135. put('tex,'laprifn,'texprla);
  136. symbolic procedure maprintla(l,p);
  137. % L is printed expression, P is the infix precedence of infix operator
  138. % Procedure is similar to that one in the REDUCE source
  139. begin
  140. scalar x;
  141. if null l then return nil
  142. else if numberp l then go to c
  143. else if atom l then return prinlatom l
  144. else if stringp l then return prin2la l
  145. else if not atom car l then return maprintla(car l,p)
  146. else if (x:=get(car l,'laprifn)) and
  147. ((not flagp(car l,'fulla)
  148. and not (apply(x,list(cdr l,p)) eq 'failed))
  149. or (flagp(car l,'fulla) and not(apply(x,list(l,p)) eq 'failed)))
  150. then return l
  151. else if (x:=get(car l,'indexed)) then return prinidop(car l,cdr l,x)
  152. else if x:=get(car l,'infix) then go to a;
  153. oprinla(car l);
  154. prinpopargs(car l,cdr l,p);
  155. return l;
  156. a:p:=x>p;
  157. if null p and car l eq 'equal then p:=t;
  158. if p then go to b;
  159. prinlatom '!(;
  160. b:inprinla(car l,x,cdr l);
  161. if p then return l;
  162. prinlatom '!);
  163. return l;
  164. c:if not l<0 or p<get('minus,'infix) then return prin2la l;
  165. prin2la '!(;
  166. prin2la l;
  167. prin2la '!);
  168. return l
  169. end;
  170. symbolic procedure prinpopargs(op,args,p);
  171. % Prints argument(s) of prefix operator, decides if arg(s) will be
  172. % enclosed in parantheses
  173. begin
  174. scalar x;
  175. x:=null args or cdr args or not atom car args;
  176. % x:=x or null get(op,'lapop);
  177. if x then prinlatom '!( else prin2la "\,";
  178. if args then inprinla('!*comma!*,0,args);
  179. if x then prinlatom '!);
  180. if null x and p=get('times,'infix) then prin2la "\:";
  181. return args
  182. end;
  183. symbolic procedure prinlatom u;
  184. % Prints atom or the symbol associated to the atom in given font
  185. % and with given accent
  186. begin
  187. scalar n,f,a;
  188. if f:=get(u,'font) then prin2la f;
  189. if a:=get(u,'accent) then prin2la a;
  190. if n:=get(u,'name) then prin2la n
  191. else prin2la testchar1 u;
  192. if a then prin2la "}";
  193. if f then prin2la "}";
  194. return u
  195. end;
  196. symbolic procedure defid u;
  197. % Defines the statement DEFID for defining symbol, font and accent
  198. % associated to given atom
  199. begin
  200. scalar at,x,y;
  201. at:=car u;
  202. if not atom at or null car u then go to er;
  203. a:u:=cdr u;
  204. x:=car u;
  205. if eqcar(x,'equal) then x:=cdr x
  206. else go to er;
  207. if car x eq 'name then
  208. if flagp(cadr x,'symbol)
  209. then put(at,'name,incompe3('!\,cadr x,'! ))
  210. else put(at,'name,testchar1 cadr x)
  211. else if car x eq 'font then
  212. if y:=get(cadr x,'fontdef) then put(at,'font,y)
  213. else go to er
  214. else if car x eq 'accent then
  215. if flagp(cadr x,'accdef)
  216. then put(at,'accent,incompe3('!\,cadr x,'!{))
  217. else go to er
  218. else go to er;
  219. if cdr u then go to a;
  220. return nil;
  221. er:lprie(" Syntax error ")
  222. end;
  223. put('defid,'stat,'rlis);
  224. symbolic procedure incompe3(a,b,c);
  225. % Constructs new atom by concatenating A,B,C
  226. intern compress append(explode a,append(explode b,explode c));
  227. symbolic procedure testchar1 u;
  228. % Checks if U has only one character
  229. if fixp u then u
  230. else if null cdr explode2 u then u
  231. else if member(u,nochar1!*) then u
  232. else <<nochar1!*:=u . nochar1!*; u>>;
  233. symbolic procedure inprinla(op,p,l);
  234. % Prints infix operator OP with arguments in the list L
  235. begin
  236. if get(op,'alt) then go to a;
  237. maprintla(car l,p);
  238. a0:l:=cdr l;
  239. a:if null l then return nil
  240. else if atom car l or not(op eq get!*(caar l,'alt)) then
  241. <<oprinla op;
  242. maprintla(negnumberchk car l,p)>>
  243. else maprintla(car l,p);
  244. go to a0;
  245. end;
  246. symbolic procedure oprinla op;
  247. % Prints operator OP
  248. begin
  249. scalar x;
  250. if x:=get(op,'lapr) then prin2la x
  251. else if x:=get(op,'prtch) then prin2la x
  252. else if x:=get(op,'lapop) then <<prin2la x; prin2la '! >>
  253. else prinlatom op
  254. end;
  255. % Definition of new operator of division --> horizontal division line
  256. newtok '((!\) backslash);
  257. deflist('((backslash recip)),'unary);
  258. algebraic infix \;
  259. precedence 'backslash,'quotient;
  260. put('backslash,'simpfn,'simpiden);
  261. symbolic procedure prin2la u;
  262. % Prints atom or string U, checks the length of line
  263. begin
  264. scalar l;
  265. l:=lengthc u;
  266. if ncharspr!* + l > laline!* then <<terpri(); ncharspr!*:=0 >>;
  267. prin2 u;
  268. ncharspr!*:=ncharspr!* + l
  269. end;
  270. symbolic procedure prinfrac(l,p);
  271. % Prints the fraction with horizontal division line
  272. <<prin2la "\frac{";
  273. maprintla(car l,0);
  274. prin2la "}{";
  275. maprintla(cadr l,0);
  276. prin2la "}" >>;
  277. put('backslash,'laprifn,'prinfrac);
  278. symbolic procedure defindex u;
  279. % Defines the placing of indices of an operator
  280. for each a in u do defindex1 a;
  281. put('defindex,'stat,'rlis);
  282. symbolic procedure defindex1 u;
  283. begin
  284. scalar at,x;
  285. at:=car u;
  286. for each a in cdr u do if not a memq '(arg up down leftup leftdown)
  287. then x:=t;
  288. if not atom at or null cdr u then x:=t;
  289. return if x then msgpri(" Syntax error ",u,nil,nil,'hold)
  290. else put(at,'indexed,cdr u)
  291. end;
  292. symbolic procedure prinidop(op,args,mask);
  293. % Prints operator with indices. MASK describe the place of indices
  294. begin
  295. scalar arg,up,down,lup,ldown;
  296. if null args then return prinlatom op;
  297. a:if car mask eq 'arg then arg:=car args . arg
  298. else if car mask eq 'up then up:=car args . up
  299. else if car mask eq 'down then down:=car args . down
  300. else if car mask eq 'leftup then lup:=car args . lup
  301. else if car mask eq 'leftdown then ldown:=car args . ldown;
  302. mask:=cdr mask;
  303. args:=cdr args;
  304. if mask and args then go to a;
  305. mask:='(arg);
  306. if args then go to a;
  307. arg:=reverse arg;
  308. up:=reverse up;
  309. down:=reverse down;
  310. lup:=reverse lup;
  311. ldown:=reverse ldown;
  312. if lup or ldown then prin2la "\:";
  313. if lup then
  314. <<prin2la '!^!{;
  315. prinindexs lup;
  316. prin2la "}" >>;
  317. if ldown then
  318. <<prin2la "_{";
  319. prinindexs ldown;
  320. prin2la "}" >>;
  321. prinlatom op;
  322. if up then
  323. <<prin2la '!^!{;
  324. prinindexs up;
  325. prin2la "}" >>;
  326. if down then
  327. <<prin2la "_{";
  328. prinindexs down;
  329. prin2la "}" >>;
  330. if arg then
  331. <<prinlatom '!(;
  332. inprinla('!*comma!*,0,arg);
  333. prinlatom '!) >>;
  334. return op
  335. end;
  336. symbolic procedure prinindexs ndxs;
  337. % Prints indexces NDXS, if all indices are atoms prints them withouth
  338. % separating commas
  339. begin
  340. scalar b;
  341. for each a in ndxs do if not atom a then b:=t;
  342. if not b then for each a in ndxs do prinlatom a
  343. else inprinla('!*comma!*,0,ndxs)
  344. end;
  345. symbolic procedure exptprla(args,p);
  346. % Prints powers
  347. begin
  348. scalar arg,exp,ilist;
  349. arg:=car args;
  350. exp:=cadr args;
  351. if not atom exp and car exp eq 'quotient and cadr exp = 1
  352. and atom caddr exp
  353. then if caddr exp = 2 then
  354. <<prin2la "\sqrt{";
  355. maprintla(arg,0);
  356. prin2la "}" >>
  357. else
  358. <<prin2la "\sqrt[";
  359. prinlatom caddr exp;
  360. prin2la "]{";
  361. maprintla(arg,0);
  362. prin2la "}" >>
  363. else if atom arg then
  364. <<prinlatom arg;
  365. prin2la '!^!{;
  366. maprintla(exp,0);
  367. prin2la "}" >>
  368. else if atom car arg and not (ilist:=get(car arg,'indexed)) and
  369. not get(car arg,'laprifn) and
  370. not get(car arg,'infix) and atom exp then
  371. <<oprinla car arg;
  372. prin2la '!^!{;
  373. prinlatom exp;
  374. prin2la "}";
  375. prinpopargs(car arg,cdr arg,p) >>
  376. else if atom car arg and (ilist:=get(car arg,'indexed)) and
  377. not memq('up,ilist) then
  378. <<maprintla(arg,0);
  379. prin2la '!^!{;
  380. maprintla(exp,0);
  381. prin2la '!} >>
  382. else
  383. <<prinlatom '!(;
  384. maprintla(arg,0);
  385. prinlatom '!);
  386. prin2la '!^!{;
  387. maprintla(exp,0);
  388. prin2la "}" >>;
  389. return args
  390. end;
  391. put('expt,'laprifn,'exptprla);
  392. procedure sqrtprla(arg,p);
  393. % Prints square root
  394. <<prin2la "\sqrt {";
  395. maprintla(car arg,0);
  396. prin2la "}" >>;
  397. put('sqrt,'laprifn,'sqrtprla);
  398. symbolic procedure intprla(args,p);
  399. % Prints indefinite itegral
  400. begin
  401. scalar arg,var;
  402. if null args or null cdr args or not atom cadr args
  403. then return 'failed;
  404. arg:=car args;
  405. var:=cadr args;
  406. prin2la "\int ";
  407. maprintla(arg,0);
  408. prin2la "\:d\,";
  409. prinlatom var;
  410. return args
  411. end;
  412. put('int,'laprifn,'intprla);
  413. symbolic procedure dintprla(args,p);
  414. % Prints definite integral
  415. begin
  416. scalar down,up,arg,var;
  417. if null args or null cdr args or null cddr args or null cdddr args or
  418. not atom (var:=cadddr args) then return 'failed;
  419. down:=car args;
  420. up:=cadr args;
  421. arg:=caddr args;
  422. prin2la "\int_{";
  423. maprintla(down,0);
  424. prin2la '!}!^!{;
  425. maprintla(up,0);
  426. prin2la "}";
  427. maprintla(arg,0);
  428. prin2la "\:d\,";
  429. prinlatom var;
  430. return args
  431. end;
  432. put('dint,'laprifn,'dintprla);
  433. symbolic procedure sumprla(ex,p);
  434. % Prints a sum
  435. begin
  436. scalar op,down,up,arg;
  437. if not get(op:=car ex,'lapop) or null cdr ex or null cddr ex
  438. or null cdddr ex
  439. then return 'failed;
  440. down:=cadr ex;
  441. up:=caddr ex;
  442. arg:=cadddr ex;
  443. oprinla op;
  444. if down then
  445. <<prin2la"_{";
  446. maprintla(down,0);
  447. prin2la "}" >>;
  448. if up then
  449. <<prin2la '!^!{;
  450. maprintla(up,0);
  451. prin2la "}" >>;
  452. maprintla(arg,get('times,'infix) - 1);
  453. return ex
  454. end;
  455. put('sum,'laprifn,'sumprla);
  456. put('product,'laprifn,'sumprla);
  457. flag('(sum product),'fulla);
  458. symbolic procedure sqprla(args,p);
  459. % Prints standard quotient
  460. maprintla(prepsq!* car args,p);
  461. put('!*sq,'laprifn,'sqprla);
  462. symbolic procedure dfprla(dfex,p);
  463. % Prints derivaves
  464. begin
  465. scalar op,ord,arg,x,argup;
  466. op:=get(car dfex,'lapop);
  467. arg:=cadr dfex;
  468. dfex:=cddr dfex;
  469. x:=dfex;
  470. ord:=0;
  471. a:if null cdr x then
  472. <<x:=cdr x;
  473. ord:=ord+1 >>
  474. else if fixp cadr x then
  475. <<ord:=ord+cadr x;
  476. x:=cddr x >>
  477. else
  478. <<x:=cdr x;
  479. ord:=ord+1 >>;
  480. if x then go to a;
  481. if atom arg or (not get(car arg,'infix) and not get(car arg,'laprifn))
  482. then argup:=t;
  483. prin2la "\frac{";
  484. prin2la op;
  485. if ord=1 then prin2la "\,"
  486. else
  487. <<prin2la '!^!{;
  488. prin2la ord;
  489. prin2la "}" >>;
  490. if argup then maprintla(arg,0);
  491. prin2la "}{";
  492. x:=dfex;
  493. b:if not atom car x and cdr x and fixp cadr x then prin2la "(";
  494. prin2la op;
  495. if null cdr x or not fixp cadr x then
  496. <<prin2la "\,";
  497. maprintla(car x,0);
  498. x:=cdr x >>
  499. else
  500. <<maprintla(car x,0);
  501. if not atom car x then prin2la ")";
  502. prin2la '!^!{;
  503. prin2la cadr x;
  504. prin2la "}";
  505. x:=cddr x >>;
  506. if x then go to b;
  507. prin2la "}";
  508. if null argup then maprintla(arg,get('quotient,'infix));
  509. return arg
  510. end;
  511. put('df,'laprifn,'dfprla);
  512. put('pdf,'laprifn,'dfprla);
  513. flag('(df pdf),'fulla);
  514. put('df,'lapop,"{\rm d}");
  515. put('pdf,'lapop,"\partial ");
  516. algebraic;
  517. operator pdf,dint,product;
  518. endmodule;
  519. end;