source: tags/0.8.0/example/clim-lookup.lisp

Last change on this file was 47, checked in by bmastenbrook, 20 years ago

CLIM spec lookup

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 3.5 KB
Line 
1(defpackage :clim-lookup (:use :common-lisp :split-sequence)
2            (:export :term-lookup :populate-table))
3(in-package :clim-lookup)
4
5(defvar *clim-table*)
6
7(defvar *clim-abbrev-table*)
8
9(defparameter *clim-file*
10  (merge-pathnames "mrindex"
11                   (make-pathname
12                    :directory
13                    (pathname-directory
14                     (or *load-truename*
15                         *default-pathname-defaults*)))))
16
17(defun merge-to-spec (url)
18  (concatenate 'string "http://www.stud.uni-karlsruhe.de/~unk6/clim-spec/"
19               url))
20
21(defun set-abbrev (term)
22  (let ((abbrev (abbrev:abbrev term)))
23    (if abbrev
24        (pushnew term (gethash abbrev *clim-abbrev-table* nil)
25                 :test #'string-equal))))
26
27(defun populate-table ()
28  (setf *clim-table* (make-hash-table :test #'equalp))
29  (setf *clim-abbrev-table* (make-hash-table :test #'equalp))
30  (with-open-file (f *clim-file* :direction :input)
31    (loop for i = (read f nil nil)
32          while i
33          do (destructuring-bind (ig1 (term sep (ig2 type)) url)
34                 i
35               (declare (ignore ig1 ig2 sep))
36               (setf term (substitute #\space (code-char 160) term :test #'eql))
37               (setf type (substitute #\space (code-char 160) type :test #'eql))
38               (push (cons type url)
39                     (gethash term *clim-table* nil))
40               (set-abbrev term)))))
41
42(defun abbrev-lookup (term)
43  (let ((found (gethash term *clim-abbrev-table* nil)))
44    (if found
45        (if (eql (length found) 1)
46            (let ((r (real-term-lookup (car found))))
47              (and r
48                   (concatenate 'string (car found) ": " r)))
49            (format nil "Multiple matches found. Try any of: ~{~A~^ ~}"
50                    found)))))
51
52(defun real-term-lookup (term)
53  (destructuring-bind (real-term &optional type (index-str "0"))
54      (split-sequence #\, term)
55    (let ((ents (gethash real-term *clim-table* nil))
56          (index (parse-integer index-str :junk-allowed t)))
57      (if type
58          (let ((all-type (loop for ent in ents
59                                if (string-equal (car ent) type)
60                                collect ent)))
61            (if (< index (length all-type))
62                (merge-to-spec (cdr (nth index all-type)))
63                (format nil "Invalid index ~A: must be between 0 and ~A."
64                        index (1- (length all-type)))))
65          (if (eql (length ents) 0)
66              nil
67              (if (eql (length ents) 1)
68                  (merge-to-spec (cdr (car ents)))
69                  (let ((unique-types nil))
70                    (loop for ent in ents
71                          do (pushnew (car ent) unique-types :test #'string-equal))
72                    (format nil "Multiple entries found. Try looking up one of: ~{\"~A\"~^, ~}"
73                            (mapcar #'(lambda (type)
74                                        (format nil "~A,~A~A"
75                                                real-term
76                                                type
77                                                (let ((count (count type ents :key #'car :test #'string-equal)))
78                                                  (if (> count 1)
79                                                      (format nil ",{0-~A}"
80                                                              (1- count))
81                                                      ""))))
82                                    unique-types)))))))))
83
84(defun term-lookup (term)
85  (or (real-term-lookup term)
86      (abbrev-lookup term)))
Note: See TracBrowser for help on using the repository browser.