helphtml1.red 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. % helphtml.red
  2. %
  3. % interfacing reduce help file to HTML (world wide web)
  4. %
  5. % Author: Herbert Melenk, ZIB Berlin
  6. %
  7. % November 1992
  8. %
  9. % PSL dependent
  10. fluid '(outc newl par !*font !*newline !*html html_specials!* !*windows !*secondrun);
  11. fluid '(node_file_name!* current_base_dir !*directory_open CURRENT_NODE_NUMBER!*);
  12. !*HTML := t;
  13. !*windows := t;
  14. helvetica:= "R";
  15. courier:= "TT";
  16. !#if (member 'csl lispsystem!*)
  17. fluid '(root dest);
  18. symbolic procedure rootname();
  19. if boundp 'root and root then
  20. list!-to!-string explodec root
  21. else "r38";
  22. symbolic procedure dest_directory();
  23. if boundp 'dest and dest then
  24. list!-to!-string explodec dest
  25. else "../lisp/csl/r38.doc";
  26. !#else
  27. symbolic procedure rootname();
  28. getenv "package";
  29. symbolic procedure dest_directory();
  30. getenv "tdir";
  31. !#endif
  32. fluid '(node_file_labels filenumber indexfilename labels2nodes outname);
  33. filenumber:=0;
  34. symbolic procedure reset_html();
  35. <<
  36. indexfilename := make_html_file_name "index";
  37. filenumber := 0;
  38. >>;
  39. symbolic procedure html_open(u);
  40. myprin2(compress ('!" . ( '!< . append(explode2 u, '(!> !")) )) );
  41. symbolic procedure html_close(u);
  42. myprin2(compress ('!" . ( '!< . ( '!/ . append(explode2 u, '(!> !")) )) ));
  43. symbolic procedure open_current_base_dir u;
  44. % myprin2 " open_current_base_dir "; myprin2 u;
  45. nil;
  46. symbolic procedure close_current_base_dir ();
  47. % myprin2 " close_current_base_dir ";
  48. nil;
  49. symbolic procedure make_html_file_name u;
  50. begin scalar base,num;
  51. outname := nil;
  52. base := reversip explode2 rootname();
  53. while length base > 4 do base := cdr base;
  54. base := compress ('!" . reversip ('!" . base));
  55. !#if (member 'csl lispsystem!*)
  56. if u="main_index" then return "index.html"
  57. else if u="index" then return "r38_idx.html"
  58. else <<filenumber:=filenumber+1;
  59. num := compress('!" . append(cdr explode2
  60. (10000+filenumber),'(!")));
  61. outname := filenumber;
  62. >>;
  63. return bldmsg("%w_%w.html",base,num);
  64. !#else
  65. if u="main_index" then num:="_dir"
  66. else if u="index" then num:="_idx"
  67. else <<filenumber:=filenumber+1;
  68. num := compress('!" . append(cdr explode2
  69. (10000+filenumber),'(!")));
  70. >>;
  71. return bldmsg("%w%w.html",base,num);
  72. !#endif
  73. end;
  74. symbolic procedure open_node_file u;
  75. begin scalar dir,name;
  76. dir:=if (dir:=dest_directory()) then bldmsg("%w/",dir) else "";
  77. name := node_file_name!* := make_html_file_name u;
  78. labels2nodes := (name . u) . labels2nodes;
  79. % non-unix and PSL: open with suffix "htm".
  80. if not member('unix,lispsystem!*) and member('psl, lispsystem!*) then
  81. name:= compress ('!" . reversip('!" . cdr reversip explode2 name));
  82. if null outname or outname<2 or remainder(outname, 50)=0 then <<
  83. if outfile!* then close outfile!*;
  84. outfile!* := open(bldmsg("%w%w",dir,name), 'output) >>;
  85. return outfile!*;
  86. end;
  87. symbolic procedure close_node_file ();
  88. %if outfile!* then << close outfile!*; outfile!* := nil;
  89. % node_file_name!* := nil;
  90. % >>;
  91. nil;
  92. symbolic procedure node_file_name(); node_file_name!*;
  93. symbolic procedure initoutput (); nil;
  94. symbolic procedure endoutput(); nil;
  95. symbolic procedure verbatim u;
  96. !*verbatim := u;
  97. symbolic procedure newfont(f);
  98. if currentfont neq f then
  99. <<fontoff(); currentfont:=f; fonton()>>;
  100. symbolic procedure fontoff();
  101. <<% if !*font then channelprin2(outfile!*,"}");
  102. outc:=nil;
  103. !*font:=nil>>;
  104. symbolic procedure fonton();
  105. <<if not !*font then
  106. <<% channelprintf(outfile!*,"{\%w ",currentfont); outc := nil
  107. >>;
  108. !*font:=t>>;
  109. symbolic procedure myprin2 u;
  110. <<!*newline:=nil; channelprin2(outfile!*,u)>>;
  111. deflist( '((!< "&lt;")
  112. (!> "&gt;")
  113. (!" "&quot;")
  114. (!& "&amp;")),
  115. 'HTML_Symbol_Name);
  116. html_specials!* := '(!< !> !" !&);
  117. symbolic procedure myprin2_protected u;
  118. <<if u memq html_specials!* then myprin2 get(u, 'HTML_Symbol_Name)
  119. else myprin2 u;
  120. u
  121. >>;
  122. fluid '(!*verbescape);
  123. symbolic procedure emit_start_verbatim();
  124. <<html_open "p"; html_open "pre"; html_open "tt">>;
  125. symbolic procedure emit_end_verbatim();
  126. <<html_close "tt"; html_close "pre"; html_open "p">> ;
  127. symbolic procedure verbprin2 u;
  128. if u = '!\ then << !*verbescape :=t>>
  129. else
  130. if u=!$eol!$ then << myterpri();!*verbescape := nil>>
  131. else
  132. if (u = '!&) then
  133. <<myprin2 " _ _ _ "; !*verbescape:=par:=newl:=outc:=nil>>
  134. else
  135. if u memq html_specials!* then
  136. <<if not !*verbescape then myprin2_protected u else myprin2 u;
  137. !*verbescape := nil>>
  138. else
  139. <<myprin2 u; !*verbescape := nil>>;
  140. symbolic procedure myterpri();
  141. channelterpri outfile!*;
  142. symbolic procedure number4out n;
  143. % print number with 4 digits.
  144. << if n<10 then textout "0";
  145. if n<100 then textout "0";
  146. if n<1000 then textout "0";
  147. textout n>>;
  148. % par = t: paragraph has been terminated - no new data so far
  149. % newl = t: last character has been an EOL
  150. symbolic procedure textout(u);
  151. if par and (u=!$eol!$ or u='! ) then nil else
  152. if stringp u then mapc(explode2 u, 'textout) else
  153. <<fonton();
  154. if u=!$eol!$ and (!*verbatim or newl)
  155. then <<print_newline();
  156. outc:='! ;
  157. if not !*verbatim then second_newline();
  158. newl:=nil;
  159. par:=t
  160. >>
  161. else
  162. if (u = '!&) then
  163. <<myprin2 " _ _ _ "; par:=newl:=outc:=nil>>
  164. else
  165. if (u = '!$) then
  166. newfont(if currentfont = helvetica then courier else helvetica)
  167. else
  168. if (u memq html_specials!*) then <<myprin2_protected u>> else
  169. if (u neq '! ) or (outc neq '! ) or !*verbatim
  170. then
  171. <<if u=!$eol!$ and outc neq '! then myprin2 '! ;
  172. myprin2(u); outc := u;
  173. if u=!$eol!$ then newl:=t else
  174. if u neq '! then newl:=nil;
  175. par:=nil;
  176. >>;
  177. >>;
  178. % -------- paragraph heading ---------------------------
  179. symbolic procedure par_heading(type);
  180. <<myprin2 " <P> <H3> ";
  181. verbprin2 !$eol!$;
  182. for each x in explode type do verbprin2 x;
  183. verbprin2 ": </H3>";
  184. verbprin2 !$eol!$;
  185. >>;
  186. % -------- directory structure -------------------------
  187. symbolic procedure base_new_dir(name);
  188. <<
  189. close_current_base_dir();
  190. open_current_base_dir name;
  191. current_base_dir := name>>;
  192. symbolic procedure emit_dir_new();
  193. nil;
  194. symbolic procedure emit_dir_key u;
  195. emit_node_key u;
  196. symbolic procedure emit_dir_separator();
  197. emit_node_separator();
  198. symbolic procedure emit_dir_label u;
  199. emit_node_label u;
  200. symbolic procedure emit_dir_title u;
  201. emit_node_title(u,nil,'section);
  202. symbolic procedure emit_dir_browse(u,n);
  203. emit_node_browse(u,n);
  204. % ---- node structure
  205. symbolic procedure emit_node_separator();
  206. <<fonton();
  207. if !*directory_open then <<html_close "menu" ;
  208. !*directory_open := nil>>;
  209. %myterpri(); myterpri();
  210. %channelprin2(outfile!*,"emit_node_separator");
  211. %myterpri(); myterpri();
  212. outc:='! ; par:=t;
  213. close_node_file();
  214. >>;
  215. symbolic procedure set_tab(); nil;
  216. % myprin2 "set_tab ";
  217. symbolic procedure release_tab(); nil;
  218. % myprin2 "release_tab ";
  219. symbolic procedure textout_name(l);
  220. % l is a list of characters to be printed.
  221. % special action for names: \ in front of _ suppressed because
  222. % of Microsoft HC logic (don't know why).
  223. if atom l then textout l else
  224. while l do
  225. <<if not(car l = '!\) or null cdr l or not(cadr l = '!_)
  226. then textout car l;
  227. l := cdr l>>;
  228. symbolic procedure textout2(l);
  229. if l then
  230. if atom l then myprin2 l else
  231. for each x in l do myprin2
  232. if x='! then '!_ else x;
  233. symbolic procedure printem(s);
  234. % print italic
  235. begin
  236. html_open "em";
  237. mapc(s,'myprin2);
  238. html_close "em";
  239. end;
  240. symbolic procedure printem(s);
  241. begin
  242. fontoff();
  243. html_open "em";
  244. mapc(s,'myprin2_protected);
  245. html_close "em";
  246. end;
  247. symbolic procedure printref u;
  248. begin scalar r,s;
  249. % print ( ">>>" . u);
  250. r:= get_label u;
  251. % s := assoc (u,node_file_labels);
  252. s := assoc (r,node_file_labels);
  253. if null s then s := assoc(append(r, '(!_ !s !w !i !t !c !h)), node_file_labels);
  254. if null s then s := assoc(append(r, '(!_ !c !o !m !m !a !n !d)), node_file_labels);
  255. if null s then s := assoc(append(r, '(!_ !v !a !r !i !a !b !l !e)), node_file_labels);
  256. if null s then s := assoc(append(r, '(!_ !o !p !e !r !a !t !o !r)), node_file_labels);
  257. if null s then s := assoc(append(r, '(!_ !d !e !c !l !a !r !a !t !i !o !n)), node_file_labels);
  258. if null s then s := assoc(append(r, '(!_ !c !o !n !s !t !a !n !t)), node_file_labels);
  259. if null s then s := assoc(append(r, '(!_ !t !y !p !e)), node_file_labels);
  260. if null s then s := assoc(append(r, '(!_ !c !o !n !c !e !p !t)), node_file_labels);
  261. if null s then s := assoc(append(r, '(!_ !p !a !c !k !a !g !e)), node_file_labels);
  262. if null s then s := assoc(append(r, '(!_ !i !n !t !r !o !d !u !c !t !i !o !n)), node_file_labels);
  263. if s then s := cdr s;
  264. if null r then return printem u;
  265. fontoff();
  266. myterpri();
  267. if null s then <<
  268. wrs nil;
  269. printc "*** missing cross-reference ***";
  270. princ "u = "; print u;
  271. princ "r = "; print r;
  272. princ "s = "; print s;
  273. princ "assoc(u,..) = ", print assoc(u, node_file_labels);
  274. printc "node_file_labels = ";
  275. for each w in node_file_labels do <<
  276. princ " "; prin car w; ttab 30; print cdr w >>;
  277. printc "*** stopping ***";
  278. stop 0 >>;
  279. myprin2 "<a href="; refout s;
  280. myprin2 ">";
  281. mapc(u,'myprin2); html_close "a";
  282. end;
  283. symbolic procedure printnameref u;
  284. printref u;
  285. fluid '(key_database);
  286. symbolic procedure emit_node_keys u;
  287. begin scalar keys;
  288. keys := assoc(u,key_database);
  289. if null keys then return;
  290. keys := cdr keys;
  291. fonton();
  292. myterpri();
  293. while keys do
  294. <<
  295. node_file_labels := ( car keys . node_file_name!*) . node_file_labels;
  296. keys:= cdr keys;
  297. >>;
  298. myterpri();
  299. end;
  300. symbolic procedure emit_node_key u;
  301. emit_hidden_node_key u;
  302. symbolic procedure emit_hidden_node_key u;
  303. if current_node!* then
  304. begin scalar q;
  305. q:= assoc(current_node!*,key_database);
  306. if null q then
  307. key_database := (current_node!* . {u}).key_database
  308. else
  309. if not member(u,cdr q) then cdr q:=u.cdr q;
  310. end;
  311. symbolic procedure remove_html x;
  312. compress reverse cdddr cddr reverse explodec x;
  313. symbolic procedure emit_node_label u;
  314. <<open_node_file u;
  315. fonton();
  316. myterpri();
  317. myprin2 "<a name=";
  318. %textout_name u; % ACN
  319. myprin2 remove_html node_file_name!*; % ACN
  320. myprin2 ">";
  321. myterpri();
  322. node_file_labels := ( u . node_file_name!* ) . node_file_labels;
  323. >>;
  324. symbolic procedure emit_node_title(u,dummy,type);
  325. <<fonton();
  326. myterpri();
  327. html_open "title";
  328. textout_name u;
  329. html_close "title";
  330. html_close "a"; % from emit_node_label
  331. myterpri();
  332. % The next 2 lines are from JPFF and add in a Reduce logo on each page.
  333. % seems a neat idea!
  334. channelprintf(outfile!*,"<p align=""centre""><img src=""redlogo.gif"" width=621 height=60 border=0 alt=""REDUCE""></p>");
  335. myterpri();
  336. channelprintf(outfile!*,"<b><a href=%w>INDEX</a></b><p><p>%n",indexfilename);
  337. >>;
  338. symbolic procedure emit_node_browse(u,n);
  339. <<fonton();
  340. current_node_number!* := n;
  341. node_file_labels := ( u . node_file_name!* ) . node_file_labels;
  342. >>;
  343. symbolic procedure print_bold u;
  344. <<fontoff();
  345. html_open "b";
  346. mapc(u,'myprin2);
  347. html_close "b";
  348. >>;
  349. symbolic procedure emit_dir_header();
  350. <<
  351. fontoff();
  352. html_open "menu";
  353. !*directory_open := t;
  354. myterpri();
  355. >>;
  356. symbolic procedure dig4 n;
  357. compress ('!" . append(cdr explodec (10000+n), '(!")));
  358. symbolic procedure refout x;
  359. begin
  360. % input is eg r38_1234.html
  361. % desired output = r38_1200.html#r38_1234
  362. scalar num, num50;
  363. num := cddddr explodec x;
  364. num := compress reverse cddr cdddr reverse num;
  365. num50 := num - (remainder(num, 50));
  366. if num50=0 then num50 := 1;
  367. myprin2 "r38_"; myprin2 dig4 num50; myprin2 ".html#r38_";
  368. myprin2 dig4 num
  369. end;
  370. symbolic procedure emit_dir_entry(name,lab);
  371. begin scalar alias, s;
  372. s:= assoc(lab,node_file_labels); if s then s := cdr s;
  373. fontoff();
  374. if null s then error(0, "emit_dir_entry" . name . lab);
  375. html_open "li"; myprin2 "<a href=";
  376. refout s;
  377. myprin2 ">";
  378. mapc(name,'myprin2);
  379. html_close "a";
  380. % myterpri();
  381. % myprin2 "{\v\f2 ";
  382. if (alias:=assoc(lab,aliases)) then
  383. <<myprin2 "alias= "; myprin2 cdr alias>>;
  384. % myprin2 " ENDemit_dir_entry";
  385. print_newline();
  386. end;
  387. symbolic procedure print_newline();
  388. <<if null !*newline then
  389. <<fonton(); channelprin2(outfile!*,"<P>"); channelterpri outfile!*>>;
  390. !*newline:=t
  391. >>;
  392. symbolic procedure second_newline();
  393. <<!*newline :=nil; print_newline()>>;
  394. symbolic procedure print_tab ();
  395. <<fonton(); myprin2 " _ _ _ ">>;
  396. %------------------- HTML index file --------------------------------
  397. symbolic procedure html_indexfile();
  398. begin scalar u,v,q,r,s,rr,!*lower;
  399. prin2t "..... compiling html index file";
  400. s := for each q in node_file_labels join
  401. if pairp car q then {sort_term car q . q};
  402. s := sort(s,'html_indexfile_sort);
  403. % remove trivial entries
  404. r:=s;
  405. while r do
  406. <<u:=car r; r:=cdr r;
  407. if car u member
  408. '((c o m m a n d)
  409. (c o n c e p t)
  410. (c o n s t a n t)
  411. (d e c l a r a t i o n)
  412. (i n t r o d u c t i o n)
  413. (o p e r a t o r)
  414. (p a c k a g e)
  415. (s w i t c h)
  416. (v a r i a b l e)
  417. )
  418. then s:=deletip(u,s);
  419. >>;
  420. % remove duplicates
  421. r:=s;
  422. while r and cdr r do
  423. <<u:=car r; rr:=r:=cdr r;
  424. while rr and html_indexfile_subsetp(car u,car (v:=car rr)) do
  425. <<if cddr u = cddr v then s:=deletip(u,s); rr:=cdr rr>>;
  426. >>;
  427. open_node_file "index";
  428. channelprintf(outfile!*, "<title>%w search index</title>%n",rootname());
  429. % channelprintf(outfile!*, "<dl compact><isindex>%n");
  430. channelprintf(outfile!*, "<dl compact>%n");
  431. % JPFF: add logo
  432. channelprintf(outfile!*, "<p align=""center""><img src=""redlogo.gif"" width=621 height=60 border=0 alt=""REDUCE""></p>");
  433. myterpri();
  434. channelprintf(outfile!*, "<menu>%n");
  435. for each x in s do
  436. <<channelprin2(outfile!*, "<dt>");
  437. for each c in cadr x do
  438. if c='!_ then channelprin2(outfile!*," ") else
  439. if not(c='!\) then channelprin2(outfile!*,c);
  440. channelprintf(outfile!*, ": <a href="); refout cddr x; myprin2 ">";
  441. q := cdr assoc(cddr x,labels2nodes);
  442. for each c in q do
  443. if c='!_ then channelprin2(outfile!*," ") else
  444. if not(c='!\) then channelprin2(outfile!*,c);
  445. channelprin2t(outfile!*, "</a>");
  446. >>;
  447. channelprintf(outfile!*, "</menu>%n");
  448. close outfile!*;
  449. outfile!* := nil;
  450. end;
  451. symbolic procedure sort_term u;
  452. for each c in raisestring u join
  453. if liter c or digit c then {c};
  454. symbolic procedure html_indexfile_sort(u,v);
  455. html_indexfile_sort1(car u,car v);
  456. symbolic procedure html_indexfile_sort1(u,v);
  457. if null u then t else
  458. if null v then nil else
  459. if car u = car v then html_indexfile_sort1(cdr u,cdr v) else
  460. id2int car u < id2int car v;
  461. symbolic procedure html_indexfile_subsetp(a,b);
  462. null a or
  463. b and car a = car b and html_indexfile_subsetp(cdr a,cdr b);
  464. %------------------- LISP index file --------------------------------
  465. symbolic procedure LISP_indexfile();
  466. begin scalar u,v,q,r,s,rr,!*lower,pack;
  467. prin2t "..... compiling independent index file";
  468. pack := rootname();
  469. s := for each q in node_file_labels join
  470. if pairp car q then {sort_term car q . q};
  471. s := sort(s,'html_indexfile_sort);
  472. % remove trivial entries
  473. r:=s;
  474. while r do
  475. <<u:=car r; r:=cdr r;
  476. if car u member
  477. '((c o m m a n d)
  478. (c o n c e p t)
  479. (c o n s t a n t)
  480. (d e c l a r a t i o n)
  481. (i n t r o d u c t i o n)
  482. (o p e r a t o r)
  483. (p a c k a g e)
  484. (s w i t c h)
  485. (v a r i a b l e)
  486. )
  487. then s:=deletip(u,s);
  488. >>;
  489. % remove duplicates
  490. r:=s;
  491. while r and cdr r do
  492. <<u:=car r; rr:=r:=cdr r;
  493. while rr and html_indexfile_subsetp(car u,car (v:=car rr)) do
  494. <<if cddr u = cddr v then s:=deletip(u,s); rr:=cdr rr>>;
  495. >>;
  496. outfile!*:= open(bldmsg("%w.hdx",pack),'output);
  497. channelprintf(outfile!*, "%w generated from reference manual >%w< %n",'!%,pack);
  498. channelprintf(outfile!*, "%w (node text description status details) %n",'!%,pack);
  499. for each x in s do
  500. <<channelprin2(outfile!*, "(");
  501. q := cdr assoc(cddr x,labels2nodes);
  502. for each c in q do
  503. if not(c='!\) then
  504. <<c:=id2int c;
  505. if c> 64 and c<91 then c:=c+32;
  506. channelprin2(outfile!*,int2id c)>>;
  507. channelprin2(outfile!*,'! );
  508. channelprin2(outfile!*,'!");
  509. for each c in cadr x do
  510. if not(c='!\) then channelprin2(outfile!*,c);
  511. channelprin2(outfile!*,'!");
  512. channelprin2(outfile!*,'! );
  513. channelprintf(outfile!*," %w help nil)%n", pack);
  514. >>;
  515. close outfile!*;
  516. outfile!*:=nil;
  517. end;
  518. %------------------- printstruct -------------------------------
  519. symbolic procedure printstruct();
  520. <<terpri(); printstruct1(car record,1)>>;
  521. symbolic procedure printstruct1(r,n);
  522. <<for i:=1:n do prin2 " ";
  523. mapc(name r,'prin2);
  524. terpri();
  525. for each x in reverse seq r do
  526. printstruct1(nil . x,n+1);
  527. >>;
  528. end;