home *** CD-ROM | disk | FTP | other *** search
- ;; mif.ol -- the Frame MIF class
-
- (require 'objective-lisp)
- (require 'stream)
-
- (defClass MIF ()
- (out PgfCatalog FontCatalog VariableFormats XRefFormats
- TextFlows MasterPages AFrames body hyper)
- )
-
- (defClassMethod MIF :reader (in)
- [MIFReader :new in]
- )
-
- (defMethod MIF :isnew (o)
- (setq out o)
- )
-
- (defClass MIFReader IStream
- ()
- (table)
- )
-
- (defMethod MIFReader :read ()
- [self :set-readtable [self :readtable]]
- (prog1 (send-super :read)
- [self :set-readtable])
- )
-
- ;;;;;;;;;;;;;;;
- ;;; MIF Syntax
-
- (defun read-mif-statement (f c &aux ex ret)
- ;; like (read stream) but uses <> in stead of ()
- (flet ((non-comment-char (comm)
- ;; skip whitespace. skip comm...newline
- ;; return next char
- (do ((c (peek-char t f) (peek-char t f))
- )
- ((not (eql c comm))
- c)
- (read-line f)
- ) )
- )
-
- (do ()
- ((eq (non-comment-char #\#) #\>))
- (let ((cell (cons (read f) nil))
- )
- (if ex (setf (cdr ex) cell) (setf ret cell))
- (setf ex cell)))
- )
- (read-char f) ; toss the trailing #\>
- (cons ret NIL)
- )
-
- (defun read-mif-string (f c &aux ex ret nonascii)
- ;; MIF strings look like `lksdjf \n \t \q \Q \x80 lksjdf'
- ;; aka "lksdjf \n \009 ` ' \200lksjdf"
- ;; returns a string if all chars are printable ASCII.
- ;; returns a list of characters otherwise
- (labels ((hex-digit (d)
- (or (digit-char-p d)
- (+ 10
- (- (char-int (char-upcase d))
- (char-int #\A))))
- )
-
- (read-mif-char (f)
- ;; interpret mif escapes
- (let ((c (read-char f))
- )
- (if (eq c #\\)
- (case (read-char f)
- (#\> #\>) (#\q #\') (#\Q #\`) (#\\ #\\)
- (#\t (setq nonascii t) (int-char 9))
- (#\x (setq nonascii t)
- (let ((d1 (read-char f))
- (d2 (read-char f))
- )
- (read-char f) ;; skip trailing blank
- (int-char (+ (* 16 (hex-digit d1))
- (hex-digit d2) ))
- ))
- )
- c) ) )
- )
-
- (do ()
- ((eq (peek-char nil f) #\'))
- (let ((cell (cons (read-mif-char f) nil))
- )
- (if ex (setf (cdr ex) cell) (setf ret cell))
- (setf ex cell)))
- (read-char f) ; toss the trailing #\'
- (cons (concatenate (if nonascii 'cons 'string) ret) NIL)
- ) )
-
- (defun read-mif-inset (f c &aux ex ret)
- ;; a mif inset looks like:
- ;; =FrameImage
- ;; &lksjdflskdjflsdkj
- ;; &lksdjflsdkjflsdkjf
- ;; =EndInset
- ;;
- (setf ret (setf ex (cons (read f) nil))) ;; read =symbol
- (do ()
- ((not (eq (peek-char t f) #\&)))
- (read-char f) ;; skip &
- (let ((cell (cons (read-line f) nil))
- )
- (setf (cdr ex) cell)
- (setf ex cell)))
- (cons ret NIL))
-
- (defMethod MifReader :readtable ()
- (or table
- (progn
- (setq table (subseq *readtable* 0))
- (flet ((setchar (c v)
- (setf (aref table (char-int c))
- v) )
- )
- (setchar #\< (cons :tmacro #'read-mif-statement))
- (setchar #\` (cons :tmacro #'read-mif-string))
- (setchar #\= (cons :tmacro #'read-mif-inset))
- ; # is the MIF comment char
- (setchar #\# (aref table (char-int #\;)))
- ; signal errors on >'s
- (setchar #\>
- (cons :tmacro
- (lambda (f c)
- (error "misplaced right angle bracket"))) )
- ; quote is short for IN, i.e. inch
- (setchar #\" (cons :tmacro
- (lambda (f c)
- (cons 'in nil) ) ))
- )
- table
- ) ) )
-
- (provide 'Mif)
-