" dline))
(set! topic #f)))))))))
;; end call-with-input-file loop
(let ((tnames (make-vector (+ n g)))
(ctr 0))
(do ((i 0 (+ i 1)))
((= i n))
(set! (tnames ctr)
(clean-and-downcase-first-char (names i) capitalized (files i)))
(if (positive? (length (ind-sortby (tnames ctr))))
(set! ctr (+ ctr 1))))
(unless (= ctr n)
(set! n ctr)
(set! tnames (copy tnames (make-vector n))))
(when (positive? g)
(if (< (length tnames) (+ g n))
(set! tnames (copy tnames (make-vector (+ g n) #f))))
(do ((i 0 (+ i 1)))
((= i g))
(set! (tnames (+ i n))
(create-general (generals i) (gfiles i))))
(set! n (+ n g)))
(set! tnames (sort! tnames string*))
(let ((len (length tnames)))
(let ((new-names (make-vector (+ len 100)))
(j 0)
(last-char #f))
(do ((i 0 (+ i 1)))
((= i len))
(let ((name (tnames i)))
(if (and name
(ind-sortby name))
(let ((this-char ((ind-sortby name) 0)))
(if (char=? this-char #\*)
(set! this-char ((ind-sortby name) 1)))
(if (and last-char
(not (char-ci=? last-char this-char)))
(begin
(set! (new-names j) (make-ind :name #f :sortby #f))
(set! j (+ j 1))
(set! (new-names j) (make-ind :name " "
:char (char-upcase this-char)
:sortby #f))
(set! j (+ j 1))
(set! (new-names j) (make-ind :name #f :sortby #f))
(set! j (+ j 1))))
(set! (new-names j) name)
(set! j (+ j 1))
(set! last-char this-char)))))
(set! tnames new-names)
(set! n j)))
(call-with-output-file output
(lambda (ofil)
(format ofil "
Snd Index
\n" (creation-date))
(format ofil "\n ")
(set! got-tr #t)
(do ((row 0)
(ctr 0)
(offset (ceiling (/ n cols)))
(i 0 (+ i 1)))
((= row offset))
(let ((x (+ row (* ctr offset))))
(if (>= x n)
(format ofil "\n")
(let ((name (tnames x)))
(format ofil
"~A~A~A | "
(if (or (not (ind-name name))
(ind-sortby name))
""
" class=\"green\"")
(if (ind-char name)
""
"")
(or (ind-char name)
(ind-name name)
" ")
(if (ind-char name)
"
"
"")
)
(if (ind-indexed name)
(format () "~A indexed twice\n" (ind-name name)))
(set! (ind-indexed name) #t))))
(set! ctr (+ ctr 1))
(when (< ctr cols)
(format ofil " | "))
(when (= ctr cols)
(if got-tr (begin (format ofil "
\n") (set! got-tr #f)))
(set! row (+ row 1))
(if (< i n) (begin (format ofil " ") (set! got-tr #t)))
(set! ctr 0)))
(format ofil "\n
\n\n")))
;; end output
(do ((i 0 (+ i 1)))
((= i n))
(if (not (ind-indexed (tnames i)))
(format () "unindexed: ~A (~A)\n" (ind-name (tnames i)) i)))
(do ((i 0 (+ i 1)))
((= i (- n 1)))
(let ((n1 (tnames i))
(n2 (tnames (+ i 1))))
(if (and (string? (ind-sortby n1))
(string? (ind-sortby n2))
(string=? (ind-sortby n1) (ind-sortby n2))
(string=? (ind-name n1) (ind-name n2)))
(format () "duplicated name: ~A (~A ~A)\n" (ind-sortby n1) (ind-name n1) (ind-name n2)))))
(when with-scm
(call-with-output-file "test.c"
(lambda (sfil)
(let ((help-names ())
(help-urls ()))
(format sfil "/* Snd help index (generated by make-index.scm) */\n")
(do ((i 0 (+ i 1)))
((= i n))
(if (and (tnames i)
(ind-sortby (tnames i)))
(let* ((line (substring (ind-name (tnames i)) 8))
(dpos (char-position #\> line))
(ind (substring line (+ dpos 1) (char-position #\< line))))
(let ((url (substring line 1 (- dpos 1)))
(gpos (string-position ">" ind)))
(if gpos
(set! ind (string-append (substring ind 0 gpos)
">"
(substring ind (+ gpos 4)))))
(when (positive? (length ind))
(set! help-names (cons ind help-names))
(set! help-urls (cons url help-urls)))))))
(set! help-names (reverse help-names))
(set! help-urls (reverse help-urls))
(format sfil "#define HELP_NAMES_SIZE ~D\n" (length help-names))
(format sfil "#if HAVE_SCHEME || HAVE_FORTH\n")
(format sfil "static const char *help_names[HELP_NAMES_SIZE] = {\n ")
(format sfil "~S" (car help-names))
(do ((ctr 1 (+ ctr 1))
(lname (cdr help-names) (cdr lname)))
((null? lname))
(format sfil (if (= (modulo ctr 6) 0) ",\n ~S" ", ~S") (car lname)))
(format sfil "};\n")
(format sfil "#endif\n#if HAVE_RUBY\n")
(format sfil "static const char *help_names[HELP_NAMES_SIZE] = {\n ")
(format sfil "~S" (car help-names))
(do ((ctr 1 (+ ctr 1))
(lname (cdr help-names) (cdr lname)))
((null? lname))
(let ((name (car lname)))
(format sfil (if (= (modulo ctr 6) 0) ",\n ~S" ", ~S") (without-dollar-sign (scheme->ruby name)))))
(format sfil "};\n#endif\n")
(format sfil "#if (!HAVE_EXTENSION_LANGUAGE)\nstatic const char **help_names = NULL;\n#endif\n")
(format sfil "static const char *help_urls[HELP_NAMES_SIZE] = {\n ")
(format sfil "~S" (car help-names))
(do ((ctr 1 (+ ctr 1))
(lname (cdr help-urls) (cdr lname)))
((null? lname))
(let ((url (car lname)))
(format sfil (if (= (modulo ctr 4) 0) ",\n ~S" ", ~S") url)))
(format sfil "};\n")
(do ((i 0 (+ i 1)))
((= i g))
(if (and (xrefs i)
(> (length (xrefs i)) 1))
(let ((vals (clean-up-xref (xrefs i) (gfiles i))))
(format sfil "\nstatic const char *~A_xrefs[] = {\n ~A,\n NULL};\n"
(let* ((str (generals i))
(mid (char-position #\: str)))
(make-vector-name (substring str (+ mid 1))))
(car vals))
(format sfil "\nstatic const char *~A_urls[] = {\n ~ANULL};\n"
(let* ((str (generals i))
(mid (char-position #\: str)))
(make-vector-name (substring str (+ mid 1))))
(cadr vals)))))
(format sfil "\n\n#if HAVE_SCHEME\n"))))
(system "cat indexer.data >> test.c")
(system "echo '#endif\n\n' >> test.c")))))
;;; --------------------------------------------------------------------------------
;;; html-check
;;; (html-check '("sndlib.html" "snd.html" "sndclm.html" "extsnd.html" "grfsnd.html" "sndscm.html" "fm.html" "balance.html" "snd-contents.html" "s7.html"))
(define (html-check files)
(let ((name 0)
(href 0)
(names (make-hash-table 2048))
(closables (let ((h (make-hash-table)))
(for-each (lambda (c)
(set! (h c) #t))
'(ul tr td table small sub blockquote p details summary
a A i b title pre span h1 h2 h3 code body html
em head h4 sup map smaller bigger th tbody div))
h)))
(for-each
(lambda (file)
(call-with-input-file file
(lambda (f)
(do ((linectr -1)
(commands ())
(comments 0)
(openctr 0)
(warned #f)
(p-parens 0)
(p-quotes 0)
(p-curlys 0)
(in-comment #f)
(scripting #f)
(line (read-line f) (read-line f)))
((eof-object? line)
(if (pair? commands)
(format () "open directives at end of ~A: ~A\n" file commands)))
(set! linectr (+ linectr 1))
(let* ((len (length line))
(opos (and (positive? len)
(char-position "<>\"(){}&" line)))
(cpos (and (not opos)
in-comment
(string-position " -- " line))))
(when cpos
(format () "~A[~D]: possible -- in comment: ~A\n" file linectr line))
(when opos
;; open/close html entities
(do ((i opos (or (char-position "<>\"(){}&" line (+ i 1)) len)))
((>= i len))
(case (string-ref line i)
((#\<)
(unless scripting
(if (not (or (zero? openctr)
(positive? p-quotes)
in-comment))
(format () "~A[~D]: ~A has unclosed \n" file linectr line))
(set! openctr (+ openctr 1))
(if (and (< i (- len 3))
(char=? (string-ref line (+ i 1)) #\!)
(char=? (string-ref line (+ i 2)) #\-)
(char=? (string-ref line (+ i 3)) #\-))
(begin
(set! comments (+ comments 1))
(if (> comments 1)
(begin
(format () "~A[~D]: nested ?\n" file linectr)
(set! comments 0))))
(if (not (or (zero? openctr)
(positive? p-quotes)
in-comment))
(format () "~A[~D]: ~A has unmatched >?\n" file linectr line)))
(set! openctr 0)
(if (and (not in-comment)
(>= i 2)
(char=? (string-ref line (- i 1)) #\-)
(not (char=? (string-ref line (- i 2)) #\-))
(< i (- len 1))
(alphanumeric? (string-ref line (+ i 1))))
(format () "~A[~D]: untranslated '>': ~A\n" file linectr line))))
;; else c != < or >
((#\()
(set! p-parens (+ p-parens 1)))
((#\))
(set! p-parens (- p-parens 1)))
((#\")
(if (or (= i 0)
(not (char=? (string-ref line (- i 1)) #\\)))
(set! p-quotes (+ p-quotes 1))))
((#\&)
(if (and (not in-comment)
(case (string-ref line (+ i 1))
((#\g) (not (string=? ">" (substring line i (min len (+ i 4))))))
((#\l) (not (or (string=? "<" (substring line i (min len (+ i 4))))
(string=? "λ" (substring line i (min len (+ i 8)))))))
((#\a) (not (string=? "&" (substring line i (min len (+ i 5))))))
((#\q) (not (string=? """ (substring line i (min len (+ i 6))))))
((#\o) (not (string=? "ö" (substring line i (min len (+ i 6))))))
((#\m) (not (member (substring line i (min len (+ i 7))) '("—" "µ") string=?)))
((#\n) (not (string=? " " (substring line i (min len (+ i 6))))))
((#\&) (not (string=? "&&" (substring line i (min len (+ i 2))))))
((#\space) (not (string=? "& " (substring line i (min len (+ i 2)))))) ; following char -- should skip this
(else #t)))
(format () "~A[~D]: unknown escape sequence: ~A\n" file linectr line)))
((#\{)
(set! p-curlys (+ p-curlys 1)))
((#\})
(set! p-curlys (- p-curlys 1)))))
;; end line scan
(unless in-comment
(let ((start #f)
(closing #f)
(pos (char-position #\< line)))
(when pos
(do ((i pos (or (char-position "! >" line (+ i 1)) len)))
((>= i len))
(case (string-ref line i)
((#\space #\>)
(when start
(if closing
(let ((closer (string->symbol (substring line (+ start 2) i))))
(if (eq? closer 'TABLE) (set! closer 'table))
(cond ((memq closer '(center big font))
(format () "~A[~D]: ~A is obsolete, ~A\n" file linectr closer line))
((eq? closer 'script)
(set! scripting #f))
(scripting)
((not (memq closer commands))
(format () "~A[~D]: ~A without start? ~A from [~D:~D] (commands: ~A)\n"
file linectr closer line (+ start 2) i commands))
((not (hash-table-ref closables closer))
(set! commands (remove-all closer commands)))
(else
(if (not (eq? (car commands) closer))
(format () "~A[~D]: ~A -> ~A?\n" file linectr closer commands))
(if (memq closer '(p td pre))
(begin
(if (odd? p-quotes)
(format () "~A[~D]: unmatched quote\n" file linectr))
(set! p-quotes 0)
(case p-curlys
((1)
(format () "~A[~D]: extra '{'\n" file linectr))
((-1)
(format () "~A[~D]: extra '}'\n" file linectr))
((0) #f)
(else
(format () "~A[~D]: curlys: ~D\n" file linectr p-curlys)))
(set! p-curlys 0)
(case p-curlys
((1)
(format () "~A[~D]: extra '('\n" file linectr))
((-1)
(format () "~A[~D]: extra ')'\n" file linectr))
((0) #f)
(else
(format () "~A[~D]: parens: ~D\n" file linectr p-parens)))
(set! p-parens 0)))
(set! commands (remove-one closer commands))
(when (and (not warned)
(eq? closer 'table)
(not (memq 'table commands)))
(if (memq 'tr commands)
(begin
(set! warned #t)
(set! commands (remove-all 'tr commands))
(format () "~A[~D]: unclosed tr at table (~A)\n" file linectr commands)))
(if (memq 'td commands)
(begin
(set! warned #t)
(set! commands (remove-all 'td commands))
(format () "~A[~D]: unclosed td at table (~A)\n" file linectr commands))))))
(set! closing #f))
;; not closing
(unless scripting
(let ((opener (string->symbol (substring line (+ start 1) i))))
(if (eq? opener 'TABLE) (set! opener 'table))
(cond ((memq opener '(center big font))
(format () "~A[~D]: ~A is obsolete, ~A\n" file linectr opener line))
((eq? opener 'script)
(set! scripting #t))
((eq? opener 'img)
(let* ((rest-line (substring line (+ start 4)))
(src-pos (string-position "src=" rest-line)))
(if (not (string-position "alt=" rest-line))
(format () "~A[~D]: img but no alt: ~A\n" file linectr line))
(if src-pos
(let ((png-pos (string-position ".png" rest-line)))
(if png-pos
(let ((file (substring rest-line (+ src-pos 5) (+ png-pos 4))))
(if (not (file-exists? file))
(format () "~A[~D]: src not found: ~S\n" file linectr file))))))))
((and (not (memq opener '(br spacer li hr area ul tr td table small sub blockquote)))
(memq opener commands)
(= p-quotes 0))
(format () "~A[~D]: nested ~A? ~A from: ~A\n" file linectr opener line commands))
(else
(case opener
((td)
(if (not (eq? 'tr (car commands)))
(format () "~A[~D]: td without tr?\n" file linectr))
(if (and (not warned)
(memq 'td commands)
(< (count-table commands) 2))
(begin
(set! warned #t)
(set! commands (remove-one 'td commands))
(format () "~A[~D]: unclosed td at table\n" file linectr))))
((tr)
(if (not (or (eq? (car commands) 'table)
(eq? (cadr commands) 'table)))
(format () "~A[~D]: tr without table?\n" file linectr))
(if (and (not warned)
(memq 'tr commands)
(< (count-table commands) 2))
(begin
(set! warned #t)
(set! commands (remove-one 'tr commands))
(format () "~A[~D]: unclosed tr at table\n" file linectr))))
((p)
(if (eq? (car commands) 'table)
(format () "~A[~D]: unclosed table?\n" file linectr)))
((pre br table hr img ul)
(if (memq 'p commands)
(format () "~A[~D]: ~A within ?\n" file linectr opener)))
((li)
(if (not (memq 'ul commands))
(format () "~A[~D]: li without ul\n" file linectr)))
((small)
(if (memq (car commands) '(pre code))
(format () "~A[~D]: small shouldn't follow ~A\n" file linectr (car commands))))
((--)
(format () "~A[~D]: <-- missing !?\n" file linectr)))
(if (not (memq opener '(br meta spacer li hr area)))
(set! commands (cons opener commands))))))))
;; end if closing
(set! start #f)))
((#\<)
(if start
(if (not (or scripting
(positive? p-quotes)))
(format () "~A[~D]: nested < ~A\n" file linectr line))
(set! start i)))
((#\/)
(if (and (integer? start) (= start (- i 1)))
(set! closing #t)))
((#\!)
(if (and (integer? start) (= start (- i 1)))
(set! start #f)))))))
) ; if not in-comment...
;; search for name
(let ((dline line))
(do ((pos (string-position "" dline)
(string-position "" dline)
(string-position "" dline))))
;; actually should look for close double quote
(if (not epos)
(format () "~A[~D]: but no
for ~A\n" file linectr dline)
(begin
(let ((min-epos (char-position #\space dline)))
(set! epos (char-position #\> dline))
(if (and (real? min-epos)
(< min-epos epos))
(set! epos min-epos)))
(let ((new-name (string-append file "#" (substring dline 0 (- epos 1)))))
(if (hash-table-ref names new-name)
(format () "~A[~D]: ambiguous name: ~A\n" file linectr new-name))
(hash-table-set! names new-name file))
(set! name (+ name 1))
(set! dline (substring dline epos))
(set! pos (string-position "