WebGate

Hex Artifact Content
Login

Artifact 6f01e31703faf5ad7a21dd7e82f5099f687b4a2f:


0000: 3b 3b 20 2d 2a 2d 20 6d 6f 64 65 3a 20 53 63 68  ;; -*- mode: Sch
0010: 65 6d 65 3b 20 2d 2a 2d 0a 3b 3b 0a 3b 3b 20 54  eme; -*-.;;.;; T
0020: 68 69 73 20 66 69 6c 65 20 69 73 20 70 61 72 74  his file is part
0030: 20 6f 66 20 57 65 62 47 61 74 65 20 66 6f 72 20   of WebGate for 
0040: 43 48 49 43 4b 45 4e 2e 0a 3b 3b 20 43 6f 70 79  CHICKEN..;; Copy
0050: 72 69 67 68 74 20 28 63 29 20 32 30 31 31 2d 32  right (c) 2011-2
0060: 30 31 33 20 62 79 20 54 68 6f 6d 61 73 20 43 68  013 by Thomas Ch
0070: 75 73 74 2e 20 20 41 6c 6c 20 72 69 67 68 74 73  ust.  All rights
0080: 20 72 65 73 65 72 76 65 64 2e 0a 3b 3b 0a 3b 3b   reserved..;;.;;
0090: 20 50 65 72 6d 69 73 73 69 6f 6e 20 69 73 20 68   Permission is h
00a0: 65 72 65 62 79 20 67 72 61 6e 74 65 64 2c 20 66  ereby granted, f
00b0: 72 65 65 20 6f 66 20 63 68 61 72 67 65 2c 20 74  ree of charge, t
00c0: 6f 20 61 6e 79 20 70 65 72 73 6f 6e 0a 3b 3b 20  o any person.;; 
00d0: 6f 62 74 61 69 6e 69 6e 67 20 61 20 63 6f 70 79  obtaining a copy
00e0: 20 6f 66 20 74 68 69 73 20 73 6f 66 74 77 61 72   of this softwar
00f0: 65 20 61 6e 64 20 61 73 73 6f 63 69 61 74 65 64  e and associated
0100: 20 64 6f 63 75 6d 65 6e 74 61 74 69 6f 6e 0a 3b   documentation.;
0110: 3b 20 66 69 6c 65 73 20 28 74 68 65 20 53 6f 66  ; files (the Sof
0120: 74 77 61 72 65 29 2c 20 74 6f 20 64 65 61 6c 20  tware), to deal 
0130: 69 6e 20 74 68 65 20 53 6f 66 74 77 61 72 65 20  in the Software 
0140: 77 69 74 68 6f 75 74 20 72 65 73 74 72 69 63 74  without restrict
0150: 69 6f 6e 2c 0a 3b 3b 20 69 6e 63 6c 75 64 69 6e  ion,.;; includin
0160: 67 20 77 69 74 68 6f 75 74 20 6c 69 6d 69 74 61  g without limita
0170: 74 69 6f 6e 20 74 68 65 20 72 69 67 68 74 73 20  tion the rights 
0180: 74 6f 20 75 73 65 2c 20 63 6f 70 79 2c 20 6d 6f  to use, copy, mo
0190: 64 69 66 79 2c 0a 3b 3b 20 6d 65 72 67 65 2c 20  dify,.;; merge, 
01a0: 70 75 62 6c 69 73 68 2c 20 64 69 73 74 72 69 62  publish, distrib
01b0: 75 74 65 2c 20 73 75 62 6c 69 63 65 6e 73 65 2c  ute, sublicense,
01c0: 20 61 6e 64 2f 6f 72 20 73 65 6c 6c 20 63 6f 70   and/or sell cop
01d0: 69 65 73 20 6f 66 20 74 68 65 0a 3b 3b 20 53 6f  ies of the.;; So
01e0: 66 74 77 61 72 65 2c 20 61 6e 64 20 74 6f 20 70  ftware, and to p
01f0: 65 72 6d 69 74 20 70 65 72 73 6f 6e 73 20 74 6f  ermit persons to
0200: 20 77 68 6f 6d 20 74 68 65 20 53 6f 66 74 77 61   whom the Softwa
0210: 72 65 20 69 73 20 66 75 72 6e 69 73 68 65 64 0a  re is furnished.
0220: 3b 3b 20 74 6f 20 64 6f 20 73 6f 2c 20 73 75 62  ;; to do so, sub
0230: 6a 65 63 74 20 74 6f 20 74 68 65 20 66 6f 6c 6c  ject to the foll
0240: 6f 77 69 6e 67 20 63 6f 6e 64 69 74 69 6f 6e 73  owing conditions
0250: 3a 0a 3b 3b 20 0a 3b 3b 20 54 68 65 20 61 62 6f  :.;; .;; The abo
0260: 76 65 20 63 6f 70 79 72 69 67 68 74 20 6e 6f 74  ve copyright not
0270: 69 63 65 20 61 6e 64 20 74 68 69 73 20 70 65 72  ice and this per
0280: 6d 69 73 73 69 6f 6e 20 6e 6f 74 69 63 65 20 73  mission notice s
0290: 68 61 6c 6c 20 62 65 0a 3b 3b 20 69 6e 63 6c 75  hall be.;; inclu
02a0: 64 65 64 20 69 6e 20 61 6c 6c 20 63 6f 70 69 65  ded in all copie
02b0: 73 20 6f 72 20 73 75 62 73 74 61 6e 74 69 61 6c  s or substantial
02c0: 20 70 6f 72 74 69 6f 6e 73 20 6f 66 20 74 68 65   portions of the
02d0: 20 53 6f 66 74 77 61 72 65 2e 0a 3b 3b 20 0a 3b   Software..;; .;
02e0: 3b 20 54 48 45 20 53 4f 46 54 57 41 52 45 20 49  ; THE SOFTWARE I
02f0: 53 20 50 52 4f 56 49 44 45 44 20 41 53 49 53 2c  S PROVIDED ASIS,
0300: 20 57 49 54 48 4f 55 54 20 57 41 52 52 41 4e 54   WITHOUT WARRANT
0310: 59 20 4f 46 20 41 4e 59 20 4b 49 4e 44 2c 0a 3b  Y OF ANY KIND,.;
0320: 3b 20 45 58 50 52 45 53 53 20 4f 52 20 49 4d 50  ; EXPRESS OR IMP
0330: 4c 49 45 44 2c 20 49 4e 43 4c 55 44 49 4e 47 20  LIED, INCLUDING 
0340: 42 55 54 20 4e 4f 54 20 4c 49 4d 49 54 45 44 20  BUT NOT LIMITED 
0350: 54 4f 20 54 48 45 20 57 41 52 52 41 4e 54 49 45  TO THE WARRANTIE
0360: 53 20 4f 46 0a 3b 3b 20 4d 45 52 43 48 41 4e 54  S OF.;; MERCHANT
0370: 41 42 49 4c 49 54 59 2c 20 46 49 54 4e 45 53 53  ABILITY, FITNESS
0380: 20 46 4f 52 20 41 20 50 41 52 54 49 43 55 4c 41   FOR A PARTICULA
0390: 52 20 50 55 52 50 4f 53 45 20 41 4e 44 0a 3b 3b  R PURPOSE AND.;;
03a0: 20 4e 4f 4e 49 4e 46 52 49 4e 47 45 4d 45 4e 54   NONINFRINGEMENT
03b0: 2e 20 49 4e 20 4e 4f 20 45 56 45 4e 54 20 53 48  . IN NO EVENT SH
03c0: 41 4c 4c 20 54 48 45 20 41 55 54 48 4f 52 53 20  ALL THE AUTHORS 
03d0: 4f 52 20 43 4f 50 59 52 49 47 48 54 20 48 4f 4c  OR COPYRIGHT HOL
03e0: 44 45 52 53 0a 3b 3b 20 42 45 20 4c 49 41 42 4c  DERS.;; BE LIABL
03f0: 45 20 46 4f 52 20 41 4e 59 20 43 4c 41 49 4d 2c  E FOR ANY CLAIM,
0400: 20 44 41 4d 41 47 45 53 20 4f 52 20 4f 54 48 45   DAMAGES OR OTHE
0410: 52 20 4c 49 41 42 49 4c 49 54 59 2c 20 57 48 45  R LIABILITY, WHE
0420: 54 48 45 52 20 49 4e 20 41 4e 0a 3b 3b 20 41 43  THER IN AN.;; AC
0430: 54 49 4f 4e 20 4f 46 20 43 4f 4e 54 52 41 43 54  TION OF CONTRACT
0440: 2c 20 54 4f 52 54 20 4f 52 20 4f 54 48 45 52 57  , TORT OR OTHERW
0450: 49 53 45 2c 20 41 52 49 53 49 4e 47 20 46 52 4f  ISE, ARISING FRO
0460: 4d 2c 20 4f 55 54 20 4f 46 20 4f 52 20 49 4e 0a  M, OUT OF OR IN.
0470: 3b 3b 20 43 4f 4e 4e 45 43 54 49 4f 4e 20 57 49  ;; CONNECTION WI
0480: 54 48 20 54 48 45 20 53 4f 46 54 57 41 52 45 20  TH THE SOFTWARE 
0490: 4f 52 20 54 48 45 20 55 53 45 20 4f 52 20 4f 54  OR THE USE OR OT
04a0: 48 45 52 20 44 45 41 4c 49 4e 47 53 20 49 4e 20  HER DEALINGS IN 
04b0: 54 48 45 0a 3b 3b 20 53 4f 46 54 57 41 52 45 2e  THE.;; SOFTWARE.
04c0: 0a 0a 3b 3b 3b 20 4e 65 74 73 74 72 69 6e 67 73  ..;;; Netstrings
04d0: 0a 0a 28 64 65 66 69 6e 65 20 28 77 72 69 74 65  ..(define (write
04e0: 2d 6e 65 74 73 74 72 69 6e 67 20 73 20 23 21 6f  -netstring s #!o
04f0: 70 74 69 6f 6e 61 6c 20 28 70 6f 72 74 20 28 63  ptional (port (c
0500: 75 72 72 65 6e 74 2d 6f 75 74 70 75 74 2d 70 6f  urrent-output-po
0510: 72 74 29 29 29 0a 20 20 28 66 70 72 69 6e 74 66  rt))).  (fprintf
0520: 20 70 6f 72 74 20 22 7e 61 3a 7e 61 2c 22 20 28   port "~a:~a," (
0530: 73 74 72 69 6e 67 2d 6c 65 6e 67 74 68 20 73 29  string-length s)
0540: 20 73 29 29 0a 0a 28 64 65 66 69 6e 65 20 28 72   s))..(define (r
0550: 65 61 64 2d 6e 65 74 73 74 72 69 6e 67 20 23 21  ead-netstring #!
0560: 6f 70 74 69 6f 6e 61 6c 20 28 70 6f 72 74 20 28  optional (port (
0570: 63 75 72 72 65 6e 74 2d 69 6e 70 75 74 2d 70 6f  current-input-po
0580: 72 74 29 29 29 0a 20 20 28 6c 65 74 20 28 28 6c  rt))).  (let ((l
0590: 20 28 73 74 72 69 6e 67 2d 3e 6e 75 6d 62 65 72   (string->number
05a0: 20 28 72 65 61 64 2d 74 6f 6b 65 6e 20 63 68 61   (read-token cha
05b0: 72 2d 6e 75 6d 65 72 69 63 3f 20 70 6f 72 74 29  r-numeric? port)
05c0: 29 29 29 0a 20 20 20 20 28 75 6e 6c 65 73 73 20  ))).    (unless 
05d0: 6c 0a 20 20 20 20 20 20 28 65 72 72 6f 72 0a 20  l.      (error. 
05e0: 20 20 20 20 20 20 27 72 65 61 64 2d 6e 65 74 73        'read-nets
05f0: 74 72 69 6e 67 0a 20 20 20 20 20 20 20 22 63 6c  tring.       "cl
0600: 69 65 6e 74 20 73 69 64 65 20 70 72 6f 74 6f 63  ient side protoc
0610: 6f 6c 20 65 72 72 6f 72 3a 20 6d 61 6c 66 6f 72  ol error: malfor
0620: 6d 65 64 20 6e 65 74 73 74 72 69 6e 67 20 28 62  med netstring (b
0630: 61 64 20 6c 65 6e 67 74 68 29 22 29 29 0a 20 20  ad length)")).  
0640: 20 20 28 75 6e 6c 65 73 73 20 28 65 71 3f 20 28    (unless (eq? (
0650: 72 65 61 64 2d 63 68 61 72 20 70 6f 72 74 29 20  read-char port) 
0660: 23 5c 3a 29 0a 20 20 20 20 20 20 28 65 72 72 6f  #\:).      (erro
0670: 72 0a 20 20 20 20 20 20 20 27 72 65 61 64 2d 6e  r.       'read-n
0680: 65 74 73 74 72 69 6e 67 0a 20 20 20 20 20 20 20  etstring.       
0690: 22 63 6c 69 65 6e 74 20 73 69 64 65 20 70 72 6f  "client side pro
06a0: 74 6f 63 6f 6c 20 65 72 72 6f 72 3a 20 6d 61 6c  tocol error: mal
06b0: 66 6f 72 6d 65 64 20 6e 65 74 73 74 72 69 6e 67  formed netstring
06c0: 20 28 62 61 64 20 64 65 6c 69 6d 69 74 65 72 29   (bad delimiter)
06d0: 22 29 29 0a 20 20 20 20 28 6c 65 74 20 28 28 73  ")).    (let ((s
06e0: 20 28 72 65 61 64 2d 73 74 72 69 6e 67 20 6c 20   (read-string l 
06f0: 70 6f 72 74 29 29 29 0a 20 20 20 20 20 20 28 75  port))).      (u
0700: 6e 6c 65 73 73 20 28 65 71 3f 20 28 72 65 61 64  nless (eq? (read
0710: 2d 63 68 61 72 20 70 6f 72 74 29 20 23 5c 2c 29  -char port) #\,)
0720: 0a 09 28 65 72 72 6f 72 0a 09 20 27 72 65 61 64  ..(error.. 'read
0730: 2d 6e 65 74 73 74 72 69 6e 67 0a 09 20 22 63 6c  -netstring.. "cl
0740: 69 65 6e 74 20 73 69 64 65 20 70 72 6f 74 6f 63  ient side protoc
0750: 6f 6c 20 65 72 72 6f 72 3a 20 6d 61 6c 66 6f 72  ol error: malfor
0760: 6d 65 64 20 6e 65 74 73 74 72 69 6e 67 20 28 62  med netstring (b
0770: 61 64 20 74 65 72 6d 69 6e 61 6c 29 22 29 29 0a  ad terminal)")).
0780: 20 20 20 20 20 20 73 29 29 29 0a 0a 3b 3b 3b 20        s)))..;;; 
0790: 40 2d 65 78 70 72 65 73 73 69 6f 6e 73 0a 0a 28  @-expressions..(
07a0: 64 65 66 69 6e 65 20 28 6d 61 6b 65 2d 61 74 2d  define (make-at-
07b0: 72 65 61 64 65 72 2b 74 61 62 6c 65 20 61 72 67  reader+table arg
07c0: 73 29 0a 20 20 28 6c 65 74 72 65 63 2a 20 28 28  s).  (letrec* ((
07d0: 63 6f 6d 6d 61 6e 64 2d 63 68 61 72 0a 09 20 20  command-char..  
07e0: 20 20 20 28 67 65 74 2d 6b 65 79 77 6f 72 64 20     (get-keyword 
07f0: 23 3a 63 6f 6d 6d 61 6e 64 2d 63 68 61 72 20 61  #:command-char a
0800: 72 67 73 20 28 63 6f 6e 73 74 61 6e 74 6c 79 20  rgs (constantly 
0810: 23 5c 40 29 29 29 0a 09 20 20 20 20 28 74 72 69  #\@)))..    (tri
0820: 6d 2d 77 68 69 74 65 73 70 61 63 65 3f 0a 09 20  m-whitespace?.. 
0830: 20 20 20 20 28 67 65 74 2d 6b 65 79 77 6f 72 64      (get-keyword
0840: 20 23 3a 74 72 69 6d 2d 77 68 69 74 65 73 70 61   #:trim-whitespa
0850: 63 65 3f 20 61 72 67 73 20 28 63 6f 6e 73 74 61  ce? args (consta
0860: 6e 74 6c 79 20 23 74 29 29 29 0a 09 20 20 20 20  ntly #t)))..    
0870: 28 63 6f 6e 64 65 6e 73 65 2d 77 68 69 74 65 73  (condense-whites
0880: 70 61 63 65 3f 0a 09 20 20 20 20 20 28 67 65 74  pace?..     (get
0890: 2d 6b 65 79 77 6f 72 64 20 23 3a 63 6f 6e 64 65  -keyword #:conde
08a0: 6e 73 65 2d 77 68 69 74 65 73 70 61 63 65 3f 20  nse-whitespace? 
08b0: 61 72 67 73 20 28 63 6f 6e 73 74 61 6e 74 6c 79  args (constantly
08c0: 20 23 74 29 29 29 0a 09 20 20 20 20 28 6c 69 73   #t)))..    (lis
08d0: 74 2d 61 72 67 75 6d 65 6e 74 73 3f 0a 09 20 20  t-arguments?..  
08e0: 20 20 20 28 67 65 74 2d 6b 65 79 77 6f 72 64 20     (get-keyword 
08f0: 23 3a 6c 69 73 74 2d 61 72 67 75 6d 65 6e 74 73  #:list-arguments
0900: 3f 20 61 72 67 73 20 28 63 6f 6e 73 74 61 6e 74  ? args (constant
0910: 6c 79 20 23 66 29 29 29 0a 09 20 20 20 20 28 63  ly #f)))..    (c
0920: 68 61 72 2d 6e 6f 72 6d 61 6c 3f 0a 09 20 20 20  har-normal?..   
0930: 20 20 28 63 75 74 65 20 63 68 61 72 2d 73 65 74    (cute char-set
0940: 2d 63 6f 6e 74 61 69 6e 73 3f 0a 09 09 20 20 20  -contains?...   
0950: 28 63 68 61 72 2d 73 65 74 2d 63 6f 6d 70 6c 65  (char-set-comple
0960: 6d 65 6e 74 0a 09 09 20 20 20 20 28 63 68 61 72  ment...    (char
0970: 2d 73 65 74 20 63 6f 6d 6d 61 6e 64 2d 63 68 61  -set command-cha
0980: 72 20 23 5c 7b 20 23 5c 7d 20 23 5c 72 65 74 75  r #\{ #\} #\retu
0990: 72 6e 20 23 5c 6e 65 77 6c 69 6e 65 29 29 0a 09  rn #\newline))..
09a0: 09 20 20 20 3c 3e 29 29 0a 09 20 20 20 20 28 63  .   <>))..    (c
09b0: 68 61 72 2d 67 72 6f 75 70 3f 0a 09 20 20 20 20  har-group?..    
09c0: 20 28 63 75 74 65 20 63 68 61 72 2d 73 65 74 2d   (cute char-set-
09d0: 63 6f 6e 74 61 69 6e 73 3f 0a 09 09 20 20 20 28  contains?...   (
09e0: 63 68 61 72 2d 73 65 74 20 23 5c 5b 20 23 5c 7b  char-set #\[ #\{
09f0: 29 0a 09 09 20 20 20 3c 3e 29 29 0a 09 20 20 20  )...   <>))..   
0a00: 20 28 73 6b 69 70 2d 77 68 69 74 65 73 70 61 63   (skip-whitespac
0a10: 65 0a 09 20 20 20 20 20 28 6c 61 6d 62 64 61 20  e..     (lambda 
0a20: 28 70 6f 72 74 29 0a 09 20 20 20 20 20 20 20 28  (port)..       (
0a30: 77 68 65 6e 20 28 63 68 61 72 2d 77 68 69 74 65  when (char-white
0a40: 73 70 61 63 65 3f 20 28 70 65 65 6b 2d 63 68 61  space? (peek-cha
0a50: 72 20 70 6f 72 74 29 29 0a 09 09 20 28 72 65 61  r port))... (rea
0a60: 64 2d 63 68 61 72 20 70 6f 72 74 29 0a 09 09 20  d-char port)... 
0a70: 28 73 6b 69 70 2d 77 68 69 74 65 73 70 61 63 65  (skip-whitespace
0a80: 20 70 6f 72 74 29 29 29 29 0a 09 20 20 20 20 28   port))))..    (
0a90: 72 65 61 64 2d 77 68 69 74 65 73 70 61 63 65 0a  read-whitespace.
0aa0: 09 20 20 20 20 20 28 69 66 20 63 6f 6e 64 65 6e  .     (if conden
0ab0: 73 65 2d 77 68 69 74 65 73 70 61 63 65 3f 0a 09  se-whitespace?..
0ac0: 09 20 28 6c 61 6d 62 64 61 20 28 70 6f 72 74 29  . (lambda (port)
0ad0: 0a 09 09 20 20 20 28 73 6b 69 70 2d 77 68 69 74  ...   (skip-whit
0ae0: 65 73 70 61 63 65 20 70 6f 72 74 29 0a 09 09 20  espace port)... 
0af0: 20 20 22 20 22 29 0a 09 09 20 28 63 75 74 20 72    " ")... (cut r
0b00: 65 61 64 2d 74 6f 6b 65 6e 20 63 68 61 72 2d 77  ead-token char-w
0b10: 68 69 74 65 73 70 61 63 65 3f 20 3c 3e 29 29 29  hitespace? <>)))
0b20: 0a 09 20 20 20 20 28 72 65 61 64 2d 64 61 74 75  ..    (read-datu
0b30: 6d 0a 09 20 20 20 20 20 28 6c 61 6d 62 64 61 20  m..     (lambda 
0b40: 28 70 6f 72 74 29 0a 09 20 20 20 20 20 20 20 28  (port)..       (
0b50: 70 61 72 61 6d 65 74 65 72 69 7a 65 20 28 28 63  parameterize ((c
0b60: 75 72 72 65 6e 74 2d 72 65 61 64 2d 74 61 62 6c  urrent-read-tabl
0b70: 65 20 64 61 74 75 6d 2d 72 65 61 64 2d 74 61 62  e datum-read-tab
0b80: 6c 65 29 29 0a 09 09 20 28 72 65 61 64 20 70 6f  le))... (read po
0b90: 72 74 29 29 29 29 0a 09 20 20 20 20 28 72 65 61  rt))))..    (rea
0ba0: 64 2d 61 74 2d 65 78 70 0a 09 20 20 20 20 20 28  d-at-exp..     (
0bb0: 6c 61 6d 62 64 61 20 28 70 6f 72 74 29 0a 09 20  lambda (port).. 
0bc0: 20 20 20 20 20 20 28 73 6b 69 70 2d 77 68 69 74        (skip-whit
0bd0: 65 73 70 61 63 65 20 70 6f 72 74 29 0a 09 20 20  espace port)..  
0be0: 20 20 20 20 20 28 6c 65 74 20 28 28 63 68 61 72       (let ((char
0bf0: 20 28 70 65 65 6b 2d 63 68 61 72 20 70 6f 72 74   (peek-char port
0c00: 29 29 29 0a 09 09 20 28 63 6f 6e 64 0a 09 09 20  )))... (cond... 
0c10: 20 28 28 65 6f 66 2d 6f 62 6a 65 63 74 3f 20 63   ((eof-object? c
0c20: 68 61 72 29 0a 09 09 20 20 20 28 72 65 61 64 2d  har)...   (read-
0c30: 63 68 61 72 20 70 6f 72 74 29 29 0a 09 09 20 20  char port))...  
0c40: 28 65 6c 73 65 0a 09 09 20 20 20 28 77 68 65 6e  (else...   (when
0c50: 20 28 65 71 76 3f 20 63 68 61 72 20 63 6f 6d 6d   (eqv? char comm
0c60: 61 6e 64 2d 63 68 61 72 29 0a 09 09 20 20 20 20  and-char)...    
0c70: 20 28 72 65 61 64 2d 63 68 61 72 20 70 6f 72 74   (read-char port
0c80: 29 29 0a 09 09 20 20 20 28 6c 65 74 2a 20 28 28  ))...   (let* ((
0c90: 68 65 61 64 20 28 61 6e 64 20 28 6e 6f 74 20 28  head (and (not (
0ca0: 63 68 61 72 2d 67 72 6f 75 70 3f 20 28 70 65 65  char-group? (pee
0cb0: 6b 2d 63 68 61 72 20 70 6f 72 74 29 29 29 0a 09  k-char port)))..
0cc0: 09 09 09 20 20 20 20 20 28 72 65 61 64 2d 64 61  ...     (read-da
0cd0: 74 75 6d 20 70 6f 72 74 29 29 29 0a 09 09 09 20  tum port))).... 
0ce0: 20 28 61 72 67 73 20 28 61 6e 64 20 28 65 71 76   (args (and (eqv
0cf0: 3f 20 28 70 65 65 6b 2d 63 68 61 72 20 70 6f 72  ? (peek-char por
0d00: 74 29 20 23 5c 5b 29 0a 09 09 09 09 20 20 20 20  t) #\[).....    
0d10: 20 28 72 65 61 64 2d 64 61 74 75 6d 20 70 6f 72   (read-datum por
0d20: 74 29 29 29 0a 09 09 09 20 20 28 62 6f 64 79 20  t)))....  (body 
0d30: 28 61 6e 64 20 28 65 71 76 3f 20 28 70 65 65 6b  (and (eqv? (peek
0d40: 2d 63 68 61 72 20 70 6f 72 74 29 20 23 5c 7b 29  -char port) #\{)
0d50: 0a 09 09 09 09 20 20 20 20 20 28 72 65 61 64 2d  .....     (read-
0d60: 69 6e 73 69 64 65 2d 61 74 2d 65 78 70 20 27 73  inside-at-exp 's
0d70: 6b 69 70 20 70 6f 72 74 29 29 29 29 0a 09 09 20  kip port))))... 
0d80: 20 20 20 20 28 69 66 20 28 6f 72 20 61 72 67 73      (if (or args
0d90: 20 62 6f 64 79 29 0a 09 09 09 20 28 61 70 70 65   body).... (appe
0da0: 6e 64 21 0a 09 09 09 20 20 28 63 6f 6e 64 0a 09  nd!....  (cond..
0db0: 09 09 20 20 20 28 68 65 61 64 20 3d 3e 20 6c 69  ..   (head => li
0dc0: 73 74 29 0a 09 09 09 20 20 20 28 65 6c 73 65 20  st)....   (else 
0dd0: 27 28 29 29 29 0a 09 09 09 20 20 28 63 6f 6e 64  '()))....  (cond
0de0: 0a 09 09 09 20 20 20 28 28 61 6e 64 20 6c 69 73  ....   ((and lis
0df0: 74 2d 61 72 67 75 6d 65 6e 74 73 3f 20 61 72 67  t-arguments? arg
0e00: 73 29 20 3d 3e 20 6c 69 73 74 29 0a 09 09 09 20  s) => list).... 
0e10: 20 20 28 65 6c 73 65 20 28 6f 72 20 61 72 67 73    (else (or args
0e20: 20 27 28 29 29 29 29 0a 09 09 09 20 20 28 6f 72   '())))....  (or
0e30: 20 62 6f 64 79 20 27 28 29 29 29 0a 09 09 09 20   body '())).... 
0e40: 68 65 61 64 29 29 29 29 29 29 29 0a 09 20 20 20  head)))))))..   
0e50: 20 28 72 65 61 64 2d 69 6e 73 69 64 65 2d 61 74   (read-inside-at
0e60: 2d 65 78 70 0a 09 20 20 20 20 20 28 6c 61 6d 62  -exp..     (lamb
0e70: 64 61 20 28 62 72 61 63 65 2d 6d 6f 64 65 20 70  da (brace-mode p
0e80: 6f 72 74 29 0a 09 20 20 20 20 20 20 20 28 61 70  ort)..       (ap
0e90: 70 65 6e 64 21 0a 09 09 28 6c 65 74 20 28 28 68  pend!...(let ((h
0ea0: 65 61 64 0a 09 09 20 20 20 20 20 20 20 28 63 61  ead...       (ca
0eb0: 73 65 20 62 72 61 63 65 2d 6d 6f 64 65 0a 09 09  se brace-mode...
0ec0: 09 20 28 28 6e 6f 6e 65 29 0a 09 09 09 20 20 27  . ((none)....  '
0ed0: 28 29 29 0a 09 09 09 20 28 28 73 6b 69 70 29 0a  ()).... ((skip).
0ee0: 09 09 09 20 20 28 61 6e 64 20 28 65 71 76 3f 20  ...  (and (eqv? 
0ef0: 28 70 65 65 6b 2d 63 68 61 72 20 70 6f 72 74 29  (peek-char port)
0f00: 20 23 5c 7b 29 0a 09 09 09 20 20 20 20 20 20 20   #\{)....       
0f10: 28 62 65 67 69 6e 20 28 72 65 61 64 2d 63 68 61  (begin (read-cha
0f20: 72 20 70 6f 72 74 29 20 27 28 29 29 29 29 0a 09  r port) '())))..
0f30: 09 09 20 28 65 6c 73 65 0a 09 09 09 20 20 28 61  .. (else....  (a
0f40: 6e 64 20 28 65 71 76 3f 20 28 70 65 65 6b 2d 63  nd (eqv? (peek-c
0f50: 68 61 72 20 70 6f 72 74 29 20 23 5c 7b 29 0a 09  har port) #\{)..
0f60: 09 09 20 20 20 20 20 20 20 28 6c 69 73 74 20 28  ..       (list (
0f70: 73 74 72 69 6e 67 20 28 72 65 61 64 2d 63 68 61  string (read-cha
0f80: 72 20 70 6f 72 74 29 29 29 29 29 29 29 29 0a 09  r port))))))))..
0f90: 09 20 20 28 69 66 20 68 65 61 64 0a 09 09 20 20  .  (if head...  
0fa0: 20 20 20 20 28 62 65 67 69 6e 0a 09 09 09 28 77      (begin....(w
0fb0: 68 65 6e 20 74 72 69 6d 2d 77 68 69 74 65 73 70  hen trim-whitesp
0fc0: 61 63 65 3f 20 28 73 6b 69 70 2d 77 68 69 74 65  ace? (skip-white
0fd0: 73 70 61 63 65 20 70 6f 72 74 29 29 0a 09 09 09  space port))....
0fe0: 68 65 61 64 29 0a 09 09 20 20 20 20 20 20 28 73  head)...      (s
0ff0: 79 6e 74 61 78 2d 65 72 72 6f 72 0a 09 09 20 20  yntax-error...  
1000: 20 20 20 20 20 27 72 65 61 64 2d 69 6e 73 69 64       'read-insid
1010: 65 2d 61 74 2d 65 78 70 20 22 65 78 70 65 63 74  e-at-exp "expect
1020: 65 64 20 40 2d 65 78 70 72 65 73 73 69 6f 6e 20  ed @-expression 
1030: 62 6f 64 79 2c 20 66 6f 75 6e 64 22 0a 09 09 20  body, found"... 
1040: 20 20 20 20 20 20 28 70 65 65 6b 2d 63 68 61 72        (peek-char
1050: 20 70 6f 72 74 29 29 29 29 0a 09 09 28 6c 65 74   port))))...(let
1060: 20 6d 6f 72 65 20 28 29 0a 09 09 20 20 28 6c 65   more ()...  (le
1070: 74 20 28 28 63 68 61 72 20 28 70 65 65 6b 2d 63  t ((char (peek-c
1080: 68 61 72 20 70 6f 72 74 29 29 29 0a 09 09 20 20  har port)))...  
1090: 20 20 28 63 6f 6e 64 0a 09 09 20 20 20 20 20 28    (cond...     (
10a0: 28 65 71 76 3f 20 63 68 61 72 20 23 5c 7b 29 0a  (eqv? char #\{).
10b0: 09 09 20 20 20 20 20 20 28 63 61 73 65 20 62 72  ..      (case br
10c0: 61 63 65 2d 6d 6f 64 65 0a 09 09 09 28 28 6e 6f  ace-mode....((no
10d0: 6e 65 29 0a 09 09 09 20 28 63 6f 6e 73 20 28 73  ne).... (cons (s
10e0: 74 72 69 6e 67 20 28 72 65 61 64 2d 63 68 61 72  tring (read-char
10f0: 20 70 6f 72 74 29 29 20 28 6d 6f 72 65 29 29 29   port)) (more)))
1100: 0a 09 09 09 28 65 6c 73 65 0a 09 09 09 20 28 61  ....(else.... (a
1110: 70 70 65 6e 64 21 20 28 72 65 61 64 2d 69 6e 73  ppend! (read-ins
1120: 69 64 65 2d 61 74 2d 65 78 70 20 27 6b 65 65 70  ide-at-exp 'keep
1130: 20 70 6f 72 74 29 20 28 6d 6f 72 65 29 29 29 29   port) (more))))
1140: 29 0a 09 09 20 20 20 20 20 28 28 65 71 76 3f 20  )...     ((eqv? 
1150: 63 68 61 72 20 23 5c 7d 29 0a 09 09 20 20 20 20  char #\})...    
1160: 20 20 28 63 61 73 65 20 62 72 61 63 65 2d 6d 6f    (case brace-mo
1170: 64 65 0a 09 09 09 28 28 6e 6f 6e 65 29 0a 09 09  de....((none)...
1180: 09 20 28 63 6f 6e 73 20 28 73 74 72 69 6e 67 20  . (cons (string 
1190: 28 72 65 61 64 2d 63 68 61 72 20 70 6f 72 74 29  (read-char port)
11a0: 29 20 28 6d 6f 72 65 29 29 29 0a 09 09 09 28 28  ) (more)))....((
11b0: 73 6b 69 70 29 0a 09 09 09 20 28 72 65 61 64 2d  skip).... (read-
11c0: 63 68 61 72 20 70 6f 72 74 29 0a 09 09 09 20 27  char port).... '
11d0: 28 29 29 0a 09 09 09 28 65 6c 73 65 0a 09 09 09  ())....(else....
11e0: 20 28 6c 69 73 74 20 28 73 74 72 69 6e 67 20 28   (list (string (
11f0: 72 65 61 64 2d 63 68 61 72 20 70 6f 72 74 29 29  read-char port))
1200: 29 29 29 29 0a 09 09 20 20 20 20 20 28 28 65 6f  ))))...     ((eo
1210: 66 2d 6f 62 6a 65 63 74 3f 20 63 68 61 72 29 0a  f-object? char).
1220: 09 09 20 20 20 20 20 20 28 63 61 73 65 20 62 72  ..      (case br
1230: 61 63 65 2d 6d 6f 64 65 0a 09 09 09 28 28 6e 6f  ace-mode....((no
1240: 6e 65 29 0a 09 09 09 20 28 72 65 61 64 2d 63 68  ne).... (read-ch
1250: 61 72 20 70 6f 72 74 29 0a 09 09 09 20 27 28 29  ar port).... '()
1260: 29 0a 09 09 09 28 65 6c 73 65 0a 09 09 09 20 28  )....(else.... (
1270: 73 79 6e 74 61 78 2d 65 72 72 6f 72 0a 09 09 09  syntax-error....
1280: 20 20 27 72 65 61 64 2d 69 6e 73 69 64 65 2d 61    'read-inside-a
1290: 74 2d 65 78 70 20 22 40 2d 65 78 70 72 65 73 73  t-exp "@-express
12a0: 69 6f 6e 20 62 6f 64 79 20 6e 6f 74 20 63 6c 6f  ion body not clo
12b0: 73 65 64 22 29 29 29 29 0a 09 09 20 20 20 20 20  sed"))))...     
12c0: 28 28 65 71 76 3f 20 63 68 61 72 20 63 6f 6d 6d  ((eqv? char comm
12d0: 61 6e 64 2d 63 68 61 72 29 0a 09 09 20 20 20 20  and-char)...    
12e0: 20 20 28 63 6f 6e 73 20 28 72 65 61 64 2d 61 74    (cons (read-at
12f0: 2d 65 78 70 20 70 6f 72 74 29 20 28 6d 6f 72 65  -exp port) (more
1300: 29 29 29 0a 09 09 20 20 20 20 20 28 28 63 68 61  )))...     ((cha
1310: 72 2d 77 68 69 74 65 73 70 61 63 65 3f 20 63 68  r-whitespace? ch
1320: 61 72 29 0a 09 09 20 20 20 20 20 20 28 6c 65 74  ar)...      (let
1330: 2a 20 28 28 68 65 61 64 20 28 72 65 61 64 2d 77  * ((head (read-w
1340: 68 69 74 65 73 70 61 63 65 20 70 6f 72 74 29 29  hitespace port))
1350: 0a 09 09 09 20 20 20 20 20 28 74 61 69 6c 20 28  ....     (tail (
1360: 6d 6f 72 65 29 29 29 0a 09 09 09 28 69 66 20 28  more)))....(if (
1370: 6f 72 20 28 70 61 69 72 3f 20 74 61 69 6c 29 20  or (pair? tail) 
1380: 28 6e 6f 74 20 74 72 69 6d 2d 77 68 69 74 65 73  (not trim-whites
1390: 70 61 63 65 3f 29 29 0a 09 09 09 20 20 20 20 28  pace?))....    (
13a0: 63 6f 6e 73 20 68 65 61 64 20 74 61 69 6c 29 0a  cons head tail).
13b0: 09 09 09 20 20 20 20 74 61 69 6c 29 29 29 0a 09  ...    tail)))..
13c0: 09 20 20 20 20 20 28 65 6c 73 65 0a 09 09 20 20  .     (else...  
13d0: 20 20 20 20 28 63 6f 6e 73 20 28 72 65 61 64 2d      (cons (read-
13e0: 74 6f 6b 65 6e 20 63 68 61 72 2d 6e 6f 72 6d 61  token char-norma
13f0: 6c 3f 20 70 6f 72 74 29 20 28 6d 6f 72 65 29 29  l? port) (more))
1400: 29 29 29 29 29 29 29 0a 09 20 20 20 20 28 72 65  )))))))..    (re
1410: 61 64 2d 74 61 62 6c 65 0a 09 20 20 20 20 20 28  ad-table..     (
1420: 67 65 74 2d 6b 65 79 77 6f 72 64 20 23 3a 72 65  get-keyword #:re
1430: 61 64 2d 74 61 62 6c 65 20 61 72 67 73 20 63 75  ad-table args cu
1440: 72 72 65 6e 74 2d 72 65 61 64 2d 74 61 62 6c 65  rrent-read-table
1450: 29 29 0a 09 20 20 20 20 28 61 74 2d 72 65 61 64  ))..    (at-read
1460: 2d 74 61 62 6c 65 0a 09 20 20 20 20 20 28 70 61  -table..     (pa
1470: 72 61 6d 65 74 65 72 69 7a 65 20 28 28 63 75 72  rameterize ((cur
1480: 72 65 6e 74 2d 72 65 61 64 2d 74 61 62 6c 65 20  rent-read-table 
1490: 28 63 6f 70 79 2d 72 65 61 64 2d 74 61 62 6c 65  (copy-read-table
14a0: 20 72 65 61 64 2d 74 61 62 6c 65 29 29 29 0a 09   read-table)))..
14b0: 20 20 20 20 20 20 20 28 73 65 74 2d 72 65 61 64         (set-read
14c0: 2d 73 79 6e 74 61 78 21 20 63 6f 6d 6d 61 6e 64  -syntax! command
14d0: 2d 63 68 61 72 20 72 65 61 64 2d 61 74 2d 65 78  -char read-at-ex
14e0: 70 29 0a 09 20 20 20 20 20 20 20 28 63 75 72 72  p)..       (curr
14f0: 65 6e 74 2d 72 65 61 64 2d 74 61 62 6c 65 29 29  ent-read-table))
1500: 29 0a 09 20 20 20 20 28 64 61 74 75 6d 2d 72 65  )..    (datum-re
1510: 61 64 2d 74 61 62 6c 65 0a 09 20 20 20 20 20 28  ad-table..     (
1520: 6c 65 74 20 28 28 73 70 65 63 20 28 67 65 74 2d  let ((spec (get-
1530: 6b 65 79 77 6f 72 64 20 23 3a 64 61 74 75 6d 2d  keyword #:datum-
1540: 72 65 61 64 2d 74 61 62 6c 65 20 61 72 67 73 20  read-table args 
1550: 28 63 6f 6e 73 74 61 6e 74 6c 79 20 23 74 29 29  (constantly #t))
1560: 29 29 0a 09 20 20 20 20 20 20 20 28 63 6f 6e 64  ))..       (cond
1570: 0a 09 09 28 28 70 72 6f 63 65 64 75 72 65 3f 20  ...((procedure? 
1580: 73 70 65 63 29 0a 09 09 20 28 73 70 65 63 20 61  spec)... (spec a
1590: 74 2d 72 65 61 64 2d 74 61 62 6c 65 29 29 0a 09  t-read-table))..
15a0: 09 28 73 70 65 63 0a 09 09 20 61 74 2d 72 65 61  .(spec... at-rea
15b0: 64 2d 74 61 62 6c 65 29 0a 09 09 28 65 6c 73 65  d-table)...(else
15c0: 0a 09 09 20 72 65 61 64 2d 74 61 62 6c 65 29 29  ... read-table))
15d0: 29 29 29 0a 20 20 20 20 28 76 61 6c 75 65 73 0a  ))).    (values.
15e0: 20 20 20 20 20 28 69 66 20 28 67 65 74 2d 6b 65       (if (get-ke
15f0: 79 77 6f 72 64 20 23 3a 69 6e 73 69 64 65 3f 20  yword #:inside? 
1600: 61 72 67 73 29 0a 09 20 28 6c 61 6d 62 64 61 20  args).. (lambda 
1610: 28 23 21 6f 70 74 69 6f 6e 61 6c 20 28 70 6f 72  (#!optional (por
1620: 74 20 28 63 75 72 72 65 6e 74 2d 69 6e 70 75 74  t (current-input
1630: 2d 70 6f 72 74 29 29 29 0a 09 20 20 20 28 72 65  -port)))..   (re
1640: 61 64 2d 69 6e 73 69 64 65 2d 61 74 2d 65 78 70  ad-inside-at-exp
1650: 20 27 6e 6f 6e 65 20 70 6f 72 74 29 29 0a 09 20   'none port)).. 
1660: 28 6c 61 6d 62 64 61 20 28 23 21 6f 70 74 69 6f  (lambda (#!optio
1670: 6e 61 6c 20 28 70 6f 72 74 20 28 63 75 72 72 65  nal (port (curre
1680: 6e 74 2d 69 6e 70 75 74 2d 70 6f 72 74 29 29 29  nt-input-port)))
1690: 0a 09 20 20 20 28 72 65 61 64 2d 61 74 2d 65 78  ..   (read-at-ex
16a0: 70 20 70 6f 72 74 29 29 29 0a 20 20 20 20 20 61  p port))).     a
16b0: 74 2d 72 65 61 64 2d 74 61 62 6c 65 29 29 29 0a  t-read-table))).
16c0: 0a 28 64 65 66 69 6e 65 20 28 6d 61 6b 65 2d 61  .(define (make-a
16d0: 74 2d 72 65 61 64 65 72 20 2e 20 61 72 67 73 29  t-reader . args)
16e0: 0a 20 20 28 6e 74 68 2d 76 61 6c 75 65 20 30 20  .  (nth-value 0 
16f0: 28 6d 61 6b 65 2d 61 74 2d 72 65 61 64 65 72 2b  (make-at-reader+
1700: 74 61 62 6c 65 20 61 72 67 73 29 29 29 0a 0a 28  table args)))..(
1710: 64 65 66 69 6e 65 20 28 6d 61 6b 65 2d 61 74 2d  define (make-at-
1720: 72 65 61 64 2d 74 61 62 6c 65 20 2e 20 61 72 67  read-table . arg
1730: 73 29 0a 20 20 28 6e 74 68 2d 76 61 6c 75 65 20  s).  (nth-value 
1740: 31 20 28 6d 61 6b 65 2d 61 74 2d 72 65 61 64 65  1 (make-at-reade
1750: 72 2b 74 61 62 6c 65 20 61 72 67 73 29 29 29 0a  r+table args))).
1760: 0a 28 64 65 66 69 6e 65 20 28 75 73 65 2d 61 74  .(define (use-at
1770: 2d 72 65 61 64 2d 74 61 62 6c 65 20 2e 20 61 72  -read-table . ar
1780: 67 73 29 0a 20 20 28 63 75 72 72 65 6e 74 2d 72  gs).  (current-r
1790: 65 61 64 2d 74 61 62 6c 65 20 28 6e 74 68 2d 76  ead-table (nth-v
17a0: 61 6c 75 65 20 31 20 28 6d 61 6b 65 2d 61 74 2d  alue 1 (make-at-
17b0: 72 65 61 64 65 72 2b 74 61 62 6c 65 20 61 72 67  reader+table arg
17c0: 73 29 29 29 29 0a 0a 3b 3b 3b 20 55 52 49 20 65  s))))..;;; URI e
17d0: 6e 63 6f 64 69 6e 67 0a 0a 28 64 65 66 69 6e 65  ncoding..(define
17e0: 20 75 72 69 2d 65 6e 63 6f 64 65 0a 20 20 28 6c   uri-encode.  (l
17f0: 65 74 20 28 28 70 72 6f 62 6c 65 6d 61 74 69 63  et ((problematic
1800: 2d 72 78 20 28 69 72 72 65 67 65 78 20 27 28 7e  -rx (irregex '(~
1810: 20 28 6f 72 20 61 6c 70 68 61 6e 75 6d 65 72 69   (or alphanumeri
1820: 63 20 22 2d 2e 5f 7e 22 29 29 29 29 29 0a 20 20  c "-._~"))))).  
1830: 20 20 28 6c 61 6d 62 64 61 20 28 73 29 0a 20 20    (lambda (s).  
1840: 20 20 20 20 28 69 72 72 65 67 65 78 2d 72 65 70      (irregex-rep
1850: 6c 61 63 65 2f 61 6c 6c 0a 20 20 20 20 20 20 20  lace/all.       
1860: 70 72 6f 62 6c 65 6d 61 74 69 63 2d 72 78 20 73  problematic-rx s
1870: 0a 20 20 20 20 20 20 20 28 6c 61 6d 62 64 61 20  .       (lambda 
1880: 28 6d 29 0a 09 20 28 73 74 72 69 6e 67 2d 61 70  (m).. (string-ap
1890: 70 65 6e 64 0a 09 20 20 22 25 22 0a 09 20 20 28  pend..  "%"..  (
18a0: 73 74 72 69 6e 67 2d 70 61 64 0a 09 20 20 20 28  string-pad..   (
18b0: 6e 75 6d 62 65 72 2d 3e 73 74 72 69 6e 67 0a 09  number->string..
18c0: 20 20 20 20 28 63 68 61 72 2d 3e 69 6e 74 65 67      (char->integ
18d0: 65 72 20 28 73 74 72 69 6e 67 2d 72 65 66 20 28  er (string-ref (
18e0: 69 72 72 65 67 65 78 2d 6d 61 74 63 68 2d 73 75  irregex-match-su
18f0: 62 73 74 72 69 6e 67 20 6d 29 20 30 29 29 20 31  bstring m) 0)) 1
1900: 36 29 0a 09 20 20 20 32 20 23 5c 30 29 29 29 29  6)..   2 #\0))))
1910: 29 29 29 0a 0a 28 64 65 66 69 6e 65 20 75 72 69  )))..(define uri
1920: 2d 64 65 63 6f 64 65 0a 20 20 28 6c 65 74 20 28  -decode.  (let (
1930: 28 65 73 63 61 70 65 2d 72 78 20 28 69 72 72 65  (escape-rx (irre
1940: 67 65 78 20 27 28 6f 72 20 23 5c 2b 20 28 3a 20  gex '(or #\+ (: 
1950: 23 5c 25 20 28 24 20 28 3d 20 32 20 68 65 78 2d  #\% ($ (= 2 hex-
1960: 64 69 67 69 74 29 29 29 29 29 29 29 0a 20 20 20  digit))))))).   
1970: 20 28 6c 61 6d 62 64 61 20 28 73 29 0a 20 20 20   (lambda (s).   
1980: 20 20 20 28 69 72 72 65 67 65 78 2d 72 65 70 6c     (irregex-repl
1990: 61 63 65 2f 61 6c 6c 0a 20 20 20 20 20 20 20 65  ace/all.       e
19a0: 73 63 61 70 65 2d 72 78 20 73 0a 20 20 20 20 20  scape-rx s.     
19b0: 20 20 28 6c 61 6d 62 64 61 20 28 6d 29 0a 09 20    (lambda (m).. 
19c0: 28 63 61 73 65 20 28 73 74 72 69 6e 67 2d 72 65  (case (string-re
19d0: 66 20 73 20 28 69 72 72 65 67 65 78 2d 6d 61 74  f s (irregex-mat
19e0: 63 68 2d 73 74 61 72 74 2d 69 6e 64 65 78 20 6d  ch-start-index m
19f0: 29 29 0a 09 20 20 20 28 28 23 5c 2b 29 0a 09 20  ))..   ((#\+).. 
1a00: 20 20 20 22 20 22 29 0a 09 20 20 20 28 28 23 5c     " ")..   ((#\
1a10: 25 29 20 0a 09 20 20 20 20 28 73 74 72 69 6e 67  %) ..    (string
1a20: 0a 09 20 20 20 20 20 28 69 6e 74 65 67 65 72 2d  ..     (integer-
1a30: 3e 63 68 61 72 0a 09 20 20 20 20 20 20 28 73 74  >char..      (st
1a40: 72 69 6e 67 2d 3e 6e 75 6d 62 65 72 20 28 69 72  ring->number (ir
1a50: 72 65 67 65 78 2d 6d 61 74 63 68 2d 73 75 62 73  regex-match-subs
1a60: 74 72 69 6e 67 20 6d 20 31 29 20 31 36 29 29 29  tring m 1) 16)))
1a70: 29 29 29 29 29 29 29 0a 0a 3b 3b 3b 20 42 61 73  )))))))..;;; Bas
1a80: 65 36 34 55 52 49 20 65 6e 63 6f 64 69 6e 67 0a  e64URI encoding.
1a90: 0a 28 64 65 66 69 6e 65 20 62 61 73 65 36 34 2d  .(define base64-
1aa0: 61 6c 70 68 61 62 65 74 0a 20 20 22 41 42 43 44  alphabet.  "ABCD
1ab0: 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54  EFGHIJKLMNOPQRST
1ac0: 55 56 57 58 59 5a 61 62 63 64 65 66 67 68 69 6a  UVWXYZabcdefghij
1ad0: 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a  klmnopqrstuvwxyz
1ae0: 30 31 32 33 34 35 36 37 38 39 2b 2f 22 29 0a 28  0123456789+/").(
1af0: 64 65 66 69 6e 65 20 62 61 73 65 36 34 2d 61 6c  define base64-al
1b00: 70 68 61 62 65 74 2f 75 72 69 0a 20 20 22 41 42  phabet/uri.  "AB
1b10: 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52  CDEFGHIJKLMNOPQR
1b20: 53 54 55 56 57 58 59 5a 61 62 63 64 65 66 67 68  STUVWXYZabcdefgh
1b30: 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78  ijklmnopqrstuvwx
1b40: 79 7a 30 31 32 33 34 35 36 37 38 39 2d 5f 22 29  yz0123456789-_")
1b50: 0a 0a 28 64 65 66 69 6e 65 20 28 62 61 73 65 36  ..(define (base6
1b60: 34 2d 65 6e 63 6f 64 65 20 73 20 23 21 6f 70 74  4-encode s #!opt
1b70: 69 6f 6e 61 6c 20 75 72 69 2d 73 61 66 65 3f 29  ional uri-safe?)
1b80: 0a 20 20 28 6c 65 74 2a 20 28 28 61 6c 70 68 61  .  (let* ((alpha
1b90: 62 65 74 20 28 69 66 20 75 72 69 2d 73 61 66 65  bet (if uri-safe
1ba0: 3f 20 62 61 73 65 36 34 2d 61 6c 70 68 61 62 65  ? base64-alphabe
1bb0: 74 2f 75 72 69 20 62 61 73 65 36 34 2d 61 6c 70  t/uri base64-alp
1bc0: 68 61 62 65 74 29 29 0a 09 20 28 6e 20 28 73 74  habet)).. (n (st
1bd0: 72 69 6e 67 2d 6c 65 6e 67 74 68 20 73 29 29 0a  ring-length s)).
1be0: 09 20 28 65 20 28 6d 61 6b 65 2d 73 74 72 69 6e  . (e (make-strin
1bf0: 67 20 28 69 6e 65 78 61 63 74 2d 3e 65 78 61 63  g (inexact->exac
1c00: 74 20 28 63 65 69 6c 69 6e 67 20 28 2a 20 34 2f  t (ceiling (* 4/
1c10: 33 20 6e 29 29 29 29 29 29 0a 20 20 20 20 28 64  3 n)))))).    (d
1c20: 6f 20 28 28 69 73 20 30 20 28 66 78 2b 20 69 73  o ((is 0 (fx+ is
1c30: 20 33 29 29 20 28 69 65 20 30 20 28 66 78 2b 20   3)) (ie 0 (fx+ 
1c40: 69 65 20 34 29 29 29 20 28 28 66 78 3e 3d 20 69  ie 4))) ((fx>= i
1c50: 73 20 6e 29 20 65 29 0a 20 20 20 20 20 20 28 6c  s n) e).      (l
1c60: 65 74 20 28 28 69 20 28 66 78 69 6f 72 0a 09 09  et ((i (fxior...
1c70: 28 66 78 73 68 6c 20 28 63 68 61 72 2d 3e 69 6e  (fxshl (char->in
1c80: 74 65 67 65 72 20 28 73 74 72 69 6e 67 2d 72 65  teger (string-re
1c90: 66 20 73 20 69 73 29 29 20 31 36 29 0a 09 09 28  f s is)) 16)...(
1ca0: 69 66 20 28 66 78 3c 20 28 66 78 2b 20 69 73 20  if (fx< (fx+ is 
1cb0: 31 29 20 6e 29 0a 09 09 20 20 20 20 28 66 78 69  1) n)...    (fxi
1cc0: 6f 72 0a 09 09 20 20 20 20 20 28 66 78 73 68 6c  or...     (fxshl
1cd0: 20 28 63 68 61 72 2d 3e 69 6e 74 65 67 65 72 20   (char->integer 
1ce0: 28 73 74 72 69 6e 67 2d 72 65 66 20 73 20 28 66  (string-ref s (f
1cf0: 78 2b 20 69 73 20 31 29 29 29 20 38 29 0a 09 09  x+ is 1))) 8)...
1d00: 20 20 20 20 20 28 69 66 20 28 66 78 3c 20 28 66       (if (fx< (f
1d10: 78 2b 20 69 73 20 32 29 20 6e 29 0a 09 09 09 20  x+ is 2) n).... 
1d20: 28 63 68 61 72 2d 3e 69 6e 74 65 67 65 72 20 28  (char->integer (
1d30: 73 74 72 69 6e 67 2d 72 65 66 20 73 20 28 66 78  string-ref s (fx
1d40: 2b 20 69 73 20 32 29 29 29 0a 09 09 09 20 30 29  + is 2))).... 0)
1d50: 29 0a 09 09 20 20 20 20 30 29 29 29 29 0a 09 28  )...    0))))..(
1d60: 73 74 72 69 6e 67 2d 73 65 74 21 0a 09 20 65 20  string-set!.. e 
1d70: 69 65 0a 09 20 28 73 74 72 69 6e 67 2d 72 65 66  ie.. (string-ref
1d80: 20 61 6c 70 68 61 62 65 74 20 28 66 78 61 6e 64   alphabet (fxand
1d90: 20 28 66 78 73 68 72 20 69 20 31 38 29 20 23 62   (fxshr i 18) #b
1da0: 31 31 31 31 31 31 29 29 29 0a 09 28 73 74 72 69  111111)))..(stri
1db0: 6e 67 2d 73 65 74 21 0a 09 20 65 20 28 66 78 2b  ng-set!.. e (fx+
1dc0: 20 69 65 20 31 29 0a 09 20 28 73 74 72 69 6e 67   ie 1).. (string
1dd0: 2d 72 65 66 20 61 6c 70 68 61 62 65 74 20 28 66  -ref alphabet (f
1de0: 78 61 6e 64 20 28 66 78 73 68 72 20 69 20 31 32  xand (fxshr i 12
1df0: 29 20 23 62 31 31 31 31 31 31 29 29 29 0a 09 28  ) #b111111)))..(
1e00: 77 68 65 6e 20 28 66 78 3c 20 28 66 78 2b 20 69  when (fx< (fx+ i
1e10: 73 20 31 29 20 6e 29 0a 09 20 20 28 73 74 72 69  s 1) n)..  (stri
1e20: 6e 67 2d 73 65 74 21 0a 09 20 20 20 65 20 28 66  ng-set!..   e (f
1e30: 78 2b 20 69 65 20 32 29 0a 09 20 20 20 28 73 74  x+ ie 2)..   (st
1e40: 72 69 6e 67 2d 72 65 66 20 61 6c 70 68 61 62 65  ring-ref alphabe
1e50: 74 20 28 66 78 61 6e 64 20 28 66 78 73 68 72 20  t (fxand (fxshr 
1e60: 69 20 36 29 20 23 62 31 31 31 31 31 31 29 29 29  i 6) #b111111)))
1e70: 0a 09 20 20 28 77 68 65 6e 20 28 66 78 3c 20 28  ..  (when (fx< (
1e80: 66 78 2b 20 69 73 20 32 29 20 6e 29 0a 09 20 20  fx+ is 2) n)..  
1e90: 20 20 28 73 74 72 69 6e 67 2d 73 65 74 21 0a 09    (string-set!..
1ea0: 20 20 20 20 20 65 20 28 66 78 2b 20 69 65 20 33       e (fx+ ie 3
1eb0: 29 0a 09 20 20 20 20 20 28 73 74 72 69 6e 67 2d  )..     (string-
1ec0: 72 65 66 20 61 6c 70 68 61 62 65 74 20 28 66 78  ref alphabet (fx
1ed0: 61 6e 64 20 69 20 23 62 31 31 31 31 31 31 29 29  and i #b111111))
1ee0: 29 29 29 29 29 29 29 0a 0a 28 64 65 66 69 6e 65  )))))))..(define
1ef0: 20 62 61 73 65 36 34 2d 64 65 63 6f 64 65 0a 20   base64-decode. 
1f00: 20 28 6c 65 74 20 28 28 61 6c 70 68 61 62 65 74   (let ((alphabet
1f10: 2d 72 65 66 0a 09 20 28 6c 65 74 2a 20 28 28 6e  -ref.. (let* ((n
1f20: 20 28 73 74 72 69 6e 67 2d 6c 65 6e 67 74 68 20   (string-length 
1f30: 62 61 73 65 36 34 2d 61 6c 70 68 61 62 65 74 29  base64-alphabet)
1f40: 29 0a 09 09 28 61 6c 70 68 61 62 65 74 20 28 6d  )...(alphabet (m
1f50: 61 6b 65 2d 68 61 73 68 2d 74 61 62 6c 65 20 65  ake-hash-table e
1f60: 71 76 3f 20 65 71 76 3f 2d 68 61 73 68 20 28 66  qv? eqv?-hash (f
1f70: 78 2b 20 6e 20 32 29 29 29 29 0a 09 20 20 20 28  x+ n 2))))..   (
1f80: 64 6f 20 28 28 69 20 30 20 28 66 78 2b 20 69 20  do ((i 0 (fx+ i 
1f90: 31 29 29 29 20 28 28 66 78 3e 3d 20 69 20 6e 29  1))) ((fx>= i n)
1fa0: 29 0a 09 20 20 20 20 20 28 68 61 73 68 2d 74 61  )..     (hash-ta
1fb0: 62 6c 65 2d 73 65 74 21 20 61 6c 70 68 61 62 65  ble-set! alphabe
1fc0: 74 20 28 73 74 72 69 6e 67 2d 72 65 66 20 62 61  t (string-ref ba
1fd0: 73 65 36 34 2d 61 6c 70 68 61 62 65 74 20 69 29  se64-alphabet i)
1fe0: 20 69 29 29 0a 09 20 20 20 28 64 6f 20 28 28 69   i))..   (do ((i
1ff0: 20 28 66 78 2d 20 6e 20 32 29 20 28 66 78 2b 20   (fx- n 2) (fx+ 
2000: 69 20 31 29 29 29 20 28 28 66 78 3e 3d 20 69 20  i 1))) ((fx>= i 
2010: 6e 29 29 0a 09 20 20 20 20 20 28 68 61 73 68 2d  n))..     (hash-
2020: 74 61 62 6c 65 2d 73 65 74 21 20 61 6c 70 68 61  table-set! alpha
2030: 62 65 74 20 28 73 74 72 69 6e 67 2d 72 65 66 20  bet (string-ref 
2040: 62 61 73 65 36 34 2d 61 6c 70 68 61 62 65 74 2f  base64-alphabet/
2050: 75 72 69 20 69 29 20 69 29 29 0a 09 20 20 20 28  uri i) i))..   (
2060: 6c 61 6d 62 64 61 20 28 63 68 72 29 0a 09 20 20  lambda (chr)..  
2070: 20 20 20 28 68 61 73 68 2d 74 61 62 6c 65 2d 72     (hash-table-r
2080: 65 66 0a 09 20 20 20 20 20 20 61 6c 70 68 61 62  ef..      alphab
2090: 65 74 20 63 68 72 0a 09 20 20 20 20 20 20 28 63  et chr..      (c
20a0: 75 74 20 73 79 6e 74 61 78 2d 65 72 72 6f 72 20  ut syntax-error 
20b0: 27 62 61 73 65 36 34 2d 64 65 63 6f 64 65 20 22  'base64-decode "
20c0: 69 6c 6c 65 67 61 6c 20 63 68 61 72 61 63 74 65  illegal characte
20d0: 72 22 20 63 68 72 29 29 29 29 29 29 0a 20 20 20  r" chr)))))).   
20e0: 20 28 6c 61 6d 62 64 61 20 28 65 29 0a 20 20 20   (lambda (e).   
20f0: 20 20 20 28 6c 65 74 2a 20 28 28 6e 20 28 73 74     (let* ((n (st
2100: 72 69 6e 67 2d 6c 65 6e 67 74 68 20 65 29 29 0a  ring-length e)).
2110: 09 20 20 20 20 20 28 73 20 28 6d 61 6b 65 2d 73  .     (s (make-s
2120: 74 72 69 6e 67 20 28 69 6e 65 78 61 63 74 2d 3e  tring (inexact->
2130: 65 78 61 63 74 20 28 66 6c 6f 6f 72 20 28 2a 20  exact (floor (* 
2140: 33 2f 34 20 6e 29 29 29 29 29 29 0a 09 28 64 6f  3/4 n))))))..(do
2150: 20 28 28 69 65 20 30 20 28 66 78 2b 20 69 65 20   ((ie 0 (fx+ ie 
2160: 34 29 29 20 28 69 73 20 30 20 28 66 78 2b 20 69  4)) (is 0 (fx+ i
2170: 73 20 33 29 29 29 20 28 28 66 78 3e 3d 20 69 65  s 3))) ((fx>= ie
2180: 20 6e 29 20 73 29 0a 09 20 20 28 6c 65 74 20 28   n) s)..  (let (
2190: 28 69 20 28 66 78 69 6f 72 0a 09 09 20 20 20 20  (i (fxior...    
21a0: 28 66 78 73 68 6c 0a 09 09 20 20 20 20 20 28 61  (fxshl...     (a
21b0: 6c 70 68 61 62 65 74 2d 72 65 66 20 28 73 74 72  lphabet-ref (str
21c0: 69 6e 67 2d 72 65 66 20 65 20 69 65 29 29 20 31  ing-ref e ie)) 1
21d0: 38 29 0a 09 09 20 20 20 20 28 69 66 20 28 66 78  8)...    (if (fx
21e0: 3c 20 28 66 78 2b 20 69 65 20 31 29 20 6e 29 0a  < (fx+ ie 1) n).
21f0: 09 09 09 28 66 78 69 6f 72 0a 09 09 09 20 28 66  ...(fxior.... (f
2200: 78 73 68 6c 0a 09 09 09 20 20 28 61 6c 70 68 61  xshl....  (alpha
2210: 62 65 74 2d 72 65 66 20 28 73 74 72 69 6e 67 2d  bet-ref (string-
2220: 72 65 66 20 65 20 28 66 78 2b 20 69 65 20 31 29  ref e (fx+ ie 1)
2230: 29 29 20 31 32 29 0a 09 09 09 20 28 69 66 20 28  )) 12).... (if (
2240: 66 78 3c 20 28 66 78 2b 20 69 65 20 32 29 20 6e  fx< (fx+ ie 2) n
2250: 29 0a 09 09 09 20 20 20 20 20 28 66 78 69 6f 72  )....     (fxior
2260: 0a 09 09 09 20 20 20 20 20 20 28 66 78 73 68 6c  ....      (fxshl
2270: 0a 09 09 09 20 20 20 20 20 20 20 28 61 6c 70 68  ....       (alph
2280: 61 62 65 74 2d 72 65 66 20 28 73 74 72 69 6e 67  abet-ref (string
2290: 2d 72 65 66 20 65 20 28 66 78 2b 20 69 65 20 32  -ref e (fx+ ie 2
22a0: 29 29 29 20 36 29 0a 09 09 09 20 20 20 20 20 20  ))) 6)....      
22b0: 28 69 66 20 28 66 78 3c 20 28 66 78 2b 20 69 65  (if (fx< (fx+ ie
22c0: 20 33 29 20 6e 29 0a 09 09 09 09 20 20 28 61 6c   3) n).....  (al
22d0: 70 68 61 62 65 74 2d 72 65 66 20 28 73 74 72 69  phabet-ref (stri
22e0: 6e 67 2d 72 65 66 20 65 20 28 66 78 2b 20 69 65  ng-ref e (fx+ ie
22f0: 20 33 29 29 29 0a 09 09 09 09 20 20 30 29 29 0a   3))).....  0)).
2300: 09 09 09 20 20 20 20 20 30 29 29 0a 09 09 09 30  ...     0))....0
2310: 29 29 29 29 0a 09 20 20 20 20 28 73 74 72 69 6e  ))))..    (strin
2320: 67 2d 73 65 74 21 0a 09 20 20 20 20 20 73 20 69  g-set!..     s i
2330: 73 20 28 69 6e 74 65 67 65 72 2d 3e 63 68 61 72  s (integer->char
2340: 20 28 66 78 61 6e 64 20 28 66 78 73 68 72 20 69   (fxand (fxshr i
2350: 20 31 36 29 20 23 78 66 66 29 29 29 0a 09 20 20   16) #xff)))..  
2360: 20 20 28 77 68 65 6e 20 28 66 78 3c 20 28 66 78    (when (fx< (fx
2370: 2b 20 69 65 20 32 29 20 6e 29 0a 09 20 20 20 20  + ie 2) n)..    
2380: 20 20 28 73 74 72 69 6e 67 2d 73 65 74 21 0a 09    (string-set!..
2390: 20 20 20 20 20 20 20 73 20 28 66 78 2b 20 69 73         s (fx+ is
23a0: 20 31 29 20 28 69 6e 74 65 67 65 72 2d 3e 63 68   1) (integer->ch
23b0: 61 72 20 28 66 78 61 6e 64 20 28 66 78 73 68 72  ar (fxand (fxshr
23c0: 20 69 20 38 29 20 23 78 66 66 29 29 29 0a 09 20   i 8) #xff))).. 
23d0: 20 20 20 20 20 28 77 68 65 6e 20 28 66 78 3c 20       (when (fx< 
23e0: 28 66 78 2b 20 69 65 20 33 29 20 6e 29 0a 09 09  (fx+ ie 3) n)...
23f0: 28 73 74 72 69 6e 67 2d 73 65 74 21 0a 09 09 20  (string-set!... 
2400: 73 20 28 66 78 2b 20 69 73 20 32 29 20 28 69 6e  s (fx+ is 2) (in
2410: 74 65 67 65 72 2d 3e 63 68 61 72 20 28 66 78 61  teger->char (fxa
2420: 6e 64 20 69 20 23 78 66 66 29 29 29 29 29 29 29  nd i #xff)))))))
2430: 29 29 29 29 0a 0a 3b 3b 3b 20 48 54 4d 4c 20 6f  ))))..;;; HTML o
2440: 75 74 70 75 74 0a 0a 28 64 65 66 69 6e 65 20 77  utput..(define w
2450: 72 69 74 65 2d 68 74 6d 6c 0a 20 20 28 6c 65 74  rite-html.  (let
2460: 72 65 63 20 28 28 74 61 67 2d 72 75 6c 65 73 0a  rec ((tag-rules.
2470: 09 20 20 20 20 28 61 6c 69 73 74 2d 3e 68 61 73  .    (alist->has
2480: 68 2d 74 61 62 6c 65 0a 09 20 20 20 20 20 27 28  h-table..     '(
2490: 28 61 72 65 61 20 2e 20 76 6f 69 64 29 0a 09 20  (area . void).. 
24a0: 20 20 20 20 20 20 28 62 61 73 65 20 2e 20 76 6f        (base . vo
24b0: 69 64 29 0a 09 20 20 20 20 20 20 20 28 62 72 20  id)..       (br 
24c0: 2e 20 76 6f 69 64 29 0a 09 20 20 20 20 20 20 20  . void)..       
24d0: 28 63 6f 6c 20 2e 20 76 6f 69 64 29 0a 09 20 20  (col . void)..  
24e0: 20 20 20 20 20 28 63 6f 6d 6d 61 6e 64 20 2e 20       (command . 
24f0: 76 6f 69 64 29 0a 09 20 20 20 20 20 20 20 28 65  void)..       (e
2500: 6d 62 65 64 20 2e 20 76 6f 69 64 29 0a 09 20 20  mbed . void)..  
2510: 20 20 20 20 20 28 68 72 20 2e 20 76 6f 69 64 29       (hr . void)
2520: 0a 09 20 20 20 20 20 20 20 28 69 6d 67 20 2e 20  ..       (img . 
2530: 76 6f 69 64 29 0a 09 20 20 20 20 20 20 20 28 69  void)..       (i
2540: 6e 70 75 74 20 2e 20 76 6f 69 64 29 0a 09 20 20  nput . void)..  
2550: 20 20 20 20 20 28 6b 65 79 67 65 6e 20 2e 20 76       (keygen . v
2560: 6f 69 64 29 0a 09 20 20 20 20 20 20 20 28 6c 69  oid)..       (li
2570: 6e 6b 20 2e 20 76 6f 69 64 29 0a 09 20 20 20 20  nk . void)..    
2580: 20 20 20 28 6d 65 74 61 20 2e 20 76 6f 69 64 29     (meta . void)
2590: 0a 09 20 20 20 20 20 20 20 28 70 61 72 61 6d 20  ..       (param 
25a0: 2e 20 76 6f 69 64 29 0a 09 20 20 20 20 20 20 20  . void)..       
25b0: 28 73 6f 75 72 63 65 20 2e 20 76 6f 69 64 29 0a  (source . void).
25c0: 09 20 20 20 20 20 20 20 28 74 72 61 63 6b 20 2e  .       (track .
25d0: 20 76 6f 69 64 29 0a 09 20 20 20 20 20 20 20 28   void)..       (
25e0: 77 62 72 20 2e 20 76 6f 69 64 29 0a 09 20 20 20  wbr . void)..   
25f0: 20 20 20 20 28 73 63 72 69 70 74 20 2e 20 72 61      (script . ra
2600: 77 29 0a 09 20 20 20 20 20 20 20 28 73 74 79 6c  w)..       (styl
2610: 65 20 2e 20 72 61 77 29 29 0a 09 20 20 20 20 20  e . raw))..     
2620: 23 3a 74 65 73 74 20 65 71 3f 20 23 3a 68 61 73  #:test eq? #:has
2630: 68 20 65 71 3f 2d 68 61 73 68 29 29 0a 09 20 20  h eq?-hash))..  
2640: 20 28 70 72 6f 62 6c 65 6d 61 74 69 63 2d 72 78   (problematic-rx
2650: 0a 09 20 20 20 20 28 69 72 72 65 67 65 78 20 27  ..    (irregex '
2660: 28 22 5c 22 26 3c 3e 22 29 29 29 0a 09 20 20 20  ("\"&<>")))..   
2670: 28 68 74 6d 6c 2d 65 73 63 61 70 65 0a 09 20 20  (html-escape..  
2680: 20 20 28 6c 61 6d 62 64 61 20 28 73 29 0a 09 20    (lambda (s).. 
2690: 20 20 20 20 20 28 69 72 72 65 67 65 78 2d 72 65       (irregex-re
26a0: 70 6c 61 63 65 2f 61 6c 6c 0a 09 20 20 20 20 20  place/all..     
26b0: 20 20 70 72 6f 62 6c 65 6d 61 74 69 63 2d 72 78    problematic-rx
26c0: 20 73 0a 09 20 20 20 20 20 20 20 28 6c 61 6d 62   s..       (lamb
26d0: 64 61 20 28 6d 29 0a 09 09 20 28 63 61 73 65 20  da (m)... (case 
26e0: 28 73 74 72 69 6e 67 2d 72 65 66 20 28 69 72 72  (string-ref (irr
26f0: 65 67 65 78 2d 6d 61 74 63 68 2d 73 75 62 73 74  egex-match-subst
2700: 72 69 6e 67 20 6d 29 20 30 29 0a 09 09 20 20 20  ring m) 0)...   
2710: 28 28 23 5c 22 29 20 22 26 71 75 6f 74 3b 22 29  ((#\") "&quot;")
2720: 0a 09 09 20 20 20 28 28 23 5c 26 29 20 22 26 61  ...   ((#\&) "&a
2730: 6d 70 3b 22 29 0a 09 09 20 20 20 28 28 23 5c 3c  mp;")...   ((#\<
2740: 29 20 22 26 6c 74 3b 22 29 0a 09 09 20 20 20 28  ) "&lt;")...   (
2750: 28 23 5c 3e 29 20 22 26 67 74 3b 22 29 29 29 29  (#\>) "&gt;"))))
2760: 29 29 0a 09 20 20 20 28 77 72 69 74 65 2d 65 6c  ))..   (write-el
2770: 65 6d 65 6e 74 0a 09 20 20 20 20 28 6c 61 6d 62  ement..    (lamb
2780: 64 61 20 28 65 6c 74 20 70 6f 72 74 29 0a 09 20  da (elt port).. 
2790: 20 20 20 20 20 28 75 6e 6c 65 73 73 20 28 61 6e       (unless (an
27a0: 64 20 28 70 61 69 72 3f 20 65 6c 74 29 20 28 73  d (pair? elt) (s
27b0: 79 6d 62 6f 6c 3f 20 28 63 61 72 20 65 6c 74 29  ymbol? (car elt)
27c0: 29 20 28 6c 69 73 74 3f 20 28 63 64 72 20 65 6c  ) (list? (cdr el
27d0: 74 29 29 29 0a 09 09 28 65 72 72 6f 72 0a 09 09  t)))...(error...
27e0: 20 27 77 72 69 74 65 2d 68 74 6d 6c 20 22 6e 6f   'write-html "no
27f0: 74 20 61 20 70 72 6f 70 65 72 20 65 6c 65 6d 65  t a proper eleme
2800: 6e 74 22 0a 09 09 20 65 6c 74 29 29 0a 09 20 20  nt"... elt))..  
2810: 20 20 20 20 28 6c 65 74 2d 76 61 6c 75 65 73 20      (let-values 
2820: 28 28 28 74 61 67 20 61 74 74 72 69 62 75 74 65  (((tag attribute
2830: 73 2b 63 6f 6e 74 65 6e 74 73 29 0a 09 09 09 20  s+contents).... 
2840: 20 20 20 28 63 61 72 2b 63 64 72 20 65 6c 74 29     (car+cdr elt)
2850: 29 29 0a 09 09 28 66 70 72 69 6e 74 66 20 70 6f  ))...(fprintf po
2860: 72 74 20 22 3c 7e 61 22 20 74 61 67 29 0a 09 09  rt "<~a" tag)...
2870: 28 6c 65 74 2d 76 61 6c 75 65 73 20 28 28 28 72  (let-values (((r
2880: 75 6c 65 29 0a 09 09 09 20 20 20 20 20 20 28 68  ule)....      (h
2890: 61 73 68 2d 74 61 62 6c 65 2d 72 65 66 2f 64 65  ash-table-ref/de
28a0: 66 61 75 6c 74 20 74 61 67 2d 72 75 6c 65 73 20  fault tag-rules 
28b0: 74 61 67 20 27 6e 6f 72 6d 61 6c 29 29 0a 09 09  tag 'normal))...
28c0: 09 20 20 20 20 20 28 28 61 74 74 72 69 62 75 74  .     ((attribut
28d0: 65 73 20 63 6f 6e 74 65 6e 74 73 29 0a 09 09 09  es contents)....
28e0: 20 20 20 20 20 20 28 63 6f 6e 64 0a 09 09 09 20        (cond.... 
28f0: 20 20 20 20 20 20 28 28 6e 75 6c 6c 3f 20 61 74        ((null? at
2900: 74 72 69 62 75 74 65 73 2b 63 6f 6e 74 65 6e 74  tributes+content
2910: 73 29 0a 09 09 09 09 28 76 61 6c 75 65 73 20 27  s).....(values '
2920: 28 29 20 27 28 29 29 29 0a 09 09 09 20 20 20 20  () '()))....    
2930: 20 20 20 28 28 61 6e 64 20 28 6c 69 73 74 3f 20     ((and (list? 
2940: 28 63 61 72 20 61 74 74 72 69 62 75 74 65 73 2b  (car attributes+
2950: 63 6f 6e 74 65 6e 74 73 29 29 0a 09 09 09 09 20  contents))..... 
2960: 20 20 20 20 28 65 76 65 72 79 20 6c 69 73 74 3f      (every list?
2970: 20 28 63 61 72 20 61 74 74 72 69 62 75 74 65 73   (car attributes
2980: 2b 63 6f 6e 74 65 6e 74 73 29 29 29 0a 09 09 09  +contents)))....
2990: 09 28 63 61 72 2b 63 64 72 20 61 74 74 72 69 62  .(car+cdr attrib
29a0: 75 74 65 73 2b 63 6f 6e 74 65 6e 74 73 29 29 0a  utes+contents)).
29b0: 09 09 09 20 20 20 20 20 20 20 28 65 6c 73 65 0a  ...       (else.
29c0: 09 09 09 09 28 76 61 6c 75 65 73 20 27 28 29 20  ....(values '() 
29d0: 61 74 74 72 69 62 75 74 65 73 2b 63 6f 6e 74 65  attributes+conte
29e0: 6e 74 73 29 29 29 29 29 0a 09 09 20 20 28 66 6f  nts)))))...  (fo
29f0: 72 2d 65 61 63 68 20 28 63 75 74 20 77 72 69 74  r-each (cut writ
2a00: 65 2d 61 74 74 72 69 62 75 74 65 20 3c 3e 20 70  e-attribute <> p
2a10: 6f 72 74 29 20 61 74 74 72 69 62 75 74 65 73 29  ort) attributes)
2a20: 0a 09 09 20 20 28 64 69 73 70 6c 61 79 20 23 5c  ...  (display #\
2a30: 3e 20 70 6f 72 74 29 0a 09 09 20 20 28 63 61 73  > port)...  (cas
2a40: 65 20 72 75 6c 65 0a 09 09 20 20 20 20 28 28 6e  e rule...    ((n
2a50: 6f 72 6d 61 6c 29 0a 09 09 20 20 20 20 20 28 66  ormal)...     (f
2a60: 6f 72 2d 65 61 63 68 20 28 63 75 74 20 77 72 69  or-each (cut wri
2a70: 74 65 2d 63 6f 6e 74 65 6e 74 20 23 74 20 3c 3e  te-content #t <>
2a80: 20 70 6f 72 74 29 20 63 6f 6e 74 65 6e 74 73 29   port) contents)
2a90: 29 0a 09 09 20 20 20 20 28 28 72 61 77 29 0a 09  )...    ((raw)..
2aa0: 09 20 20 20 20 20 28 66 6f 72 2d 65 61 63 68 20  .     (for-each 
2ab0: 28 63 75 74 20 77 72 69 74 65 2d 63 6f 6e 74 65  (cut write-conte
2ac0: 6e 74 20 23 66 20 3c 3e 20 70 6f 72 74 29 20 63  nt #f <> port) c
2ad0: 6f 6e 74 65 6e 74 73 29 29 0a 09 09 20 20 20 20  ontents))...    
2ae0: 28 28 76 6f 69 64 29 0a 09 09 20 20 20 20 20 28  ((void)...     (
2af0: 75 6e 6c 65 73 73 20 28 6e 75 6c 6c 3f 20 63 6f  unless (null? co
2b00: 6e 74 65 6e 74 73 29 0a 09 09 20 20 20 20 20 20  ntents)...      
2b10: 20 28 65 72 72 6f 72 0a 09 09 09 27 77 72 69 74   (error....'writ
2b20: 65 2d 68 74 6d 6c 20 22 76 6f 69 64 20 65 6c 65  e-html "void ele
2b30: 6d 65 6e 74 73 20 63 61 6e 6e 6f 74 20 68 61 76  ments cannot hav
2b40: 65 20 63 6f 6e 74 65 6e 74 73 22 0a 09 09 09 65  e contents"....e
2b50: 6c 74 29 29 29 29 0a 09 09 20 20 28 63 61 73 65  lt))))...  (case
2b60: 20 72 75 6c 65 0a 09 09 20 20 20 20 28 28 6e 6f   rule...    ((no
2b70: 72 6d 61 6c 20 72 61 77 29 0a 09 09 20 20 20 20  rmal raw)...    
2b80: 20 28 66 70 72 69 6e 74 66 20 70 6f 72 74 20 22   (fprintf port "
2b90: 3c 2f 7e 61 3e 22 20 74 61 67 29 29 29 29 29 29  </~a>" tag))))))
2ba0: 29 0a 09 20 20 20 28 77 72 69 74 65 2d 61 74 74  )..   (write-att
2bb0: 72 69 62 75 74 65 0a 09 20 20 20 20 28 6c 61 6d  ribute..    (lam
2bc0: 62 64 61 20 28 61 74 74 72 20 70 6f 72 74 29 0a  bda (attr port).
2bd0: 09 20 20 20 20 20 20 28 75 6e 6c 65 73 73 20 28  .      (unless (
2be0: 61 6e 64 20 28 70 61 69 72 3f 20 61 74 74 72 29  and (pair? attr)
2bf0: 20 28 73 79 6d 62 6f 6c 3f 20 28 63 61 72 20 61   (symbol? (car a
2c00: 74 74 72 29 29 20 28 6c 69 73 74 3f 20 28 63 64  ttr)) (list? (cd
2c10: 72 20 61 74 74 72 29 29 29 0a 09 09 28 65 72 72  r attr)))...(err
2c20: 6f 72 0a 09 09 20 27 77 72 69 74 65 2d 68 74 6d  or... 'write-htm
2c30: 6c 20 22 6e 6f 74 20 61 20 70 72 6f 70 65 72 20  l "not a proper 
2c40: 61 74 74 72 69 62 75 74 65 22 0a 09 09 20 61 74  attribute"... at
2c50: 74 72 29 29 0a 09 20 20 20 20 20 20 28 6c 65 74  tr))..      (let
2c60: 2d 76 61 6c 75 65 73 20 28 28 28 6b 65 79 20 63  -values (((key c
2c70: 6f 6e 74 65 6e 74 73 29 20 28 63 61 72 2b 63 64  ontents) (car+cd
2c80: 72 20 61 74 74 72 29 29 29 0a 09 09 28 66 70 72  r attr)))...(fpr
2c90: 69 6e 74 66 20 70 6f 72 74 20 22 20 7e 61 3d 5c  intf port " ~a=\
2ca0: 22 22 20 6b 65 79 29 0a 09 09 28 66 6f 72 2d 65  "" key)...(for-e
2cb0: 61 63 68 20 28 63 75 74 20 77 72 69 74 65 2d 63  ach (cut write-c
2cc0: 6f 6e 74 65 6e 74 20 23 66 20 3c 3e 20 70 6f 72  ontent #f <> por
2cd0: 74 29 20 63 6f 6e 74 65 6e 74 73 29 0a 09 09 28  t) contents)...(
2ce0: 64 69 73 70 6c 61 79 20 23 5c 22 20 70 6f 72 74  display #\" port
2cf0: 29 29 29 29 0a 09 20 20 20 28 77 72 69 74 65 2d  ))))..   (write-
2d00: 63 6f 6e 74 65 6e 74 0a 09 20 20 20 20 28 6c 61  content..    (la
2d10: 6d 62 64 61 20 28 61 6c 6c 6f 77 2d 65 6c 65 6d  mbda (allow-elem
2d20: 65 6e 74 73 3f 20 76 20 70 6f 72 74 29 0a 09 20  ents? v port).. 
2d30: 20 20 20 20 20 28 63 6f 6e 64 0a 09 20 20 20 20       (cond..    
2d40: 20 20 20 28 28 73 79 6d 62 6f 6c 3f 20 76 29 0a     ((symbol? v).
2d50: 09 09 28 66 70 72 69 6e 74 66 20 70 6f 72 74 20  ..(fprintf port 
2d60: 22 26 7e 61 3b 22 20 76 29 29 0a 09 20 20 20 20  "&~a;" v))..    
2d70: 20 20 20 28 28 61 6e 64 20 28 69 6e 74 65 67 65     ((and (intege
2d80: 72 3f 20 76 29 20 28 70 6f 73 69 74 69 76 65 3f  r? v) (positive?
2d90: 20 76 29 29 0a 09 09 28 66 70 72 69 6e 74 66 20   v))...(fprintf 
2da0: 70 6f 72 74 20 22 26 23 7e 61 3b 22 20 76 29 29  port "&#~a;" v))
2db0: 0a 09 20 20 20 20 20 20 20 28 28 73 74 72 69 6e  ..       ((strin
2dc0: 67 3f 20 76 29 0a 09 09 28 64 69 73 70 6c 61 79  g? v)...(display
2dd0: 20 28 68 74 6d 6c 2d 65 73 63 61 70 65 20 76 29   (html-escape v)
2de0: 20 70 6f 72 74 29 29 0a 09 20 20 20 20 20 20 20   port))..       
2df0: 28 61 6c 6c 6f 77 2d 65 6c 65 6d 65 6e 74 73 3f  (allow-elements?
2e00: 0a 09 09 28 77 72 69 74 65 2d 65 6c 65 6d 65 6e  ...(write-elemen
2e10: 74 20 76 20 70 6f 72 74 29 29 0a 09 20 20 20 20  t v port))..    
2e20: 20 20 20 28 65 6c 73 65 0a 09 09 28 65 72 72 6f     (else...(erro
2e30: 72 0a 09 09 20 27 77 72 69 74 65 2d 68 74 6d 6c  r... 'write-html
2e40: 20 22 65 6c 65 6d 65 6e 74 20 6e 6f 74 20 61 6c   "element not al
2e50: 6c 6f 77 65 64 20 69 6e 20 74 68 69 73 20 63 6f  lowed in this co
2e60: 6e 74 65 78 74 22 0a 09 09 20 76 29 29 29 29 29  ntext"... v)))))
2e70: 29 0a 20 20 20 20 28 6c 61 6d 62 64 61 20 28 68  ).    (lambda (h
2e80: 74 6d 6c 20 23 21 6f 70 74 69 6f 6e 61 6c 20 28  tml #!optional (
2e90: 70 6f 72 74 20 28 63 75 72 72 65 6e 74 2d 6f 75  port (current-ou
2ea0: 74 70 75 74 2d 70 6f 72 74 29 29 29 0a 20 20 20  tput-port))).   
2eb0: 20 20 20 28 64 69 73 70 6c 61 79 20 22 3c 21 44     (display "<!D
2ec0: 4f 43 54 59 50 45 20 68 74 6d 6c 3e 22 20 70 6f  OCTYPE html>" po
2ed0: 72 74 29 0a 20 20 20 20 20 20 28 6e 65 77 6c 69  rt).      (newli
2ee0: 6e 65 20 70 6f 72 74 29 0a 20 20 20 20 20 20 28  ne port).      (
2ef0: 77 72 69 74 65 2d 65 6c 65 6d 65 6e 74 20 68 74  write-element ht
2f00: 6d 6c 20 70 6f 72 74 29 0a 20 20 20 20 20 20 28  ml port).      (
2f10: 6e 65 77 6c 69 6e 65 20 70 6f 72 74 29 29 29 29  newline port))))
2f20: 0a                                               .