home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #31 / NN_1992_31.iso / spool / comp / sources / unix / 281 < prev    next >
Encoding:
Text File  |  1992-12-29  |  32.9 KB  |  987 lines

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