grunwald@flute.cs.uiuc.edu (Dirk Grunwald) (07/12/89)
The following is a modified webster.el that supports the INDEX keyword
in the webster server for NeXT machines written by Steve Hayman
(sahayman@iuvax.cs.indiana.edu)
Please do not contact me asking for webster servers. I now use the NeXT
box down the hall; a local guru called NeXT and they reportedly said they
couldn't see any copyright problems with using the webster database as
a server.
This version defines webster-thesaurus, and a bevy of webster-select-
functions to choose one of the three possible databases.
;; Copyright (C) 1989 Free Software Foundation
;; This file is part of GNU Emacs.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY. No author or distributor
;; accepts responsibility to anyone for the consequences of using it
;; or for whether it serves any particular purpose or works at all,
;; unless he says so in writing. Refer to the GNU Emacs General Public
;; License for full details.
;; Everyone is granted permission to copy, modify and redistribute
;; GNU Emacs, but only under the conditions described in the
;; GNU Emacs General Public License. A copy of this license is
;; supposed to have been given to you along with GNU Emacs so you
;; can know your rights and responsibilities. It should be in a
;; file named COPYING. Among other things, the copyright notice
;; and this notice must be preserved on all copies.
;;
;; Author Jason R. Glasgow (glasgow@cs.yale.edu)
;; Modified from telnet.el by William F. Schelter
;; But almost entirely different.
;;
;; Modified by Dirk Grunwald to maintain an open connection.
;;
;; 3/18/89 Ashwin Ram <Ram-Ashwin@yale.edu>
;; Added webster-mode.
;; Fixed documentation.
;;
;; 3/20/89 Dirk Grunwald <grunwald@flute.cs.uiuc.edu>
;; Merged Rams changes with new additions: smarter window placement,
;; correctly handles un-exposed webster windows, minor cleanups.
;;
;; 3/21/89 Someone (forgot who) suggested & posted webster that yanked
;; default argument
;;
;; 3/23/89 Ed Reingold suggests having prompted word be available
;; for editing.
;;
;; 7/10/89 Added webster-thesaurus command for NeXT-webster servers.
;;
;; To use this, you might want to add this line to your .emacs file:
;;
;; (autoload 'webster "webster" "look up a word in Webster's 7th edition" t)
;;
;; Then just hit M-x webster to look up a word.
;;
(defvar webster-host "your.webster.server.here"
"Host that is a webster server.")
(defvar webster-port "2627"
"The port to connect to. Either 103 or 2627")
(defvar webster-process nil
"The current webster process")
(defvar webster-process-name "webster"
"The current webster process")
(defvar webster-buffer nil
"The current webster process")
(defvar webster-running nil
"Used to determine when connection is established")
(defvar webster-selected 'dictionary
"What webster database is currently selected?")
;;;
;;; Initial filter for ignoring information until successfully connected
;;;
(defun webster-initial-filter (proc string)
(let
(( this-buffer (current-buffer)))
(set-buffer webster-buffer)
(goto-char (point-max))
(cond
((not (eq (process-status webster-process) 'run))
(progn
(setq webster-running t)
(message "Webster died")))
((string-match "telnet:" string)
(let*
((m (substring string (1+ (match-end 0))))
(message (substring m 0 (string-match "\n" m))))
(setq webster-running t)
(kill-buffer (process-buffer proc))
(error message)))
((string-match "]" string)
(progn
(setq webster-running t)
(set-process-filter proc 'webster-filter)))
( t (insert string)))
(set-buffer this-buffer)))
(defun webster-filter (proc string)
(let
((closed-message (string-match "Connection closed" string))
(end-def-message (or (string-match "\200" string) (string-match "\0" string)))
( this-buffer (current-buffer)))
(set-buffer webster-buffer)
(cond
((not (eq (process-status webster-process) 'run))
(message "Webster died"))
(closed-message
(message "Closing webster connection...")
(kill-process proc)
(replace-regexp "Process webster killed" "" nil)
(goto-char 1)
(message "Closing webster connection...Done."))
((string-match "SPELLING 0" string)
(insert-string "...Word not found in webster\n"))
((string-match "SPELLING 1" string)
(insert-string "...Spelled correctly\n"))
(end-def-message
(webster-filter proc (concat (substring string 0 (- end-def-message 1)) "\n\n"))
(goto-char (point-max)))
(t
(goto-char (point-max))
(let ((now (point)))
(insert string)
(delete-char-in-region now (point) ?\^m ?\ ))
(if (process-mark proc)
(set-marker (process-mark proc) (point)))))
;;
;; if webster is visible, move the last line to the bottom of that window
;;
(let ((here (selected-window)))
(let ((webster-window (get-buffer-window webster-buffer)))
(if (windowp webster-window)
(progn
(select-window webster-window)
(recenter -1)
(select-window here)))))
(set-buffer this-buffer)))
;;;
;;; delete char1 and char2 if it precedes char1
;;; used to get rid of <space><return>
(defun delete-char-in-region (start end char1 char2)
(goto-char start)
(while (search-forward (char-to-string char1) end t)
(backward-delete-char 1)
(if (equal (char-after (- (point) 1)) char2)
(backward-delete-char 1))))
;; Snatched from unix-apropos by Henry Kautz
(defun webster-current-word ()
"Word cursor is over, as a string."
(save-excursion
(let (beg end)
(re-search-backward "\\w" nil 2)
(re-search-backward "\\b" nil 2)
(setq beg (point))
(re-search-forward "\\w*\\b" nil 2)
(setq end (point))
(buffer-substring beg end))))
(defun webster (arg)
"Look up a word in the Webster's dictionary.
Open a network login connection to a webster host if necessary.
Communication with host is recorded in a buffer *webster*."
(interactive (list
(read-string
(concat "Look up word in webster: ") (webster-current-word) )))
(if (equal "" arg) (setq arg (webster-current-word)))
(webster-send-request "DEFINE" arg))
(defun webster-endings (arg)
"Look up endings for a word in the Webster's dictionary.
Open a network login connection to a webster host if necessary.
Communication with host is recorded in a buffer *webster*."
(interactive (list
(read-string
(concat "Find endings for word in webster: ") (webster-current-word) )))
(webster-send-request "ENDINGS" arg))
(defun webster-spell (arg)
"Look spelling for a word in the Webster's dictionary.
Open a network login connection to a webster host if necessary.
Communication with host is recorded in a buffer *webster*."
(interactive (list
(read-string
(concat "Spell word in webster: ") (webster-current-word) )))
(if (equal "" arg) (setq arg (webster-current-word)))
(webster-send-request "SPELL" arg))
;;;
;; The following defuns only work with servers that use the
;; NeXT-webster database
;;
(defun webster-select-dictionary ()
"Select the default webster dictionary; only suitable for NeXT-Webster"
(interactive)
(setq webster-selected 'dictionary)
(webster-send-request "INDEX" "dictionary"))
(defun webster-select-thesaurus ()
"Select the webster thesaurus; only suitable for NeXT-Webster"
(interactive)
(setq webster-selected 'thesaurus)
(webster-send-request "INDEX" "thesaurus"))
(defun webster-select-dictionary-full ()
"Select the full webster dictionary; only suitable for NeXT-Webster"
(interactive)
(setq webster-selected 'dictionary-full)
(webster-send-request "INDEX" "dictionary-full"))
(defun webster-select-using (what)
(cond
( (eq what 'dictionary-full)
(if (not (eq webster-selected 'dictionary-full))
(webster-select-dictionary-full)))
( (eq what 'thesaurus)
(if (not (eq webster-selected 'thesaurus))
(webster-select-thesaurus)))
( t
(if (not (eq webster-selected 'dictionary))
(webster-select-dictionary)))))
(defun webster-thesaurus (arg)
"Look up a word in the Webster's thesaurus.
This only works on NeXT-Webster servers."
(interactive (list
(read-string
(concat "Spell word in webster: ") (webster-current-word) )))
(if (equal "" arg) (setq arg (webster-current-word)))
(let
( (current-what webster-selected) )
(webster-select-using 'thesaurus)
(webster-send-request "DEFINE" arg)
(webster-select-using current-what)))
(defun webster-send-request (kind word)
(require 'shell)
(let
((webster-command (concat "open " webster-host " " webster-port "\n")))
(if (or
(not webster-buffer)
(not webster-process)
(not (eq (process-status webster-process) 'run)))
(progn
(message
(concat "Attempting to connect to server " webster-host "..."))
(setq webster-buffer
(make-shell webster-process-name "telnet"))
(let
((this-buffer (current-buffer)))
(set-buffer webster-buffer)
(webster-mode)
(set-buffer this-buffer))
(setq webster-process (get-process webster-process-name))
(set-process-filter webster-process 'webster-initial-filter)
(process-send-string webster-process webster-command)
(setq webster-running nil);
(while (not webster-running) ; wait for feedback
(accept-process-output)))) ;
(display-buffer webster-buffer nil)
(process-send-string webster-process (concat kind " " word "\n"))))
(defun webster-quit ()
"Close connection and quit webster-mode.
Buffer is not deleted."
(interactive)
(message "Closing connection to %s..." webster-host)
(kill-process webster-process)
(message "Closing connection to %s...done" webster-host)
(bury-buffer))
(defun webster-mode ()
"Major mode for interacting with on-line Webster's dictionary.
\\{webster-mode-map}
Use webster-mode-hook for customization."
(interactive)
(kill-all-local-variables)
(setq major-mode 'webster-mode)
(setq mode-name "Webster")
(use-local-map webster-mode-map)
(run-hooks 'webster-mode-hook))
(defvar webster-mode-map nil)
(if webster-mode-map
nil
(setq webster-mode-map (make-sparse-keymap))
(define-key webster-mode-map "?" 'describe-mode)
(define-key webster-mode-map "d" 'webster)
(define-key webster-mode-map "e" 'webster-endings)
(define-key webster-mode-map "q" 'webster-quit)
(define-key webster-mode-map "s" 'webster-spell))
--
Dirk Grunwald -- Univ. of Illinois (grunwald@flute.cs.uiuc.edu)kadie@m.cs.uiuc.edu (07/17/89)
Fun activity #323 for the Gnu/NeXT/Webster STEP 1: M-x webster-select-dictionary-full STEP 2: Ask about the word "vulgar" STEP 3: See every VULGAR word in the dictionary. (VULGAR is the way that this dictionary marks words that a less grown-up dictionary might leave out altogether.) You may also wish to try "obscene". - Carl Kadie U. of Illinois