htmlhelp1.red 18 KB

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