229 lines
7.0 KiB
Scheme
229 lines
7.0 KiB
Scheme
;texread.scm
|
|
;SLaTeX v. 2.3
|
|
;Various token-readers used on TeX files by SLaTeX
|
|
;(c) Dorai Sitaram, Rice U., 1991, 1994
|
|
|
|
(eval-within slatex
|
|
|
|
(define slatex::eat-till-newline
|
|
(lambda (in)
|
|
;skip all characters from port in till newline inclusive or eof
|
|
(let loop ()
|
|
(let ((c (read-char in)))
|
|
(cond ((eof-object? c) 'done)
|
|
((char=? c #\newline) 'done)
|
|
(else (loop)))))))
|
|
|
|
(define slatex::read-ctrl-seq
|
|
(lambda (in)
|
|
;assuming we've just read a backslash, read the remaining
|
|
;part of a latex control sequence from port in
|
|
(let ((c (read-char in)))
|
|
(if (eof-object? c)
|
|
(error "read-ctrl-exp: \\ followed by eof."))
|
|
(if (char-alphabetic? c)
|
|
(list->string
|
|
(reverse!
|
|
(let loop ((s (list c)))
|
|
(let ((c (peek-char in)))
|
|
(cond ((eof-object? c) s)
|
|
((char-alphabetic? c) (read-char in)
|
|
(loop (cons c s)))
|
|
((char=? c #\%) (eat-till-newline in)
|
|
(loop s))
|
|
(else s))))))
|
|
(string c)))))
|
|
|
|
(define slatex::eat-tabspace
|
|
(lambda (in)
|
|
;skip to the next non-space and non-tab character from port in
|
|
(let loop ()
|
|
(let ((c (peek-char in)))
|
|
(cond ((eof-object? c) 'done)
|
|
((or (char=? c #\space) (char=? c *tab*))
|
|
(read-char in) (loop))
|
|
(else 'done))))))
|
|
|
|
(define slatex::eat-whitespace
|
|
(lambda (in)
|
|
;skip to the next whitespace character from port in
|
|
(let loop ()
|
|
(let ((c (peek-char in)))
|
|
(cond ((eof-object? c) 'done)
|
|
((char-whitespace? c)
|
|
(read-char in) (loop))
|
|
(else 'done))))))
|
|
|
|
(define slatex::eat-tex-whitespace
|
|
(lambda (in)
|
|
;skip to the next whitespace character from port in;
|
|
;skips past latex comments too
|
|
(let loop ()
|
|
(let ((c (peek-char in)))
|
|
(cond ((eof-object? c) 'done)
|
|
((char-whitespace? c) (read-char in) (loop))
|
|
((char=? c #\%) (eat-till-newline in))
|
|
(else 'done))))))
|
|
|
|
(define slatex::chop-off-whitespace
|
|
(lambda (l)
|
|
;removes leading whitespace from character-list l
|
|
(ormapcdr (lambda (d) (if (char-whitespace? (car d)) #f d)) l)))
|
|
|
|
(define slatex::read-grouped-latexexp
|
|
(lambda (in)
|
|
;reads a latex grouped expression from port in
|
|
;(removes the groups)
|
|
(eat-tex-whitespace in)
|
|
(let ((c (read-char in)))
|
|
(if (eof-object? c) (error "read-grouped-latexexp: ~
|
|
Expected { but found eof."))
|
|
(if (not (char=? c #\{))
|
|
(error "read-grouped-latexexp: ~
|
|
Expected { but found ~a." c))
|
|
(eat-tex-whitespace in)
|
|
(list->string
|
|
(reverse!
|
|
(chop-off-whitespace
|
|
(let loop ((s '()) (nesting 0) (escape? #f))
|
|
(let ((c (read-char in)))
|
|
(if (eof-object? c) (error "read-groupted-latexexp: ~
|
|
Found eof inside {...}."))
|
|
(cond (escape? (loop (cons c s) nesting #f))
|
|
((char=? c #\\)
|
|
(loop (cons c s) nesting #t))
|
|
((char=? c #\%) (eat-till-newline in)
|
|
(loop s nesting #f))
|
|
((char=? c #\{)
|
|
(loop (cons c s) (+ nesting 1) #f))
|
|
((char=? c #\})
|
|
(if (= nesting 0) s
|
|
(loop (cons c s) (- nesting 1) #f)))
|
|
(else
|
|
(loop (cons c s) nesting #f)))))))))))
|
|
|
|
(define slatex::read-filename
|
|
(let ((filename-delims (list #\{ #\} #\[ #\] #\( #\) #\# #\% #\\ #\,
|
|
#\space *return* #\newline *tab* #\\)))
|
|
(lambda (in)
|
|
;reads a filename as allowed in latex syntax from port in
|
|
(eat-tex-whitespace in)
|
|
(let ((c (peek-char in)))
|
|
(if (eof-object? c) (error "read-filename: ~
|
|
Expected filename but found eof."))
|
|
(if (char=? c #\{) (read-grouped-latexexp in)
|
|
(list->string
|
|
(reverse!
|
|
(let loop ((s '()) (escape? #f))
|
|
(let ((c (peek-char in)))
|
|
(cond ((eof-object? c)
|
|
(if escape? (error "read-filename: ~
|
|
\\ followed by eof.")
|
|
s))
|
|
(escape? (read-char in)
|
|
(loop (cons c s) #f))
|
|
((char=? c #\\) (read-char in)
|
|
(loop (cons c s) #t))
|
|
((memv c filename-delims) s)
|
|
(else (read-char in)
|
|
(loop (cons c s) #f))))))))))))
|
|
|
|
(define slatex::read-schemeid
|
|
(let ((schemeid-delims (list #\{ #\} #\[ #\] #\( #\)
|
|
#\space *return* #\newline *tab*)))
|
|
(lambda (in)
|
|
;reads a scheme identifier from port in
|
|
(eat-whitespace in)
|
|
(list->string
|
|
(reverse!
|
|
(let loop ((s '()) (escape? #f))
|
|
(let ((c (peek-char in)))
|
|
(cond ((eof-object? c) s)
|
|
(escape? (read-char in) (loop (cons c s) #f))
|
|
((char=? c #\\) (read-char in)
|
|
(loop (cons c s) #t))
|
|
((memv c schemeid-delims) s)
|
|
(else (read-char in) (loop (cons c s) #f))))))))))
|
|
|
|
(define slatex::read-delimed-commaed-filenames
|
|
(lambda (in lft-delim rt-delim)
|
|
;reads a filename from port in, assuming it's delimited by
|
|
;lft- and rt-delims
|
|
(eat-tex-whitespace in)
|
|
(let ((c (read-char in)))
|
|
(if (eof-object? c) (error "read-delimed-commaed-filenames: ~
|
|
Expected filename(s) but found eof."))
|
|
(if (not (char=? c lft-delim))
|
|
(error "read-delimed-commaed-filenames: ~
|
|
Left delimiter ~a not found." lft-delim))
|
|
(let loop ((s '()))
|
|
(eat-tex-whitespace in)
|
|
(let ((c (peek-char in)))
|
|
(if (eof-object? c) (error "read-delimed-commaed-filenames: ~
|
|
Found eof inside filename(s)."))
|
|
(if (char=? c rt-delim)
|
|
(begin (read-char in) (reverse! s))
|
|
(let ((s (cons (read-filename in) s)))
|
|
(eat-tex-whitespace in)
|
|
(let ((c (peek-char in)))
|
|
(if (eof-object? c)
|
|
(error "read-delimed-commaed-filenames: ~
|
|
Found eof inside filename(s)."))
|
|
(cond
|
|
((char=? c #\,) (read-char in))
|
|
((char=? c rt-delim) (void))
|
|
(else (error "read-delimed-commaed-filenames: ~
|
|
Bad filename(s) syntax.")))
|
|
(loop s)))))))))
|
|
|
|
(define slatex::read-grouped-commaed-filenames
|
|
(lambda (in)
|
|
;read a filename from port in, assuming it's grouped
|
|
(read-delimed-commaed-filenames in #\{ #\})))
|
|
|
|
(define slatex::read-bktd-commaed-filenames
|
|
(lambda (in)
|
|
;read a filename from port in, assuming it's bracketed
|
|
(read-delimed-commaed-filenames in #\[ #\])))
|
|
|
|
(define slatex::read-grouped-schemeids
|
|
(lambda (in)
|
|
;read a list of scheme identifiers from port in,
|
|
;assuming they're all grouped
|
|
(eat-tex-whitespace in)
|
|
(let ((c (read-char in)))
|
|
(if (eof-object? c) (error "read-grouped-schemeids: ~
|
|
Expected Scheme identifiers but found eof."))
|
|
(if (not (char=? c #\{)) (error "read-grouped-schemeids: ~
|
|
Expected { but found ~a." c))
|
|
(let loop ((s '()))
|
|
(eat-whitespace in)
|
|
(let ((c (peek-char in)))
|
|
(if (eof-object? c) (error "read-grouped-schemeids:
|
|
Found eof inside Scheme identifiers."))
|
|
(if (char=? c #\})
|
|
(begin (read-char in) (reverse! s))
|
|
(loop (cons (read-schemeid in) s))))))))
|
|
|
|
(define slatex::eat-delimed-text
|
|
(lambda (in lft-delim rt-delim)
|
|
(eat-tex-whitespace in)
|
|
(let ((c (peek-char in)))
|
|
(if (eof-object? c) 'exit
|
|
(if (char=? c lft-delim)
|
|
(let loop ()
|
|
(let ((c (read-char in)))
|
|
(if (eof-object? c) 'exit
|
|
(if (char=? c rt-delim) 'exit
|
|
(loop))))))))))
|
|
|
|
(define slatex::eat-bktd-text
|
|
(lambda (in)
|
|
(eat-delimed-text in #\[ #\])))
|
|
|
|
(define slatex::eat-grouped-text
|
|
(lambda (in)
|
|
(eat-delimed-text in #\{ #\})))
|
|
|
|
;(trace read-filename)
|
|
) |