#!/usr/bin/clisp -q -q -C
;                         -*- mode: lisp -*-

;;; Make sure xpdf and djview are available on your system.

;;; Set the values at the end of the file
(defvar *dictionary-file* nil "Full path to the dictionary file (pdf/djvu).")
(defvar *first-page* nil "Page # of the first real dictionary page.")
(defvar *pages* nil "CONS pairs (first-word . last-word) for every page.")

(defun lookup (str)
  (flet ((dictionary-search (input entry)
           (and (string< (string-downcase (car entry))
                         (string-downcase input))
                (string<= (string-downcase input)
                          (string-downcase (cdr entry)))))
         (tolerant-dictionary-search (input entry)
           (string< (string-downcase input) (string-downcase (cdr entry)))))
    (+ *first-page*
       (or (position str *pages* :test #'dictionary-search)
           (position str *pages* :test #'tolerant-dictionary-search)
           0))))

(defun showpage (page)
  (if (string= (string-downcase
                (subseq *dictionary-file* (- (length *dictionary-file*) 3)))
               "pdf")
      (ext:run-program "xpdf" :arguments
                       (list *dictionary-file* (format nil "~d" page)))
      (ext:run-program "djview" :arguments
                       (list *dictionary-file* "-page" (format nil "~d" page)))))

(defun main-loop ()
  (format t "Search for: ")
  (let ((line (read-line)))
    (when (string/= line "quit")
      (showpage (lookup line))
      (main-loop))))

;;; Sample data
(setf *dictionary-file*
      "/path/to/some/dictionary.pdf"
      *first-page*
      13
      *pages*
      '(("abacus" . "cinnamon")         ; page 13
        ("citrus" . "fig")              ; page 14
        ("funnel" . "lime")             ; page 15
        ("litre" . "pig")               ; ...
        ("pork" . "tunnel")
        ("turret" . "zimbabwe")))

(main-loop)