[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Hypertext in MCL?
- To: info-mcl@ministry.cambridge.apple.com
- Subject: Re: Hypertext in MCL?
- From: chrispi@merle.acns.nwu.edu (Chris Crone)
- Date: 17 May 1994 05:43:21 GMT
- Followup-to: comp.lang.lisp.mcl
- Newsgroups: comp.lang.lisp.mcl
- Organization: Northwestern University, SESP
- References: <1994May16.201458.16399@midway.uchicago.edu>
In article <1994May16.201458.16399@midway.uchicago.edu>,
fensterm@cs.uchicago.edu (Kurt D. Fenstermacher) wrote:
> I'd like to implement a "hypertext" system in MCL. The program I'm
> working on involves retrieving recipes from a database, given a user
> request in English (e.g. "I'm looking for a recipe for a Thai peanut
> salad dressing, which is spicy, but also a little sour.") After I've
> recalled the appropriate recipes, I'd like the user to be able to click
> on keywords (e.g. what in the recipe made the program conclude that it
> was sour?) in the recipe text, and get an explanation of the program's
> "chain of thought.".
>
> At the moment the parse code which processes the recipes produces
> embedded codes in the text to indicate these keywords. Currently, I
> can display the plain text using a static text dialog item. But how
> can I turn a plain text item (i.e. a word) into a button, indicated by
> a different foreground/background color?
>
> One solution seems to be to calculate (based on window size, font size,
> etc.) the position of the word in the dialog item, and then draw a
> button with the word/phrase as the button's text, in the appropriate
> location, right over the existing word. But this calucation would be
> complicated by such things as proportional fonts, resized windows, etc.
> Are there higher-level functions to do implement hypertext more
> cleanly?
There's a method called fred-point-position, which returns the position in
a fred-item's buffer nearest to a point. For example if you click on a
character, and that character is the 5th in the fred-buffer,
fred-point-position of the point of that click would return 5. Of course,
fred-point-position probably is undefined for static-text-dialog-items (try
it and see!). I'd suggest specializing a fred-something
(fred-dialog-item?) for your purposes.
It seems like you could surround this with a function to return the word
that the click was in (parse for whitespace), returning (buffer-substring
...) and interface that to your database of word-meanings or uses. This
behavior could all be implemented in the view-click-event-handler for your
class. If you make your class' view-key-event-handler nil, and the
view-click-event-handler nil except for this hypertexting thing and use
view-cursor to make the cursor appropriate, it should act just like a
static-text-dialog-item.
Does this sound like a solution to your problem? If you're confused by the
CLOS-ish object-oriented stuff, check out a friend's copy of Sonya E.
Keene's Object-Oriented Programming in Common Lisp. Certainly if you have
any questions, feel free to ask me -- and, of course, definitely let me
know whether this was helpful to you. It doesn't seem hard to implement at
all, lots easier that the button stuff...
Try something like this...
(defclass hyper-fred (fred-dialog-item) ;; inherits fredness...
())
(defmethod view-key-event-handler ((self hyper-fred) char)
()) ;; deaf and dumb to keystrokes
(defmethod view-click-event-handler ((self hyper-fred) where)
(when (and *hyperactive* (double-click-p)
(not (> *multi-click-count* 2))) ;; guard against additional
clicking
(act-on (current-word self (fred-point-position self where)))))
(defun current-word (hyper-fred position) ;; returns string-- nearest
word
(let* ((hyper-fred-buffer (fred-buffer hyper-fred))
(begin-word
(1+ (or (buffer-string-pos hyper-fred-buffer " "
:start 0 :end position :from-end t) -1)))
(end-word
(or (buffer-string-pos hyper-fred-buffer " " :start position)
(buffer-size (fred-buffer hyper-fred)))))
(set-selection-range hyper-fred begin-word end-word)
(buffer-substring (fred-buffer hyper-fred) begin-word end-word)))
(defun act-on (string)
(format t "~%You clicked on ~s" string))
(defvar win (make-instance 'window :view-size #@(400 15)))
(defvar piper ;; the hyperfred!
(make-instance 'hyper-fred
:view-size #@(400 15)
:dialog-item-text "This is a very fine day to be living on the south
side of chicago."))
(add-subviews win piper)
(defvar *hyperactive* t)
(set-selection-range piper 0 0)
> Thanks for your help.
>
> Kurt D. Fenstermacher
> Artificial Intelligence Laboratory
> University of Chicago
welcome.
chris
--
Chris Crone
Northwestern University, School of Education and Social Policy
chrispi@merle.acns.nwu.edu