home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume26 / schemweb / part01 < prev    next >
Encoding:
Text File  |  1992-12-27  |  32.6 KB  |  980 lines

  1. Newsgroups: comp.sources.unix
  2. From: ramsdell@linus.mitre.org (John D. Ramsdell)
  3. Subject: v26i082: schemeweb - simple support for literate programming in Lisp, Part01/01
  4. Sender: unix-sources-moderator@pa.dec.com
  5. Approved: vixie@pa.dec.com
  6.  
  7. Submitted-By: ramsdell@linus.mitre.org (John D. Ramsdell)
  8. Posting-Number: Volume 26, Issue 82
  9. Archive-Name: schemeweb/part01
  10.  
  11. SchemeWEB---Simple support for literate programming in Lisp.
  12.  
  13. SchemeWEB is a Unix filter that translates SchemeWEB source into LaTeX
  14. source or Scheme source.  Originally developed for the Scheme dialect 
  15. of Lisp, it can easily be used with most other dialects.
  16.  
  17. SchemeWEB defines a new source file format in which source lines
  18. are divided into text and code.  Lines of code start with a line
  19. beginning with '(', and continue until the line that contains the
  20. matching ')'.  The text lines remain, and they are treated as
  21. comments.  If the first character of a text line is ';', it is
  22. stripped from the output.  This is provided for those who want to use
  23. an unmodified version of their Scheme system's LOAD.  When producing a
  24. document, both the text lines and the code lines are copied into the
  25. document source file, but the code lines are surrounded by a pair of
  26. formatting commands, as is comments beginning with ';' within code
  27. lines.  SchemeWEB is currently set up for use with LaTeX.
  28.  
  29. John D. Ramsdell
  30.  
  31. #! /bin/sh
  32. # This is a shell archive.  Remove anything before this line, then unpack
  33. # it by saving it into a file and typing "sh file".  To overwrite existing
  34. # files, type "sh file -c".  You can also feed this as standard input via
  35. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  36. # will see the following message at the end:
  37. #        "End of archive 1 (of 1)."
  38. # Contents:  MANIFEST Makefile README astyped.sty reader.sw sweb.c
  39. #   sweb.scm sweb.tex
  40. # Wrapped by vixie@cognition.pa.dec.com on Mon Dec 28 10:04:21 1992
  41. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  42. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  43.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  44. else
  45. echo shar: Extracting \"'MANIFEST'\" \(362 characters\)
  46. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  47. X   File Name        Archive #    Description
  48. X-----------------------------------------------------------
  49. X MANIFEST                   1    This shipping list
  50. X Makefile                   1    
  51. X README                     1    
  52. X astyped.sty                1    
  53. X reader.sw                  1    
  54. X sweb.c                     1    
  55. X sweb.scm                   1    
  56. X sweb.tex                   1    
  57. END_OF_FILE
  58. if test 362 -ne `wc -c <'MANIFEST'`; then
  59.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  60. fi
  61. # end of 'MANIFEST'
  62. fi
  63. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  64.   echo shar: Will not clobber existing file \"'Makefile'\"
  65. else
  66. echo shar: Extracting \"'Makefile'\" \(859 characters\)
  67. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  68. X# SchemeWEB Makefile 
  69. X# $Header: Makefile,v 1.1 90/07/12 08:57:32 ramsdell Exp $
  70. X
  71. CFLAGS        = -O
  72. X
  73. SRCS        = README Makefile astyped.sty sweb.c \
  74. X          sweb.scm sweb.tex reader.sw
  75. X
  76. CMDS        = sweave stangle
  77. X
  78. DOCS        = sweb.dvi reader.dvi
  79. X
  80. TEXSTY        = astyped.sty
  81. X
  82. X#DEST        = /usr/local/bin
  83. DEST        = $(HOME)/bin
  84. X
  85. X#TEXDEST    = /usr/local/lib/tex/inputs
  86. TEXDEST    = $(HOME)/tex/inputs
  87. X
  88. X# Generic rules
  89. X.SUFFIXES:    .dvi .tex .scm .sw
  90. X
  91. X.sw.dvi:
  92. X    make $*.tex && make $*.dvi
  93. X
  94. X.sw.tex:
  95. X    sweave $*.sw $*.tex
  96. X
  97. X.tex.dvi:
  98. X    latex $*
  99. X
  100. X.sw.scm:
  101. X    stangle $*.sw $*.scm
  102. X
  103. X# Generic commands.
  104. X
  105. all:    $(CMDS)
  106. X
  107. doc:    $(DOCS) $(CMDS)
  108. X
  109. install:    $(CMDS) $(TEXSTY)
  110. X    mv $(CMDS) $(DEST)
  111. X    cp $(TEXSTY) $(TEXDEST)
  112. X
  113. clean:
  114. X    -rm $(CMDS)
  115. X
  116. dist:    schemeweb.sh
  117. X
  118. X# Specific commands.
  119. X
  120. sweave:    sweb.c
  121. X    $(CC) $(CFLAGS) -o $@ $?
  122. X
  123. stangle:    sweb.c
  124. X    $(CC) -DTANGLE $(CFLAGS) -o $@ $?
  125. X
  126. schemeweb.sh:    $(SRCS)
  127. X    shar $(SRCS) > $@
  128. END_OF_FILE
  129. if test 859 -ne `wc -c <'Makefile'`; then
  130.     echo shar: \"'Makefile'\" unpacked with wrong size!
  131. fi
  132. # end of 'Makefile'
  133. fi
  134. if test -f 'README' -a "${1}" != "-c" ; then 
  135.   echo shar: Will not clobber existing file \"'README'\"
  136. else
  137. echo shar: Extracting \"'README'\" \(758 characters\)
  138. sed "s/^X//" >'README' <<'END_OF_FILE'
  139. SchemeWEB---Simple support for literate programming in Lisp.
  140. X
  141. SchemeWEB is a Unix filter that translates SchemeWEB source into LaTeX
  142. source or Scheme source.  Originally developed for the Scheme dialect 
  143. of Lisp, it can easily be used with most other dialects.
  144. X
  145. Installation:
  146. X
  147. X1) Processes the file "sweb.tex" with LaTeX and read that one page
  148. document.
  149. X
  150. X2) Edit "Makefile" to reflect the correct destination of the
  151. executables(DEST) and the correct destination of the style
  152. file(TEXDEST). 
  153. X
  154. X3) The command "make install" installs SchemeWEB.
  155. X
  156. X4) If you plan to modify your Lisp system's standard LOAD, follow the
  157. model given in "reader.sw", a reader of SchemeWEB source for the R4RS
  158. dialect of Scheme.
  159. X
  160. X$Header: README,v 1.1 90/07/12 08:57:33 ramsdell Exp $
  161. END_OF_FILE
  162. if test 758 -ne `wc -c <'README'`; then
  163.     echo shar: \"'README'\" unpacked with wrong size!
  164. fi
  165. # end of 'README'
  166. fi
  167. if test -f 'astyped.sty' -a "${1}" != "-c" ; then 
  168.   echo shar: Will not clobber existing file \"'astyped.sty'\"
  169. else
  170. echo shar: Extracting \"'astyped.sty'\" \(918 characters\)
  171. sed "s/^X//" >'astyped.sty' <<'END_OF_FILE'
  172. X%%%% $Header: astyped.sty,v 1.1 90/07/12 08:57:35 ramsdell Exp $ %%%%
  173. X%
  174. X% ASTYPED DOCUMENT-STYLE OPTION
  175. X%    for LaTeX version 2.09
  176. X% Based on Leslie Lamport's verbatim environment in latex.tex.
  177. X
  178. X% Defines the `astyped' environment, which is like the `verbatim'
  179. X% environment except most of the special characters have their usual meanings.
  180. X% Space, ^K, and ^A are the only specials changed.
  181. X
  182. X\def\astyped{\trivlist \item[]\if@minipage\else\vskip\parskip\fi
  183. X\leftskip\@totalleftmargin\rightskip\z@
  184. X\parindent\z@\parfillskip\@flushglue\parskip\z@
  185. X\@tempswafalse \def\par{\if@tempswa\hbox{}\fi\@tempswatrue\@@par}
  186. X\obeylines \tt \catcode``=13 \@noligs \let\do\@makeother \do\ \do\^^K\do\^^A
  187. X \frenchspacing\@vobeyspaces}
  188. X
  189. X\let\endastyped=\endtrivlist
  190. X
  191. X% Used inside astyped environments for normal formatting of a line.
  192. X% I wish I could give space its normal catcode within \notastyped.
  193. X\def\notastyped#1{\mbox{\rm #1}}
  194. END_OF_FILE
  195. if test 918 -ne `wc -c <'astyped.sty'`; then
  196.     echo shar: \"'astyped.sty'\" unpacked with wrong size!
  197. fi
  198. # end of 'astyped.sty'
  199. fi
  200. if test -f 'reader.sw' -a "${1}" != "-c" ; then 
  201.   echo shar: Will not clobber existing file \"'reader.sw'\"
  202. else
  203. echo shar: Extracting \"'reader.sw'\" \(1591 characters\)
  204. sed "s/^X//" >'reader.sw' <<'END_OF_FILE'
  205. X\documentstyle[astyped]{article}
  206. X% $Header: reader.sw,v 1.1 90/07/12 08:57:36 ramsdell Exp $
  207. X\title{{\tt read-sw}}
  208. X\author{John D. Ramsdell}
  209. X\date{\verb$Date: 90/07/12 08:57:36 $}
  210. X
  211. X\newcommand{\WEB}{{\tt WEB}}
  212. X
  213. X\begin{document}
  214. X
  215. X\maketitle
  216. X
  217. X\verb;read-sw; converts Scheme\WEB{} representations of Scheme objects
  218. into the objects themselves much as \verb;read; does.  
  219. X(define (read-sw . rest)        ; Returns what \verb;read; returns.
  220. X  (let ((port (if (pair? rest)        ; \verb;read-sw; arguments are
  221. X          (car rest)        ; the same as \verb;read;'s.
  222. X          (current-input-port))))
  223. X    (letrec                
  224. X    ((text-mode-and-saw-newline    ; Lines of a Scheme\WEB{} file
  225. X      (lambda ()            ; beginning with ``{\tt(}'', 
  226. X        (let ((ch (peek-char port))) ; start a code section.
  227. X          (cond ((eof-object? ch) ch)
  228. X            ((char=? ch #\()    ; If code section, then use
  229. X             (got-code (read port))) ; \verb;read; to get code,
  230. X            (else        ; else skip this line as it
  231. X             (text-mode-within-a-line)))))) ; is a comment.
  232. X     (text-mode-within-a-line
  233. X      (lambda ()            ; Ignore comments.
  234. X        (let ((ch (read-char port)))
  235. X          (cond ((eof-object? ch) ch)
  236. X            ((char=? ch #\newline)
  237. X             (text-mode-and-saw-newline))
  238. X            (else (text-mode-within-a-line))))))
  239. X     (got-code
  240. X      (lambda (code)        ; Ignore the remainder of the 
  241. X        (let ((ch (read-char port))) ; last code line and return
  242. X          (cond ((eof-object? ch) code) ;  the results of \verb;read;.
  243. X            ((char=? ch #\newline)
  244. X             code)
  245. X            (else (got-code code)))))))
  246. X    (text-mode-and-saw-newline)        ; Start by looking 
  247. X    )))                    ; for a code line.
  248. X\end{document}
  249. END_OF_FILE
  250. if test 1591 -ne `wc -c <'reader.sw'`; then
  251.     echo shar: \"'reader.sw'\" unpacked with wrong size!
  252. fi
  253. # end of 'reader.sw'
  254. fi
  255. if test -f 'sweb.c' -a "${1}" != "-c" ; then 
  256.   echo shar: Will not clobber existing file \"'sweb.c'\"
  257. else
  258. echo shar: Extracting \"'sweb.c'\" \(8301 characters\)
  259. sed "s/^X//" >'sweb.c' <<'END_OF_FILE'
  260. X/* SchemeWEB -- WEB for Scheme.  John D. Ramsdell.
  261. X * Simple support for literate programming in Scheme.
  262. X * This file generates both a Scheme weave program and
  263. X * a Scheme tangle program depending on if TANGLE is defined.
  264. X */
  265. X
  266. X#if !defined lint
  267. static char ID[] = "$Header: sweb.c,v 1.2 90/07/17 07:25:01 ramsdell Exp $";
  268. static char copyright[] = "Copyright 1990 by The MITRE Corporation.";
  269. X#endif
  270. X/*
  271. X * Copyright 1990 by The MITRE Corporation
  272. X *
  273. X * This program is free software; you can redistribute it and/or modify
  274. X * it under the terms of the GNU General Public License as published by
  275. X * the Free Software Foundation; either version 1, or (at your option)
  276. X * any later version.
  277. X *
  278. X * This program is distributed in the hope that it will be useful,
  279. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  280. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  281. X * GNU General Public License for more details.
  282. X * 
  283. X * For a copy of the GNU General Public License, write to the 
  284. X * Free Software Foundation, Inc., 675 Mass Ave, 
  285. X * Cambridge, MA 02139, USA.
  286. X */
  287. X
  288. X/* SchemeWEB defines a new source file format in which source lines
  289. are divided into text and code.  Lines of code start with a line
  290. beginning with '(', and continue until the line that contains the
  291. matching ')'.  The text lines remain, and they are treated as
  292. comments.  If the first character of a text line is ';', it is
  293. stripped from the output.  This is provided for those who want to use
  294. an unmodified version of their Scheme system's LOAD.  When producing a
  295. document, both the text lines and the code lines are copied into the
  296. document source file, but the code lines are surrounded by a pair of
  297. formatting commands, as is comments beginning with ';' within code
  298. lines.  SchemeWEB is currently set up for use with LaTeX. */
  299. X
  300. X/* Define TANGLE to make a program which translates SchemeWEB source
  301. into Scheme source. */
  302. X
  303. X/* Define SAVE_LEADING_SEMICOLON if you want text lines to be copied 
  304. with any leading semicolon. */
  305. X
  306. X#include <stdio.h>
  307. X
  308. typedef enum {FALSE, TRUE} bool;
  309. X
  310. X#define putstring(s) (fputs(s, stdout))
  311. X
  312. X#if defined TANGLE
  313. X#define sweb_putchar(c) (putchar(c))
  314. X#else
  315. X/* Modify the following for use with something other than LaTeX. */
  316. X#define BEGIN_COMMENT    "\\notastyped{"
  317. X#define BEGIN_CODE    "\\begin{astyped}"
  318. X#define END_CODE    "\\end{astyped}"
  319. void sweb_putchar (c)
  320. X      int c;
  321. X{                /* Raps \verb around characters */
  322. X  switch (c) {            /* which LaTeX handles specially. */
  323. X  case '\\': 
  324. X  case  '{': 
  325. X  case  '}': 
  326. X  case  '$': 
  327. X  case  '&': 
  328. X  case  '#': 
  329. X  case  '^': 
  330. X  case  '_': 
  331. X  case  '%': 
  332. X  case  '~': 
  333. X    putstring("\\verb-");
  334. X    putchar(c);
  335. X    putchar('-');
  336. X    break;
  337. X  default: putchar(c);
  338. X  }
  339. X}
  340. X#endif
  341. X
  342. X/* Error message for end of file found in code. */
  343. bool report_eof_in_code()
  344. X{
  345. X  fprintf(stderr, "End of file within a code section.\n");
  346. X  return TRUE;
  347. X}
  348. X
  349. X/* All input occurs in the following routines so that TAB characters
  350. can be expanded. TeX treats TAB characters as a space--not what is
  351. wanted. */
  352. int ch_buf;
  353. bool buf_used = FALSE;
  354. int lineno = 1;
  355. X
  356. X#undef getchar()
  357. int getchar()
  358. X{
  359. X  int c;
  360. X  static int spaces = 0;    /* Spaces left to print a TAB. */
  361. X  static int column = 0;    /* Current input column. */
  362. X  if (buf_used) {
  363. X    buf_used = FALSE;
  364. X    return ch_buf;
  365. X  }
  366. X  if (spaces > 0) {
  367. X    spaces--;
  368. X    return ' ';
  369. X  }
  370. X  switch (c = getc(stdin)) {
  371. X  case '\t':
  372. X    spaces = 7 - (7&column);    /* Maybe this should be 7&(~column). */
  373. X    column += spaces + 1;
  374. X    return ' ';
  375. X  case '\n':
  376. X    lineno++;
  377. X    column = 0;
  378. X    return c;
  379. X  default:
  380. X    column++;
  381. X    return c;
  382. X  }
  383. X}
  384. X
  385. void ungetchar(c)
  386. X     int c;
  387. X{
  388. X  buf_used = TRUE;
  389. X  ch_buf = c;
  390. X}
  391. X
  392. bool copy_text_saw_eof()
  393. X{
  394. X  int c;
  395. X  while (1) {
  396. X    c = getchar();
  397. X    if (c == EOF) return TRUE;
  398. X    if (c == '\n') return FALSE;
  399. X#if !defined TANGLE    
  400. X    putchar(c);
  401. X#endif
  402. X  }
  403. X}
  404. X
  405. bool copy_comment_saw_eof()    /* This copies comments */
  406. X{                /* within code sections. */
  407. X#if !defined TANGLE  
  408. X  putstring(BEGIN_COMMENT);
  409. X  putchar(';');
  410. X#endif  
  411. X  if (copy_text_saw_eof()) return TRUE;
  412. X#if !defined TANGLE  
  413. X  putchar('}');
  414. X#endif  
  415. X  putchar('\n');
  416. X  return FALSE;
  417. X}
  418. X
  419. bool after_sexpr_failed()    /* Copies comments in a code */
  420. X{                /* section that follow a */
  421. X  int c;            /* complete S-expr. */
  422. X  while (1)            /* It fails when there is */
  423. X    switch (c = getchar()) {    /* something other than */ 
  424. X    case EOF:            /* white space or a comment, */
  425. X      return report_eof_in_code(); /* such as an extra ')'. */
  426. X    case ';': 
  427. X#if !defined TANGLE  
  428. X      putstring(BEGIN_COMMENT);
  429. X      putchar(c);
  430. X#endif  
  431. X      if (copy_text_saw_eof()) return report_eof_in_code();
  432. X#if !defined TANGLE  
  433. X      putchar('}');
  434. X#endif  
  435. X      putchar('\n');
  436. X      return FALSE;
  437. X    case '\n':
  438. X      putchar(c);
  439. X      return FALSE;
  440. X    case ' ':
  441. X#if !defined TANGLE
  442. X      putchar(c);
  443. X#endif
  444. X      break;
  445. X    default:
  446. X      fprintf(stderr,
  447. X          "Found \"%c\"  after an S-expr finished.\n",
  448. X          c);
  449. X      return TRUE;
  450. X    }
  451. X}
  452. X
  453. bool copy_string_saw_eof()
  454. X{
  455. X  int c;
  456. X  while (1) {
  457. X    c = getchar();
  458. X    if (c == EOF) return TRUE;
  459. X    sweb_putchar(c);
  460. X    switch (c) {
  461. X    case '"': return FALSE;
  462. X    case '\\':
  463. X      c = getchar();
  464. X      if (c == EOF) return TRUE;
  465. X      sweb_putchar(c);
  466. X    }
  467. X  }
  468. X}
  469. X
  470. bool maybe_char_syntax_saw_eof()
  471. X{                /* Makes sure that the character */
  472. X  int c;            /* #\( does not get counted in */
  473. X  c = getchar();        /* balancing parentheses. */
  474. X  if (c == EOF) return TRUE;
  475. X  if (c != '\\') {
  476. X    ungetchar(c);
  477. X    return FALSE;
  478. X  }
  479. X  sweb_putchar(c);
  480. X  c = getchar();
  481. X  if (c == EOF) return TRUE;
  482. X  sweb_putchar(c);
  483. X  return FALSE;
  484. X}
  485. X
  486. bool copy_code_failed()        /* Copies a code section */
  487. X{                /* containing one S-expr. */
  488. X  int parens = 1;        /* Used to balance parentheses. */
  489. X  int c;
  490. X  while (1) {            /* While parens are not balanced, */
  491. X    c = getchar();
  492. X    if (c == EOF)        /* report failure on EOF and */
  493. X      return report_eof_in_code();
  494. X    if (c == ';')        /* report failure on EOF in a comment. */
  495. X      if (copy_comment_saw_eof()) return report_eof_in_code();
  496. X      else continue;
  497. X    sweb_putchar(c);        /* Write the character and then see */
  498. X    switch (c) {        /* if it requires special handling. */
  499. X    case '(':
  500. X      parens++;
  501. X      break;
  502. X    case ')':
  503. X      parens--;            
  504. X      if (parens == 0)        /* Parentheses balance! */
  505. X    return after_sexpr_failed(); /* Report the result of */
  506. X      break;            /* post S-expr processing. */
  507. X    case '"':            /* Report failure on EOF in a string. */
  508. X      if (copy_string_saw_eof()) {
  509. X    fprintf(stderr, "End of file found within a string.\n");
  510. X    return TRUE;
  511. X      }
  512. X      break;
  513. X    case '#':            /* Report failure on EOF in a character. */
  514. X      if (maybe_char_syntax_saw_eof()) return report_eof_in_code();
  515. X      break;
  516. X    }
  517. X  }
  518. X}
  519. X
  520. int filter()
  521. X{
  522. X  int c;
  523. X  while (1) {            /* At loop start it's in text mode */
  524. X    c = getchar();        /* and at the begining of a line. */
  525. X    if (c == '(') {        /* text mode changed to code mode. */
  526. X#if !defined TANGLE
  527. X      putstring(BEGIN_CODE); putchar('\n');
  528. X#endif
  529. X      do {            /* Copy code. */
  530. X    putchar(c);
  531. X    if (copy_code_failed()) {
  532. X      fprintf(stderr,
  533. X          "Error in the code section containing line %d.\n",
  534. X          lineno);
  535. X      return 1;
  536. X    }
  537. X    c = getchar();        /* Repeat when there is code */
  538. X      } while (c == '(');    /* immediately after some code. */
  539. X#if !defined TANGLE
  540. X      fputs(END_CODE, stdout); putc('\n', stdout);
  541. X#endif
  542. X    }
  543. X    /* Found a text line--now in text mode. */
  544. X#if !defined SAVE_LEADING_SEMICOLON
  545. X    if (c == ';') c = getchar();
  546. X#endif
  547. X    ungetchar(c);
  548. X    if (copy_text_saw_eof()) return 0; /* Copy a text line. */
  549. X#if !defined TANGLE
  550. X    putchar('\n');
  551. X#endif
  552. X  }
  553. X}
  554. X
  555. int main (argc, argv)        /* For machines which do not */
  556. X     int argc;            /* support argc and argv, */
  557. X     char *argv[];        /* just change main. */
  558. X{
  559. X  switch (argc) {
  560. X  case 3:
  561. X    if (NULL == freopen(argv[2], "w", stdout)) {
  562. X      fprintf(stderr, "Cannot open %s for writing.\n", argv[2]);
  563. X      break;
  564. X    }
  565. X  case 2:
  566. X    if (NULL == freopen(argv[1], "r", stdin)) {
  567. X      fprintf(stderr, "Cannot open %s for reading.\n", argv[1]);
  568. X      break;
  569. X    }
  570. X  case 1:
  571. X    return filter();
  572. X  }
  573. X  fprintf(stderr, 
  574. X#if defined TANGLE
  575. X      "Usage: %s [SchemeWEB file] [Scheme file]\n",
  576. X#else
  577. X      "Usage: %s [SchemeWEB file] [LaTeX file]\n", 
  578. X#endif
  579. X      argv[0]);
  580. X  return 1;
  581. X}
  582. END_OF_FILE
  583. if test 8301 -ne `wc -c <'sweb.c'`; then
  584.     echo shar: \"'sweb.c'\" unpacked with wrong size!
  585. fi
  586. # end of 'sweb.c'
  587. fi
  588. if test -f 'sweb.scm' -a "${1}" != "-c" ; then 
  589.   echo shar: Will not clobber existing file \"'sweb.scm'\"
  590. else
  591. echo shar: Extracting \"'sweb.scm'\" \(11561 characters\)
  592. sed "s/^X//" >'sweb.scm' <<'END_OF_FILE'
  593. X;;; SchemeWEB --- Simple support for literate programming in Scheme.
  594. X;;; $Header: sweb.scm,v 1.1 90/07/12 08:57:38 ramsdell Exp $
  595. X;;; John D. Ramsdell.
  596. X;;;
  597. X;;; Copyright 1990 by The MITRE Corporation
  598. X;;;
  599. X;;; This program is free software; you can redistribute it and/or modify
  600. X;;; it under the terms of the GNU General Public License as published by
  601. X;;; the Free Software Foundation; either version 1, or (at your option)
  602. X;;; any later version.
  603. X;;;
  604. X;;; This program is distributed in the hope that it will be useful,
  605. X;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  606. X;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  607. X;;; GNU General Public License for more details.
  608. X;;; 
  609. X;;; For a copy of the GNU General Public License, write to the 
  610. X;;; Free Software Foundation, Inc., 675 Mass Ave, 
  611. X;;; Cambridge, MA 02139, USA.
  612. X;;;
  613. X;;; SchemeWEB
  614. X;;; defines a new source file format in which source lines are divided
  615. X;;; into text and code.  Lines of code start with a line beginning with
  616. X;;; '(', and continue until the line that contains the matching ')'.  The
  617. X;;; text lines remain, and they are treated as comments.  When producing
  618. X;;; a document, both the text lines and the code lines are copied into
  619. X;;; the document source file, but the code lines are surrounded by a pair
  620. X;;; of formatting commands.  The formatting commands are in begin-code
  621. X;;; and end-code.  SchemeWEB is currently set up for use with LaTeX.
  622. X;;;
  623. X;;; Exports: tangle and weave.
  624. X;;; (tangle sw-file scheme-file)  Makes scheme file from SchemeWEB source.
  625. X;;; (weave sw-file tex-file)      Makes LaTeX file from SchemeWEB source.
  626. X
  627. X(define (tangle sw-filename scheme-filename) ; => scheme-filename or false.
  628. X  (if (call-with-input-file sw-filename
  629. X        (lambda (sw-port)
  630. X          (call-with-output-file scheme-filename
  631. X            (lambda (scheme-port)
  632. X              (tangle-port sw-port scheme-port)))))
  633. X      scheme-filename
  634. X      (begin                            ; Put a call to error here.
  635. X        (display "tangle failed.") (newline)
  636. X        #f)))
  637. X
  638. X(define (weave sw-filename tex-filename) ; => tex-filename or false.
  639. X  (if (call-with-input-file sw-filename
  640. X        (lambda (sw-port)
  641. X          (call-with-output-file tex-filename
  642. X            (lambda (tex-port)
  643. X              (weave-port sw-port tex-port)))))
  644. X      tex-filename
  645. X      (begin                            ; Put a call to error here.
  646. X        (display "weave failed.") (newline)
  647. X        #f)))
  648. X
  649. X(define (tangle-port sw-port scheme-port) ; => false on failure.
  650. X  (letrec
  651. X      ((tex-mode-and-saw-newline        ; Decide if input is code
  652. X        (lambda ()
  653. X          (let ((ch (peek-char sw-port))) ; or tex source.
  654. X            (cond ((eof-object? ch) #t)
  655. X                  ((char=? ch #\()
  656. X                   (scheme-mode))
  657. X                  (else (tex-mode-within-a-line))))))
  658. X       (tex-mode-within-a-line          ; Strip comments.
  659. X        (lambda ()
  660. X          (let ((ch (read-char sw-port)))
  661. X            (cond ((eof-object? ch) #t)
  662. X                  ((char=? ch #\newline)
  663. X                   (tex-mode-and-saw-newline))
  664. X                  (else (tex-mode-within-a-line))))))
  665. X       (scheme-mode                     ; This routine should use
  666. X        (lambda ()
  667. X          (write (read sw-port) scheme-port)
  668. X          (newline scheme-port)         ; read-refusing-eof if
  669. X          (tex-mode-within-a-line))))   ; available.
  670. X    (tex-mode-and-saw-newline)))
  671. X
  672. X(define begin-code "\\begin{astyped}")  ; TeX code surrounding 
  673. X(define end-code "\\end{astyped}")      ; code and comments
  674. X(define begin-comment "\\notastyped{")  ; within code.
  675. X              
  676. X(define (weave-port sw-port tex-port)
  677. X  (let ((spaces 0)                      ; Used in get-char and get-line during
  678. X        (hpos 0)                        ; the expansion of tabs into spaces.
  679. X        (ch-buf #f))                    ; One char buffer.
  680. X    (letrec                             
  681. X        ((get-char
  682. X          (lambda ()                    ; Get-char expands tabs into spaces,
  683. X            (cond (ch-buf               ; and implements a one character
  684. X                   (let ((ch ch-buf))   ; buffer.
  685. X                     (set! ch-buf #f)
  686. X                     ch))
  687. X                  ((> spaces 0)
  688. X                   (set! spaces (- spaces 1))
  689. X                   #\space)
  690. X                  (else
  691. X                   (let ((ch (read-char sw-port)))
  692. X                     (cond ((eof-object? ch) ch)
  693. X                           ((char=? ch #\tab) ; Expand tabs here.
  694. X                            (set! spaces (- 8 (modulo hpos 8)))
  695. X                            (set! hpos (+ hpos spaces))
  696. X                            (get-char))
  697. X                           ((char=? ch #\newline)
  698. X                            (set! hpos 0)
  699. X                            ch)
  700. X                           (else
  701. X                            (set! hpos (+ hpos 1))
  702. X                            ch)))))))
  703. X         (unget-char
  704. X          (lambda (ch)
  705. X            (set! ch-buf ch)))
  706. X         (copy-line-saw-eof
  707. X          (lambda ()
  708. X            (let ((ch (get-char)))
  709. X              (cond ((eof-object? ch) #t)
  710. X                    ((char=? ch #\newline) #f)
  711. X                    (else
  712. X                     (write-char ch tex-port)
  713. X                     (copy-line-saw-eof))))))
  714. X         (tex-write-char
  715. X          (lambda (ch)                  ; Write to TeX file
  716. X            (if (or (char=? ch #\\)     ; escaping TeX's special
  717. X                    (char=? ch #\{)     ; characters.
  718. X                    (char=? ch #\})
  719. X                    (char=? ch #\$)
  720. X                    (char=? ch #\&)
  721. X                    (char=? ch #\#)
  722. X                    (char=? ch #\^)
  723. X                    (char=? ch #\_)
  724. X                    (char=? ch #\%)
  725. X                    (char=? ch #\~))
  726. X                (begin
  727. X                  (display "\\verb-" tex-port)
  728. X                  (write-char ch tex-port)
  729. X                  (write-char #\- tex-port))
  730. X                (write-char ch tex-port))))
  731. X
  732. X         ;; TeX mode
  733. X         (tex-mode-and-saw-newline      ; State at which it is 
  734. X          (lambda ()                    ; decided whether to go 
  735. X            (let ((ch (get-char)))      ; into Scheme code mode
  736. X              (cond ((eof-object? ch) #t) ; or stay in TeX mode.
  737. X                    ((char=? ch #\() (scheme-mode))
  738. X                    (else       
  739. X                     ;; Strip leading semicolon for those who
  740. X                     ;; want to use regular load.
  741. X                     (if (not (char=? ch #\;))
  742. X                         (write-char ch tex-port))
  743. X                     (if (char=? ch #\newline)
  744. X                         (tex-mode-and-saw-newline)
  745. X                         (tex-mode-within-a-line)))))))
  746. X         (tex-mode-within-a-line        ; Copy out TeX line.
  747. X          (lambda ()
  748. X            (let ((saw-eof (copy-line-saw-eof)))
  749. X              (newline tex-port)
  750. X              (or saw-eof (tex-mode-and-saw-newline)))))
  751. X
  752. X         ;; Scheme mode
  753. X         (scheme-mode                   ; Change from TeX mode 
  754. X          (lambda ()                    ; to scheme code mode.
  755. X            (display begin-code tex-port)
  756. X            (newline tex-port)
  757. X            (write-char #\( tex-port)
  758. X            (sexpr 1)))
  759. X         (sexpr                         ; parens is used to watch
  760. X          (lambda (parens)              ; for the closing paren
  761. X            (let ((ch (get-char)))      ; used to detect the end
  762. X              (cond ((eof-object? ch) #f) ; of scheme code mode.
  763. X                    ((char=? ch #\;)
  764. X                     (copy-comment-within-sexpr parens))
  765. X                    (else       
  766. X                     (sexpr-write-char parens ch))))))
  767. X         (copy-comment-within-sexpr
  768. X          (lambda (parens)              ; Handle comment.
  769. X            (display begin-comment tex-port)
  770. X            (write-char #\; tex-port)
  771. X            (let ((saw-eof (copy-line-saw-eof)))
  772. X              (write-char #\} tex-port)
  773. X              (newline tex-port)
  774. X              (and (not saw-eof) (sexpr parens)))))
  775. X         (sexpr-write-char
  776. X          (lambda (parens ch)           ; Write a char and
  777. X            (tex-write-char ch)         ; figure out what to
  778. X            (cond ((char=? ch #\()      ; do next.
  779. X                   (sexpr (+ parens 1)))
  780. X                  ((char=? ch #\))
  781. X                   (if (= 1 parens)     ; Done reading sexpr.
  782. X                       (scheme-mode-after-sexpr)
  783. X                       (sexpr (- parens 1))))
  784. X                  ((char=? ch #\")
  785. X                   (copy-out-string parens))
  786. X                  ((char=? ch #\#)      ; Worrying about #\( and #\).
  787. X                   (maybe-char-syntax parens))
  788. X                  (else (sexpr parens)))))
  789. X         (copy-out-string
  790. X          (lambda (parens)
  791. X            (let ((ch (get-char)))
  792. X              (and (not (eof-object? ch))
  793. X                   (begin
  794. X                     (tex-write-char ch)
  795. X                     (cond ((char=? ch #\\)
  796. X                            (let ((ch (get-char)))
  797. X                              (and (not (eof-object? ch))
  798. X                                   (begin
  799. X                                     (tex-write-char ch)
  800. X                                     (copy-out-string parens)))))
  801. X                           ((char=? ch #\")
  802. X                            (sexpr parens))
  803. X                           (else (copy-out-string parens))))))))
  804. X         (maybe-char-syntax             ; What out for
  805. X          (lambda (parens)              ; #\( and #\).
  806. X            (let ((ch (get-char)))
  807. X              (cond ((eof-object? ch) #f)
  808. X                    ((char=? ch #\\)
  809. X                     (tex-write-char ch)
  810. X                     (let ((ch (get-char)))
  811. X                       (and (not (eof-object? ch))
  812. X                            (begin
  813. X                              (tex-write-char ch)
  814. X                              (sexpr parens)))))
  815. X                    (else
  816. X                     (unget-char ch)
  817. X                     (sexpr parens))))))
  818. X         (scheme-mode-after-sexpr
  819. X          (lambda ()
  820. X            (let ((ch (get-char)))
  821. X              (cond ((eof-object? ch) #t)
  822. X                    ((char=? ch #\;)
  823. X                     (copy-comment-after-sexpr))
  824. X                    ((char=? ch #\newline)
  825. X                     (newline tex-port)
  826. X                     (scheme-mode-merge))
  827. X                    ((char=? ch #\space)
  828. X                     (tex-write-char ch)
  829. X                     (scheme-mode-after-sexpr))
  830. X                    (else #f)))))       ; Call to error should go here.
  831. X         (copy-comment-after-sexpr
  832. X          (lambda ()                    ; Handle trailing comment.
  833. X            (display begin-comment tex-port)
  834. X            (write-char #\; tex-port)
  835. X            (let ((saw-eof (copy-line-saw-eof)))
  836. X              (write-char #\} tex-port)
  837. X              (newline tex-port)
  838. X              (and (not saw-eof) (scheme-mode-merge)))))
  839. X         (scheme-mode-merge             ; Don't change mode if next
  840. X          (lambda ()                    ; line is code.
  841. X            (let ((ch (get-char)))
  842. X              (cond ((eof-object? ch) #t)
  843. X                    ((char=? ch #\()    ; Stay in scheme mode.
  844. X                     (write-char ch tex-port)
  845. X                     (sexpr 1))
  846. X                    (else               ; Enter tex mode.
  847. X                     (display end-code tex-port)
  848. X                     (newline tex-port)
  849. X                     (write-char ch tex-port)
  850. X                     (if (char=? ch #\newline)
  851. X                         (tex-mode-and-saw-newline)
  852. X                         (tex-mode-within-a-line))))))))
  853. X      (tex-mode-and-saw-newline))))
  854. END_OF_FILE
  855. if test 11561 -ne `wc -c <'sweb.scm'`; then
  856.     echo shar: \"'sweb.scm'\" unpacked with wrong size!
  857. fi
  858. # end of 'sweb.scm'
  859. fi
  860. if test -f 'sweb.tex' -a "${1}" != "-c" ; then 
  861.   echo shar: Will not clobber existing file \"'sweb.tex'\"
  862. else
  863. echo shar: Extracting \"'sweb.tex'\" \(3170 characters\)
  864. sed "s/^X//" >'sweb.tex' <<'END_OF_FILE'
  865. X\documentstyle[proc]{article}
  866. X% $Header: sweb.tex,v 1.1 90/07/12 11:38:57 ramsdell Exp $
  867. X\title{Scheme\WEB{}}
  868. X\author{John D. Ramsdell}
  869. X\date{\verb$Date: 90/07/12 11:38:57 $}
  870. X
  871. X\newcommand{\WEB}{{\tt WEB}}
  872. X
  873. X\begin{document}
  874. X
  875. X\maketitle
  876. X
  877. Scheme\WEB{} provides simple support for literate programming in any
  878. dialect of Lisp.  Originally created for use with Scheme, it defines a
  879. new source file format which may be used to produce \LaTeX{} input or
  880. Lisp code.
  881. X
  882. Scheme\WEB{} source lines are divided into text and code.  Lines of code
  883. start with a line beginning with ``('', and continue until the line
  884. containing the matching ``)''.  The remaining lines are text lines,
  885. and they are treated as comments.
  886. X
  887. When producing a \LaTeX{} document, both the text lines and the code
  888. lines are copied into the document source file, but the code lines are
  889. surrounded by a pair of formatting commands (\verb-\begin{astyped}-
  890. and \verb-\end{astyped}-).  This \LaTeX{} environment formats the code
  891. as written, in typewriter font.  A Lisp comment within a code line is
  892. formatted in an \verb-\mbox- in Roman font.  A Scheme\WEB{} style
  893. command should include the \verb-astyped- style option, so that the
  894. X\verb-astyped- environment is available.  An example:
  895. X\begin{quote}
  896. X\verb-\documentstyle[astyped]{article}-
  897. X\end{quote}
  898. X
  899. Scheme\WEB{} was designed under the constraint that code lines must be
  900. unmodified Lisp code, and text lines must be unmodified \LaTeX{} code.
  901. Text editors with support for Lisp and \LaTeX{}, such as Emacs, may be
  902. used for Scheme\WEB{} code much as they are used for Lisp code and
  903. X\LaTeX{} code.
  904. X
  905. XFor those who prefer not to modify the reader used by their Lisp
  906. system's loader and compiler, the rule that text lines must be
  907. unmodified \LaTeX{} code has been relaxed.  Text lines that begin with
  908. X``;'' are copied without the initial ``;''.
  909. X
  910. X\section*{Usage in Scheme}
  911. The file \verb;sweb.scm; contains programs used to obtain code or
  912. X\LaTeX{} from a Scheme\WEB{} source file.  The Scheme expression
  913. X\begin{quote}\tt
  914. X(TANGLE "{\it Scheme\WEB{} file}" "{\it Scheme file}")
  915. X\end{quote}
  916. creates Scheme source from a Scheme\WEB{} file, and the expression
  917. X\begin{quote}\tt
  918. X(WEAVE "{\it Scheme\WEB{} file}" "{\it \LaTeX{} file}")
  919. X\end{quote}
  920. creates \LaTeX{} source.
  921. X
  922. The file \verb-reader.sw- contains a Scheme\WEB{} reader in R$^4$R Scheme.
  923. Use that reader with your Scheme system's loader and compiler to
  924. avoid running \verb-TANGLE- and creating a temporary file.
  925. X
  926. X\begin{figure}
  927. X\begin{verbatim}
  928. X.SUFFIXES:      .dvi .tex .scm .sw
  929. X
  930. X.sw.dvi:
  931. X        make $*.tex && make $*.dvi
  932. X
  933. X.sw.tex:
  934. X        sweave $*.sw $*.tex
  935. X
  936. X.tex.dvi:       
  937. X        latex $*
  938. X
  939. X.sw.scm:
  940. X        stangle $*.sw $*.scm
  941. X\end{verbatim}
  942. X\caption{A Scheme\WEB{} Makefile}\label{makefile}
  943. X\end{figure}
  944. X
  945. X\section*{Usage in a Unix shell}
  946. XFiles are produced from Scheme\WEB{} source
  947. using the Unix shell commands
  948. X\begin{quote}\tt
  949. sweave [{\it Scheme\WEB{} file}] [{\it \LaTeX{} file}] \\
  950. stangle [{\it Scheme\WEB{} file}] [{\it Scheme file}]
  951. X\end{quote}
  952. The obvious make file is in Figure~\ref{makefile}.
  953. It uses the convention that the extension for Scheme\WEB{} 
  954. files is ``\verb;.sw;.'' 
  955. X
  956. X\end{document}
  957. END_OF_FILE
  958. if test 3170 -ne `wc -c <'sweb.tex'`; then
  959.     echo shar: \"'sweb.tex'\" unpacked with wrong size!
  960. fi
  961. # end of 'sweb.tex'
  962. fi
  963. echo shar: End of archive 1 \(of 1\).
  964. cp /dev/null ark1isdone
  965. MISSING=""
  966. for I in 1 ; do
  967.     if test ! -f ark${I}isdone ; then
  968.     MISSING="${MISSING} ${I}"
  969.     fi
  970. done
  971. if test "${MISSING}" = "" ; then
  972.     echo You have the archive.
  973.     rm -f ark[1-9]isdone
  974. else
  975.     echo You still need to unpack the following archives:
  976.     echo "        " ${MISSING}
  977. fi
  978. ##  End of shell archive.
  979. exit 0
  980.