diff --git a/lispusers/DINFO b/lispusers/DINFO
index 056c76fe..88b13c0b 100644
--- a/lispusers/DINFO
+++ b/lispusers/DINFO
@@ -1 +1 @@
-(DEFINE-FILE-INFO PACKAGE "INTERLISP" READTABLE "INTERLISP" BASE 10)
(FILECREATED " 1-Oct-87 10:11:04" {ERINYES}<LISPUSERS>LYRIC>DINFO.;4 63282  

      changes to%:  (VARS DINFOCOMS)
                    (FNS DINFO.UPDATE.GRAPH.DISPLAY DINFO.TOGGLE.GRAPH)
                    (FUNCTIONS DINFOGRAPHPROP)

      previous date%: "14-Sep-87 12:00:05" {ERINYES}<LISPUSERS>LYRIC>DINFO.;2)


(* "
Copyright (c) 1985, 1986, 1987 by Xerox Corporation.  All rights reserved.
")

(PRETTYCOMPRINT DINFOCOMS)

(RPAQQ DINFOCOMS ((FILES TEDIT GRAPHER)
                  (RECORDS DINFOGRAPH DINFONODE)
                  (FUNCTIONS DINFOGRAPHPROP)
                  (FNS                                       (* ; "Primary functions")

                       DINFO DINFO.UPDATE DINFOGRAPH DINFO.SPECIAL.UPDATE DINFO.READ.GRAPH 
                       DINFO.WRITE.GRAPH DINFO.SELECT.GRAPH DINFO.DEFAULT.MENU DINFO.FIND 
                       DINFO.LOOKUP)
                  (FNS                                       (* ; "Koto compatability")

                       DINFO.READ.KOTO.GRAPH)
                  (FNS                                       (* ; "Window functions")

                       DINFO.SETUP.WINDOW DINFO.CLOSEFN DINFO.SHRINKFN DINFO.EXPANDFN DINFO.ICONFN)
                  (FNS                                       (* ; "FreeMenu functions")

                       DINFO.ADD.FMENU DINFO.CREATE.FMENU DINFO.FMW.CLOSEFN DINFO.FMENU.HANDLER 
                       DINFO.UPDATE.FMENU DINFO.TOGGLE.MENU DINFO.TOGGLE.GRAPH DINFO.TOGGLE.HISTORY 
                       DINFO.TOGGLE.TEXT)
                  (FNS                                       (* ; "Other menu functions")

                       DINFO.UPDATE.MENU.DISPLAY DINFO.UPDATE.FROM.MENU DINFO.UPDATE.HISTORY 
                       DINFO.HISTORIC.UPDATE)
                  (FNS                                       (* ; "Interface to GRAPHER")

                       DINFO.UPDATE.GRAPH.DISPLAY DINFO.UPDATE.FROM.GRAPH DINFO.GET.GRAPH.WINDOW 
                       DINFO.CREATE.GRAPH.WINDOW DINFO.SHOWGRAPH DINFO.INVERT.NODE DINFO.LAYOUTGRAPH)
                  (FNS                                       (* ; "Interface to TEdit")

                       DINFO.UPDATE.TEXT.DISPLAY DINFO.TITLEMENUFN DINFO.OPENTEXTSTREAM DINFO.SHOWSEL 
                       DINFO.GET.FILENAME)
                  (ADDVARS (BackgroundMenuCommands (DInfo (DINFO.SELECT.GRAPH)
                                                          
                                                    "Open a DInfo window for browsing documentation."
                                                          )))
                  (VARS (BackgroundMenu))
                  (INITVARS (DINFO.GRAPHS)
                         (DINFOMODES '(TEXT GRAPH))
                         (DINFO.HISTORY.LENGTH 20)
                         (\DINFO.MAX.MENU.LEN 10))
                  (GLOBALVARS DINFO.GRAPH.FILES DINFOMODES DINFO.HISTORY.LENGTH \DINFO.MAX.MENU.LEN)
                  (PROP (FILETYPE)
                        DINFO)))
(FILESLOAD TEDIT GRAPHER)
(DECLARE%: EVAL@COMPILE

(DATATYPE DINFOGRAPH 
          (NAME NODELST TOPNODEID CURRENTNODE USERDATA TEXTPROPS FREEMENUITEMS LOOKUPFN MENUFN 
                DEFAULTHOST DEFAULTDEVICE DEFAULTDIR MONITORLOCK DINFO.MENU WINDOW MENUFONT 
                FMENU.WINDOW GRAPH.WINDOW HISTORY.MENU.WINDOW SUBNODE.MENU.WINDOW LAST.TEXT 
                LAST.INVERTED.NODE LAST.GRAPH.LOCATION HISTORY.ITEMS FIND.STRING LOOKUP.STRING)
          (SYSTEM))

(RECORD DINFONODE (ID LABEL FILE FROMBYTE TOBYTE PARENT CHILDREN NEXTNODE PREVIOUSNODE USERDATA)
                  (SYSTEM))
)
(/DECLAREDATATYPE 'DINFOGRAPH
       '(POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER 
               POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER 
               POINTER POINTER POINTER POINTER POINTER)
       '((DINFOGRAPH 0 POINTER)
         (DINFOGRAPH 2 POINTER)
         (DINFOGRAPH 4 POINTER)
         (DINFOGRAPH 6 POINTER)
         (DINFOGRAPH 8 POINTER)
         (DINFOGRAPH 10 POINTER)
         (DINFOGRAPH 12 POINTER)
         (DINFOGRAPH 14 POINTER)
         (DINFOGRAPH 16 POINTER)
         (DINFOGRAPH 18 POINTER)
         (DINFOGRAPH 20 POINTER)
         (DINFOGRAPH 22 POINTER)
         (DINFOGRAPH 24 POINTER)
         (DINFOGRAPH 26 POINTER)
         (DINFOGRAPH 28 POINTER)
         (DINFOGRAPH 30 POINTER)
         (DINFOGRAPH 32 POINTER)
         (DINFOGRAPH 34 POINTER)
         (DINFOGRAPH 36 POINTER)
         (DINFOGRAPH 38 POINTER)
         (DINFOGRAPH 40 POINTER)
         (DINFOGRAPH 42 POINTER)
         (DINFOGRAPH 44 POINTER)
         (DINFOGRAPH 46 POINTER)
         (DINFOGRAPH 48 POINTER)
         (DINFOGRAPH 50 POINTER))
       '52)

(DEFMACRO DINFOGRAPHPROP (GRAPH PROP &OPTIONAL (NEW-VALUE NIL NEW-VALUE-SUPPLIED))
   [LET [(REAL-FIELD (AND (LISTP PROP)
                          (EQ (CAR PROP)
                              'QUOTE)
                          (FMEMB (CADR PROP)
                                 (RECORDFIELDNAMES 'DINFOGRAPH T))
                          (CADR PROP]
        (IF NEW-VALUE-SUPPLIED
            THEN [IF REAL-FIELD
                     THEN `(REPLACE (DINFOGRAPH ,REAL-FIELD) OF ,GRAPH WITH ,NEW-VALUE)
                   ELSE `(LET* ((SI::$GRAPH$ ,GRAPH)
                                (SI::$USERDATA$ (FETCH (DINFOGRAPH USERDATA) OF SI::$GRAPH$))
                                (SI::$PROP$ ,PROP)
                                (SI::$NEW-VALUE$ ,NEW-VALUE))
                               (IF (LISTP SI::$USERDATA$)
                                   THEN (LISTPUT SI::$USERDATA$ SI::$PROP$ SI::$NEW-VALUE$)
                                 ELSE (REPLACE (DINFOGRAPH USERDATA) OF SI::$GRAPH$
                                         WITH (LIST SI::$PROP$ SI::$NEW-VALUE$))
                                      SI::$NEW-VALUE$]
          ELSE (IF REAL-FIELD
                   THEN `(FETCH (DINFOGRAPH ,REAL-FIELD) OF ,GRAPH)
                 ELSE `(LISTGET (FETCH (DINFOGRAPH USERDATA) OF ,GRAPH)
                              ,PROP])

(DEFINEQ

(DINFO
  [LAMBDA (GRAPH.OR.FILE WINDOW.OR.REGION SETUP.ONLY? NO.FREEMENU?)
                                                             (* drc%: "25-Jan-86 18:23")
                                                             (* Starts a DInfo browser.)
    (RESETLST (LET ((W (OR (WINDOWP WINDOW.OR.REGION)
                           (AND (REGIONP WINDOW.OR.REGION)
                                (CREATEW WINDOW.OR.REGION "DInfo" NIL T))
                           (AND (type? DINFOGRAPH GRAPH.OR.FILE)
                                (WINDOWP (fetch (DINFOGRAPH WINDOW) of GRAPH.OR.FILE)))
                           (CREATEW NIL "DInfo")))
                    GRAPH MONITORLOCK)
                   (OPENW W)
                   [SETQ GRAPH (if (type? DINFOGRAPH GRAPH.OR.FILE)
                                   then GRAPH.OR.FILE
                                 else (RESETFORM (TTYDISPLAYSTREAM (GETPROMPTWINDOW W))
                                             (DINFO.READ.GRAPH GRAPH.OR.FILE]
                   [SETQ MONITORLOCK (OR (fetch (DINFOGRAPH MONITORLOCK) of GRAPH)
                                         (replace (DINFOGRAPH MONITORLOCK) of GRAPH
                                            with (CREATE.MONITORLOCK "DInfo"]
                   (RESETSAVE NIL (LIST 'RELEASE.MONITORLOCK MONITORLOCK))
                   (OBTAIN.MONITORLOCK MONITORLOCK)
                   (DINFO.SETUP.WINDOW GRAPH W NO.FREEMENU?)
                   (OR SETUP.ONLY? (DINFO.UPDATE GRAPH NIL NIL T))
                   GRAPH])

(DINFO.UPDATE
  [LAMBDA (GRAPH NEW.NODE SEL FORCE?)                        (* jow "20-May-86 15:14")
          
          (* * Called to visit a NEW.NODE in GRAPH, or to just make sure that the display 
          of GRAPH is current.)

    (LET ([NODE (OR NEW.NODE (fetch (DINFOGRAPH CURRENTNODE) of GRAPH)
                    (FASSOC (fetch (DINFOGRAPH TOPNODEID) of GRAPH)
                           (fetch (DINFOGRAPH NODELST) of GRAPH]
          (PREVIOUS.NODE (fetch (DINFOGRAPH CURRENTNODE) of GRAPH))
          (WINDOW (fetch (DINFOGRAPH WINDOW) of GRAPH)))
         (OPENW WINDOW)
         (WINDOWPROP WINDOW 'DINFOGRAPH GRAPH)
         (OR (FMEMB NODE (fetch (DINFOGRAPH NODELST) of GRAPH))
             (ERROR NODE "NOT IN NODELST"))
         (LET ((FMENU.WINDOW (fetch (DINFOGRAPH FMENU.WINDOW) of GRAPH))
               (MONITORLOCK (fetch (DINFOGRAPH MONITORLOCK) of GRAPH)))
              [RESETLST (RESETSAVE NIL (LIST 'RELEASE.MONITORLOCK MONITORLOCK))
                     (if (NOT (OBTAIN.MONITORLOCK MONITORLOCK T))
                         then                                (* somebody else is messing with this 
                                                             graph.)
                              (FLASHWINDOW WINDOW)
                              (PROMPTPRINT "DInfo is busy")
                       elseif (NULL FMENU.WINDOW)
                         then (replace (DINFOGRAPH CURRENTNODE) of GRAPH with NODE) 
                                                             (* FreeMenu turned off, so just 
                                                             display text)
                              (DINFO.UPDATE.TEXT.DISPLAY GRAPH NODE SEL)
                       else                                  (* We've got a FreeMenu, so update 
                                                             away!)
                            (DINFO.UPDATE.FMENU GRAPH NODE)
                            (LET ((STATUS (FM.GETSTATE FMENU.WINDOW)))
                                 (replace (DINFOGRAPH CURRENTNODE) of GRAPH with NODE)
                                 (AND (LISTGET STATUS 'GRAPH)
                                      (DINFO.UPDATE.GRAPH.DISPLAY GRAPH NODE FORCE?))
                                 (AND (LISTGET STATUS 'MENU)
                                      (DINFO.UPDATE.MENU.DISPLAY GRAPH NODE))
                                 (AND (LISTGET STATUS 'TEXT)
                                      (DINFO.UPDATE.TEXT.DISPLAY GRAPH NODE SEL))
                                 (DINFO.UPDATE.HISTORY GRAPH NODE SEL (LISTGET STATUS 'HISTORY]
              (CLEARW (GETPROMPTWINDOW WINDOW])

(DINFOGRAPH
  [LAMBDA (X)                                                (* drc%: " 8-Jan-86 11:12")
    (if (type? DINFOGRAPH X)
        then X
      elseif (AND (WINDOWP X)
                  (WINDOWPROP X 'DINFOGRAPH))
      elseif (AND (WINDOWP X)
                  (WINDOWPROP X 'MAINWINDOW))
        then (WINDOWPROP (WINDOWPROP X 'MAINWINDOW)
                    'DINFOGRAPH])

(DINFO.SPECIAL.UPDATE
  [LAMBDA (TYPE GRAPH)                                       (* drc%: "25-Jan-86 18:26")
          
          (* * Do a TYPE update of Graph, where TYPE is one of Top, Parent, Previous or 
          Next.)

    (LET* [(DINFOW (fetch (DINFOGRAPH WINDOW) of GRAPH))
           (CURRENT.NODE (fetch (DINFOGRAPH CURRENTNODE) of GRAPH))
           (NEW.NODE (FASSOC (SELECTQ TYPE
                                 (Top (fetch (DINFOGRAPH TOPNODEID) of GRAPH))
                                 (Parent (fetch (DINFONODE PARENT) of CURRENT.NODE))
                                 (Next (fetch (DINFONODE NEXTNODE) of CURRENT.NODE))
                                 (Previous (fetch (DINFONODE PREVIOUSNODE) of CURRENT.NODE))
                                 NIL)
                            (fetch (DINFOGRAPH NODELST) of GRAPH]
          (if (OBTAIN.MONITORLOCK (fetch (DINFOGRAPH MONITORLOCK) of GRAPH)
                     T)
              then (if NEW.NODE
                       then (PROCESSPROP (THIS.PROCESS)
                                   'NAME
                                   (CONCAT "DInfo " TYPE))
                            (DINFO.UPDATE GRAPH NEW.NODE)
                     else 
          
          (* TYPE of Top! or Node! will sound silly here, but should never happen.)

                          (printout (GETPROMPTWINDOW (fetch (DINFOGRAPH WINDOW) of GRAPH))
                                 T "This node has no " TYPE))
            else (FLASHWINDOW DINFOW)
                 (PROMPTPRINT "DInfo is busy"])

(DINFO.READ.GRAPH
  [LAMBDA (FILE QUIETFLG)                                    (* drc%: "25-Jan-86 18:17")
          
          (* Reads a file written by DINFO.WRITE.GRAPH.
          Returns the DInfo graph stored on FILE.)

    (OR QUIETFLG (printout T T "Reading " (FILENAMEFIELD FILE 'NAME)
                        " graph..."))
    (LET* ((FULLFILENAME (INFILEP FILE))
           [DATA (CDR (READFILE (OR FULLFILENAME (ERROR "FILE NOT FOUND" FILE]
           (GRAPH (create DINFOGRAPH)))                      (* fields stored on file)
          (replace (DINFOGRAPH TOPNODEID) of GRAPH with (LISTGET DATA 'TOPNODEID))
          (replace (DINFOGRAPH TEXTPROPS) of GRAPH with (LISTGET DATA 'TEXTPROPS))
          (replace (DINFOGRAPH LOOKUPFN) of GRAPH with (LISTGET DATA 'LOOKUPFN))
          (replace (DINFOGRAPH MENUFN) of GRAPH with (LISTGET DATA 'MENUFN))
          (replace (DINFOGRAPH FREEMENUITEMS) of GRAPH with (LISTGET DATA 'FREEMENUITEMS))
          (replace (DINFOGRAPH NODELST) of GRAPH with (LISTGET DATA 'NODELST))
          (replace (DINFOGRAPH USERDATA) of GRAPH with (LISTGET DATA 'USERDATA))
                                                             (* fields filled in at read time)
          (replace (DINFOGRAPH NAME) of GRAPH with (FILENAMEFIELD FULLFILENAME 'NAME))
          (replace (DINFOGRAPH DEFAULTHOST) of GRAPH with (FILENAMEFIELD FULLFILENAME 'HOST))
          (replace (DINFOGRAPH DEFAULTDEVICE) of GRAPH with (FILENAMEFIELD FULLFILENAME 'DEVICE))
          (replace (DINFOGRAPH DEFAULTDIR) of GRAPH with (FILENAMEFIELD FULLFILENAME 'DIRECTORY))
          (OR QUIETFLG (printout T "OK."))
          GRAPH])

(DINFO.WRITE.GRAPH
  [LAMBDA (GRAPH FILE)                                       (* drc%: "25-Jan-86 18:16")
          
          (* Writes a DInfo graph to a file for reading by DINFO.READ.GRAPH.
          Returns the full file name of the file.)
                                                             (* dump it out as a props list)
    (WRITEFILE (LIST 'TOPNODEID (fetch (DINFOGRAPH TOPNODEID) of GRAPH)
                     'TEXTPROPS
                     (fetch (DINFOGRAPH TEXTPROPS) of GRAPH)
                     'LOOKUPFN
                     (fetch (DINFOGRAPH LOOKUPFN) of GRAPH)
                     'MENUFN
                     (fetch (DINFOGRAPH MENUFN) of GRAPH)
                     'FREEMENUITEMS
                     (fetch (DINFOGRAPH FREEMENUITEMS) of GRAPH)
                     'NODELST
                     (fetch (DINFOGRAPH NODELST) of GRAPH)
                     'USERDATA
                     (fetch (DINFOGRAPH USERDATA) of GRAPH))
           FILE])

(DINFO.SELECT.GRAPH
  [LAMBDA NIL                                                (* drc%: "24-Jan-86 13:25")
          
          (* * This is called when DInfo is selected from the Background Menu.)

    (DECLARE (GLOBALVARS DINFO.GRAPHS))
    (ALLOW.BUTTON.EVENTS)
    (RESETFORM (TTY.PROCESS (THIS.PROCESS))
           (LET [(GRAPH (if (NULL DINFO.GRAPHS)
                            then (PROMPTPRINT "No Graphs installed -- load HelpSys or DInfoEdit")
                          elseif (NULL (CDR DINFO.GRAPHS))
                            then (EVAL (CADAR DINFO.GRAPHS))
                          else (MENU (create MENU
                                            CENTERFLG _ T
                                            TITLE _ "Select Graph"
                                            ITEMS _ DINFO.GRAPHS]
                (AND GRAPH (DINFO GRAPH])

(DINFO.DEFAULT.MENU
  [LAMBDA (GRAPH)                                            (* jow "15-Jul-86 17:36")
          
          (* * This is the default MENUFN for DInfo graphs.)

    (LET ((DINFOW (fetch (DINFOGRAPH WINDOW) of GRAPH)))
         (CLEARW (GETPROMPTWINDOW DINFOW))
         (LET [(TYPE (MENU (OR (fetch (DINFOGRAPH DINFO.MENU) of GRAPH)
                               (replace (DINFOGRAPH DINFO.MENU) of GRAPH
                                  with (create MENU
                                              ITEMS _ '(("Top" 'Top "Visit the top node in the graph"
                                                               )
                                                        ("Parent" 'Parent 
                                                               "Visit the parent of the current node"
                                                               )
                                                        ("Previous" 'Previous 
                                                               "Visit the node before this node")
                                                        ("Next " 'Next 
                                                               "Visit the node following this node")
                                                        ("Find" 'Find "Search the text of this node")
                                                        ("Lookup" 'Lookup 
                                                               "Lookup a new term in this graph")
                                                        ("Expanded Menu" 'FreeMenu 
                                                               "Add an expanded options menu."))
                                              CENTERFLG _ T
                                              MENUFONT _ (FONTCREATE 'HELVETICA 10 'BOLD]
              (if TYPE
                  then (PROCESSPROP (THIS.PROCESS)
                              'NAME
                              (CONCAT "DInfo " TYPE))
                       (SELECTQ TYPE
                           ((Top Parent Previous Next) 
                                (DINFO.SPECIAL.UPDATE TYPE GRAPH))
                           (Find (DINFO.FIND GRAPH))
                           (Lookup (DINFO.LOOKUP GRAPH '(LEFT)))
                           (FreeMenu (DINFO.ADD.FMENU GRAPH)
                                     (DINFO.UPDATE GRAPH))
                           NIL])

(DINFO.FIND
  [LAMBDA (GRAPH BUTTONS)                                    (* drc%: "25-Jan-86 18:23")
    (LET ((DINFOW (fetch (DINFOGRAPH WINDOW) of GRAPH)))
         (if (NOT (OBTAIN.MONITORLOCK (fetch (DINFOGRAPH MONITORLOCK) of GRAPH)
                         T))
             then (FLASHWINDOW DINFOW)
                  (PROMPTPRINT "DInfo is busy")
           else (RESETFORM (TTYDISPLAYSTREAM (GETPROMPTWINDOW DINFOW))
                       (TERPRI T)
                       (LET ([STRING (if (AND (FMEMB 'MIDDLE BUTTONS)
                                              (fetch (DINFOGRAPH FIND.STRING) of GRAPH))
                                       else (PROMPTFORWORD "Find: " (fetch (DINFOGRAPH FIND.STRING)
                                                                       of GRAPH)
                                                   NIL NIL NIL 'TTY (CONSTANT (CHARCODE (EOL ESCAPE 
                                                                                             LF]
                             (TEXTSTREAM (WINDOWPROP DINFOW 'TEXTSTREAM))
                             PAIR)
                            (replace (DINFOGRAPH FIND.STRING) of GRAPH with STRING)
                            (if STRING
                                then (PRINTOUT T " Searching...")
                                     (if (SETQ PAIR (TEDIT.FIND TEXTSTREAM STRING NIL NIL T))
                                         then (printout T "OK.")
                                              (TEDIT.NORMALIZECARET TEXTSTREAM
                                                     (TEDIT.SHOWSEL TEXTSTREAM T (TEDIT.SETSEL
                                                                                  TEXTSTREAM
                                                                                  (CAR PAIR)
                                                                                  (NCHARS STRING)
                                                                                  'RIGHT T)))
                                       else (printout T "not found.")
                                            (TEDIT.NORMALIZECARET TEXTSTREAM (TEDIT.SETSEL TEXTSTREAM 
                                                                                    0 0])

(DINFO.LOOKUP
  [LAMBDA (GRAPH BUTTONS)                                    (* drc%: "25-Jan-86 18:22")
    (LET
     ((DINFOW (fetch (DINFOGRAPH WINDOW) of GRAPH)))
     (if (OBTAIN.MONITORLOCK (fetch (DINFOGRAPH MONITORLOCK) of GRAPH)
                T)
         then
         [RESETFORM
          (TTYDISPLAYSTREAM (GETPROMPTWINDOW DINFOW))
          (LET ((LOOKUPFN (fetch (DINFOGRAPH LOOKUPFN) of GRAPH)))
               (if LOOKUPFN
                   then (CLEARW T)
                        (LET* [(OLD.STRING (fetch (DINFOGRAPH LOOKUP.STRING) of GRAPH))
                               (STRING (if (AND OLD.STRING (FMEMB 'MIDDLE BUTTONS))
                                           then OLD.STRING
                                         else (PROMPTFORWORD "Lookup: " OLD.STRING NIL NIL NIL
                                                     'TTY
                                                     (CONSTANT (CHARCODE (EOL ESCAPE LF]
                              (replace (DINFOGRAPH LOOKUP.STRING) of GRAPH with STRING)
                              (AND STRING (APPLY* LOOKUPFN STRING GRAPH)))
                 else (PRINTOUT T T "The " (fetch (DINFOGRAPH NAME) of GRAPH)
                             " graph has no LOOKUPFN."]
       else (FLASHWINDOW DINFOW)
            (PROMPTPRINT "DInfo is busy"])
)
(DEFINEQ

(DINFO.READ.KOTO.GRAPH
  [LAMBDA (FILE QUIETFLG)                                    (* drc%: " 4-Feb-86 11:27")
          
          (* Reads a file written by Koto DINFO.WRITE.GRAPH and returns a Lute 
          DINFOGRAPH. Thus, (DINFO.WRITE.GRAPH (DINFO.READ.KOTO.GRAPH <file1>) <file2>) 
          will convert the Koto format graph in <file1> to a Lute format graph in 
          <file2>.)

    (OR QUIETFLG (printout T T "Reading " (FILENAMEFIELD FILE 'NAME)
                        " graph..."))
    (LET* ((FULLFILENAME (INFILEP FILE))
           [DATA (CDR (READFILE (OR FULLFILENAME (ERROR "FILE NOT FOUND" FILE]
           (GRAPH (create DINFOGRAPH)))                      (* in Koto we just wrote out the 
                                                             DINFOGRAPH record)
          (for FIELD in DATA as N from 1 to 11 do            (* fields stored on file)
                                                  (SELECTQ N
                                                      ((1 4 5 6 10 11))
                                                      (2 (replace (DINFOGRAPH NODELST) of GRAPH
                                                            with FIELD))
                                                      (3 (replace (DINFOGRAPH TOPNODEID) of GRAPH
                                                            with FIELD))
                                                      (7 (replace (DINFOGRAPH TEXTPROPS) of GRAPH
                                                            with FIELD))
                                                      (8 (replace (DINFOGRAPH LOOKUPFN) of GRAPH
                                                            with FIELD))
                                                      (9 (replace (DINFOGRAPH MENUFN) of GRAPH
                                                            with FIELD))
                                                      (SHOULDNT)))
                                                             (* fields filled in at read time)
          (replace (DINFOGRAPH NAME) of GRAPH with (FILENAMEFIELD FULLFILENAME 'NAME))
          (replace (DINFOGRAPH DEFAULTHOST) of GRAPH with (FILENAMEFIELD FULLFILENAME 'HOST))
          (replace (DINFOGRAPH DEFAULTDEVICE) of GRAPH with (FILENAMEFIELD FULLFILENAME 'DEVICE))
          (replace (DINFOGRAPH DEFAULTDIR) of GRAPH with (FILENAMEFIELD FULLFILENAME 'DIRECTORY))
          (OR QUIETFLG (printout T "OK."))
          GRAPH])
)
(DEFINEQ

(DINFO.SETUP.WINDOW
  [LAMBDA (GRAPH WINDOW NO.FREEMENU?)                        (* jow "10-Jun-86 15:29")
    (replace (DINFOGRAPH WINDOW) of GRAPH with WINDOW)
    (WINDOWPROP WINDOW 'DINFOGRAPH GRAPH)
    (DETACHALLWINDOWS WINDOW)
    (if (NOT NO.FREEMENU?)
        then (DINFO.ADD.FMENU GRAPH))
    (DINFO.UPDATE.TEXT.DISPLAY GRAPH NIL NIL T)
    (WINDOWPROP WINDOW 'TITLE (CONCAT (fetch (DINFOGRAPH NAME) of GRAPH)
                                     " DInfo"))
    (WINDOWADDPROP WINDOW 'CLOSEFN 'DINFO.CLOSEFN)
    (WINDOWADDPROP WINDOW 'SHRINKFN 'DINFO.SHRINKFN)
    (WINDOWADDPROP WINDOW 'EXPANDFN 'DINFO.EXPANDFN])

(DINFO.CLOSEFN
  [LAMBDA (W)                                                (* drc%: "25-Jan-86 18:26")
    (LET [(GRAPH (WINDOWPROP W 'DINFOGRAPH]
         (if (type? DINFOGRAPH GRAPH)
             then (CLOSEW (fetch (DINFOGRAPH GRAPH.WINDOW) of GRAPH)) 
                                                             (* remove circularity...)
                  (WINDOWPROP W 'DINFOGRAPH NIL])

(DINFO.SHRINKFN
  [LAMBDA (W)                                                (* drc%: "25-Jan-86 18:26")
    (CLOSEW (fetch (DINFOGRAPH GRAPH.WINDOW) of (DINFOGRAPH W])

(DINFO.EXPANDFN
  [LAMBDA (W)                                                (* jow "15-Jul-86 17:00")
    (LET* ((GRAPH (DINFOGRAPH W))
           (FMENU (fetch (DINFOGRAPH FMENU.WINDOW) of GRAPH)))
          (if (AND FMENU (LISTGET (FM.GETSTATE FMENU)
                                'GRAPH))
              then (LET ((GRAPHW (fetch (DINFOGRAPH GRAPH.WINDOW) of GRAPH)))
                        (OPENW GRAPHW)
                        (TOTOPW W)
                        (WINDOWPROP GRAPHW 'DINFOGRAPH GRAPH])

(DINFO.ICONFN
  [LAMBDA (W)                                                (* drc%: "25-Jan-86 16:33")
    (OR (WINDOWPROP WINDOW 'ICON)
        (WINDOWPROP WINDOW 'ICON (TITLEDICONW TEDIT.TITLED.ICON.TEMPLATE (WINDOWPROP WINDOW
                                                                                'TITLE)
                                        TEDIT.ICON.FONT NIL T))
        (WINDOWPROP WINDOW 'ICON])
)
(DEFINEQ

(DINFO.ADD.FMENU
  [LAMBDA (GRAPH)                                            (* jow "20-May-86 15:41")
          
          (* * Add a DInfo FreeMenu to WINDOW. then update the FreeMenu's display.)

    (LET ((WINDOW (fetch (DINFOGRAPH WINDOW) of GRAPH))
          (FM.WINDOW (fetch (DINFOGRAPH FMENU.WINDOW) of GRAPH)))
         (if [AND (WINDOWP FM.WINDOW)
                  (FMEMB FM.WINDOW (WINDOWPROP WINDOW 'ATTACHEDWINDOWS]
             then (OPENW FM.WINDOW)
           else (REMOVEPROMPTWINDOW WINDOW)
                (SETQ FM.WINDOW (OR (WINDOWP FM.WINDOW)
                                    (DINFO.CREATE.FMENU GRAPH)))
                (replace (DINFOGRAPH FMENU.WINDOW) of GRAPH with FM.WINDOW)
                (ATTACHWINDOW FM.WINDOW WINDOW)
                (WINDOWPROP FM.WINDOW 'FM.PROMPTWINDOW (GETPROMPTWINDOW WINDOW))
                (WINDOWDELPROP FM.WINDOW 'PASSTOMAINCOMS 'CLOSEW)
                (WINDOWADDPROP FM.WINDOW 'CLOSEFN 'DINFO.FMW.CLOSEFN T)
                (DINFO.UPDATE.FMENU GRAPH])

(DINFO.CREATE.FMENU
  [LAMBDA (GRAPH)                                            (* jow "15-Jul-86 17:39")
          
          (* * Makes a DInfo FreeMenu for GRAPH)

    (LET* [(ADD.ITEMS (fetch (DINFOGRAPH FREEMENUITEMS) of GRAPH))
           (FONT (OR (FONTP (fetch (DINFOGRAPH MENUFONT) of GRAPH))
                     MENUFONT))
           (FM (FREEMENU `((PROPS FONT %, FONT)
                           ((LABEL Node%: TYPE DISPLAY FONT (HELVETICA 10))
                            (ID NODE LABEL "" TYPE DISPLAY))
                           ((LABEL Top! SELECTEDFN DINFO.FMENU.HANDLER FONT (HELVETICA 10 BOLD)
                                   MESSAGE "Visit the top node")
                            (ID TOP LABEL "" TYPE DISPLAY))
                           ((LABEL Parent! SELECTEDFN DINFO.FMENU.HANDLER FONT (HELVETICA 10 BOLD)
                                   MESSAGE "Visit the parent of the current node")
                            (ID PARENT LABEL "" TYPE DISPLAY))
                           ((LABEL Previous! SELECTEDFN DINFO.FMENU.HANDLER FONT (HELVETICA 10 BOLD)
                                   MESSAGE "Visit the node previous to the current node")
                            (ID PREVIOUS LABEL "" TYPE DISPLAY))
                           ((LABEL Next! SELECTEDFN DINFO.FMENU.HANDLER FONT (HELVETICA 10 BOLD)
                                   MESSAGE "Visit the node after the current node")
                            (ID NEXT LABEL "" TYPE DISPLAY))
                           ((LABEL Display%: TYPE DISPLAY FONT (HELVETICA 10))
                            (LABEL Graph ID GRAPH INITSTATE %, (MEMB 'GRAPH DINFOMODES)
                                   TYPE TOGGLE SELECTEDFN DINFO.TOGGLE.GRAPH FONT (HELVETICA 10 BOLD)
                                   MESSAGE "Toggle display of the graph")
                            (LABEL Menu ID MENU INITSTATE %, (MEMB 'MENU DINFOMODES)
                                   TYPE TOGGLE SELECTEDFN DINFO.TOGGLE.MENU FONT (HELVETICA 10 BOLD)
                                   MESSAGE "Toggle display of the subnode menu")
                            (LABEL Text ID TEXT INITSTATE %, (MEMB 'TEXT DINFOMODES)
                                   TYPE TOGGLE SELECTEDFN DINFO.TOGGLE.TEXT FONT (HELVETICA 10 BOLD)
                                   MESSAGE "Toggle display of the text of the current node")
                            (LABEL History ID HISTORY INITSTATE %, (MEMB 'HISTORY DINFOMODES)
                                   TYPE TOGGLE FONT (HELVETICA 10 BOLD)
                                   SELECTEDFN DINFO.TOGGLE.HISTORY MESSAGE 
                                   "Toggle the display of the History Menu"))
                           %,
                           (APPEND '((LABEL Find! SELECTEDFN DINFO.FMENU.HANDLER FONT
                                            (HELVETICA 10 BOLD)
                                            MESSAGE 
                                   "Perform a string search in the selected text of the current node"
                                            )
                                     (LABEL Lookup! SELECTEDFN DINFO.FMENU.HANDLER FONT
                                            (HELVETICA 10 BOLD)
                                            MESSAGE 
                            "Lookup a term in this graph.  LEFT for new term, MIDDLE to repeat last."
                                            )) ADD.ITEMS]
          (WINDOWPROP FM 'FM.DONTRESHAPE T)
          FM])

(DINFO.FMW.CLOSEFN
  [LAMBDA (W)                                                (* drc%: "25-Jan-86 18:19")
          
          (* * CLOSEFN for a DInfo FreeMenu window.)

    (LET* ((DINFOW (WINDOWPROP W 'MAINWINDOW))
           (GRAPH (DINFOGRAPH DINFOW)))
          (if GRAPH
              then (DETACHWINDOW W)
                   (replace (DINFOGRAPH FMENU.WINDOW) of GRAPH with NIL)
                   (DETACHWINDOW (fetch (DINFOGRAPH SUBNODE.MENU.WINDOW) of GRAPH))
                   (CLOSEW (fetch (DINFOGRAPH SUBNODE.MENU.WINDOW) of GRAPH))
                   (DETACHWINDOW (fetch (DINFOGRAPH HISTORY.MENU.WINDOW) of GRAPH))
                   (CLOSEW (fetch (DINFOGRAPH GRAPH.WINDOW) of GRAPH))
                   (REMOVEPROMPTWINDOW DINFOW])

(DINFO.FMENU.HANDLER
  [LAMBDA (ITEM WINDOW BUTTONS)                              (* drc%: "16-Jan-86 11:42")
          
          (* * Handle a command from the FreeMenu.)

    (LET [(GRAPH (WINDOWPROP (WINDOWPROP WINDOW 'MAINWINDOW)
                        'DINFOGRAPH))
          (TYPE (MKATOM (SUBSTRING (FM.ITEMPROP ITEM 'LABEL)
                               1 -2]
         (SELECTQ TYPE
             ((Top Parent Previous Next) 
                  (DINFO.SPECIAL.UPDATE TYPE GRAPH))
             (Find (DINFO.FIND GRAPH BUTTONS))
             (Lookup (DINFO.LOOKUP GRAPH BUTTONS))
             (SHOULDNT])

(DINFO.UPDATE.FMENU
  [LAMBDA (GRAPH NEW.NODE)                                   (* jow "20-May-86 15:13")
          
          (* * Update the display of GRAPH's FreeMenu.
          If NEW.NODE is not specified, use Top node of GRAPH, and change Top node title.)

    (LET* [(W (fetch (DINFOGRAPH FMENU.WINDOW) of GRAPH))
           (NODELST (fetch (DINFOGRAPH NODELST) of GRAPH))
           (NODE (OR NEW.NODE (FASSOC (fetch (DINFONODE ID) of (fetch (DINFOGRAPH CURRENTNODE)
                                                                  of GRAPH))
                                     NODELST)
                     (FASSOC (fetch (DINFOGRAPH TOPNODEID) of GRAPH)
                            NODELST]
          (OR NEW.NODE (FM.CHANGELABEL (FM.GETITEM 'TOP NIL W)
                              (fetch (DINFONODE LABEL) of (FASSOC (fetch (DINFOGRAPH TOPNODEID)
                                                                     of GRAPH)
                                                                 (fetch (DINFOGRAPH NODELST)
                                                                    of GRAPH)))
                              W))
          (FM.CHANGELABEL (FM.GETITEM 'NODE NIL W)
                 (fetch (DINFONODE LABEL) of NODE)
                 W)
          (FM.CHANGELABEL (FM.GETITEM 'PARENT NIL W)
                 (fetch (DINFONODE LABEL) of NODE (FASSOC (fetch (DINFONODE PARENT) of NODE)
                                                         NODELST))
                 W)
          (FM.CHANGELABEL (FM.GETITEM 'NEXT NIL W)
                 (fetch (DINFONODE LABEL) of NODE (FASSOC (fetch (DINFONODE NEXTNODE) of NODE)
                                                         NODELST))
                 W)
          (FM.CHANGELABEL (FM.GETITEM 'PREVIOUS NIL W)
                 (fetch (DINFONODE LABEL) of NODE (FASSOC (fetch (DINFONODE PREVIOUSNODE)
                                                             of NODE)
                                                         NODELST))
                 W])

(DINFO.TOGGLE.MENU
  [LAMBDA (ITEM WINDOW)                                      (* jow "10-Jun-86 14:15")
    (LET [(GRAPH (WINDOWPROP (WINDOWPROP WINDOW 'MAINWINDOW)
                        'DINFOGRAPH]
         (if (FM.ITEMPROP ITEM 'STATE)
             then (DINFO.UPDATE.MENU.DISPLAY GRAPH (fetch (DINFOGRAPH CURRENTNODE) of GRAPH))
           else (LET ((SUBNODE.MENU.WINDOW (fetch (DINFOGRAPH SUBNODE.MENU.WINDOW) of GRAPH)))
                     (DETACHWINDOW SUBNODE.MENU.WINDOW)
                     (CLOSEW SUBNODE.MENU.WINDOW])

(DINFO.TOGGLE.GRAPH
  [LAMBDA (ITEM WINDOW)                                      (* ; "Edited  1-Oct-87 09:56 by drc:")

    (LET [(GRAPH (WINDOWPROP (WINDOWPROP WINDOW 'MAINWINDOW)
                        'DINFOGRAPH]
         (if (FM.ITEMPROP ITEM 'STATE)
             then (DINFO.UPDATE.GRAPH.DISPLAY GRAPH (fetch CURRENTNODE of GRAPH)
                         T)
           else (CLOSEW (fetch (DINFOGRAPH GRAPH.WINDOW) of GRAPH)))
         ITEM])

(DINFO.TOGGLE.HISTORY
  [LAMBDA (ITEM WINDOW)                                      (* jow "10-Jun-86 14:22")
    (LET [(GRAPH (WINDOWPROP (WINDOWPROP WINDOW 'MAINWINDOW)
                        'DINFOGRAPH]
         (if (FM.ITEMPROP ITEM 'STATE)
             then (DINFO.UPDATE.HISTORY GRAPH NIL NIL T)
           else (LET ((HISTORY.MENU.WINDOW (fetch (DINFOGRAPH HISTORY.MENU.WINDOW) of GRAPH)))
                     (DETACHWINDOW HISTORY.MENU.WINDOW)
                     (CLOSEW HISTORY.MENU.WINDOW])

(DINFO.TOGGLE.TEXT
  [LAMBDA (ITEM WINDOW)                                      (* drc%: "25-Jan-86 18:26")
    (LET* ((DINFOW (WINDOWPROP WINDOW 'MAINWINDOW))
           (GRAPH (WINDOWPROP DINFOW 'DINFOGRAPH))
           (MONITORLOCK (fetch (DINFOGRAPH MONITORLOCK) of GRAPH)))
          (if (NOT (OBTAIN.MONITORLOCK MONITORLOCK T))
              then (FLASHWINDOW DINFOW)
                   (PROMPTPRINT "DInfo is busy")
            elseif (FM.ITEMPROP ITEM 'STATE)
              then (DINFO.UPDATE.TEXT.DISPLAY GRAPH (fetch (DINFOGRAPH CURRENTNODE) of GRAPH))
                   (RELEASE.MONITORLOCK MONITORLOCK)
            else (DINFO.UPDATE.TEXT.DISPLAY GRAPH (fetch (DINFOGRAPH CURRENTNODE) of GRAPH)
                        NIL T)
                 (RELEASE.MONITORLOCK MONITORLOCK])
)
(DEFINEQ

(DINFO.UPDATE.MENU.DISPLAY
  [LAMBDA (GRAPH NODE)                                       (* drc%: "25-Jan-86 18:20")
    (LET* [(DINFOW (fetch (DINFOGRAPH WINDOW) of GRAPH))
           (WINDOW (fetch (DINFOGRAPH SUBNODE.MENU.WINDOW) of GRAPH))
           [CHILDREN (DREVERSE (for ID in (fetch (DINFONODE CHILDREN) of NODE)
                                  bind (NODELST _ (fetch (DINFOGRAPH NODELST) of GRAPH))
                                  collect (FASSOC ID NODELST]
           (LENGTH (FLENGTH CHILDREN))
           (SCROLLABLE (GREATERP LENGTH \DINFO.MAX.MENU.LEN))
           (MENU (create MENU
                        MENUFONT _ (OR (FONTP (fetch (DINFOGRAPH MENUFONT) of GRAPH))
                                       MENUFONT)
                        ITEMWIDTH _ (WINDOWPROP DINFOW 'WIDTH)
                        CENTERFLG _ T
                        MENUCOLUMNS _ 1
                        MENUOUTLINESIZE _ 0
                        ITEMS _ (for CHILD in CHILDREN collect (LIST (fetch (DINFONODE LABEL)
                                                                        of CHILD)
                                                                     CHILD 
                                                                  "Will visit this node if selected."
                                                                     ))
                        WHENSELECTEDFN _ (FUNCTION DINFO.UPDATE.FROM.MENU]
          (AND WINDOW (PROGN (DETACHWINDOW WINDOW)
                             (CLOSEW WINDOW)))
          (if CHILDREN
              then (UPDATE/MENU/IMAGE MENU)
                   (SETQ WINDOW (CREATEW (create REGION
                                                LEFT _ 0
                                                BOTTOM _ 0
                                                WIDTH _ (WINDOWPROP DINFOW 'WIDTH)
                                                HEIGHT _
                                                (HEIGHTIFWINDOW
                                                 (if SCROLLABLE
                                                     then (TIMES \DINFO.MAX.MENU.LEN
                                                                 (fetch (MENU ITEMHEIGHT)
                                                                    of MENU))
                                                   else (fetch (MENU IMAGEHEIGHT) of MENU))
                                                 T))
                                       "Subnodes" NIL T))
                   (ADDMENU MENU WINDOW (create POSITION
                                               XCOORD _ 0
                                               YCOORD _ (if SCROLLABLE
                                                            then (TIMES (DIFFERENCE 
                                                                               \DINFO.MAX.MENU.LEN 
                                                                               LENGTH)
                                                                        (fetch (MENU ITEMHEIGHT)
                                                                           of MENU))
                                                          else 0))
                          T)
                   (ATTACHWINDOW WINDOW DINFOW 'BOTTOM)
                   (REDISPLAYW WINDOW)
                   (replace (DINFOGRAPH SUBNODE.MENU.WINDOW) of GRAPH with WINDOW)
                   (LET [(BITS (fetch (REGION BOTTOM) of (WINDOWPROP WINDOW 'REGION]
          
          (* Slide DINFOW up if our new menu is off the screen)

                        (AND (ILESSP BITS 0)
                             (RELMOVEW DINFOW (create POSITION
                                                     XCOORD _ 0
                                                     YCOORD _ (IDIFFERENCE 0 BITS])

(DINFO.UPDATE.FROM.MENU
  [LAMBDA (ITEM MENU BUTTONS)                                (* drc%: "12-Dec-85 14:49")
    (DINFO.UPDATE (WINDOWPROP (WINDOWPROP (WFROMMENU MENU)
                                     'MAINWINDOW)
                         'DINFOGRAPH)
           (CADR ITEM])

(DINFO.UPDATE.HISTORY
  [LAMBDA (GRAPH NODE SEL DISPLAY?)                          (* drc%: "25-Jan-86 18:21")
    (LET* ((DINFOW (fetch (DINFOGRAPH WINDOW) of GRAPH))
           (OLDWINDOW (fetch (DINFOGRAPH HISTORY.MENU.WINDOW) of GRAPH))
           (OLDITEMS (fetch (DINFOGRAPH HISTORY.ITEMS) of GRAPH))
           (NEWITEM (if SEL
                        then (LIST (if (LISTP SEL)
                                       then (CAR SEL)
                                     else SEL)
                                   (LIST (fetch (DINFONODE ID) of NODE)
                                         SEL)
                                   "Will re-lookup this term")
                      elseif NODE
                        then (LIST (fetch (DINFONODE LABEL) of NODE)
                                   (LIST (fetch (DINFONODE ID) of NODE)
                                         SEL)
                                   "Will re-visit this node")))
           (ITEMS (if [AND NEWITEM (NOT (EQUAL NEWITEM (CAR OLDITEMS]
                      then (CONS NEWITEM
                                 (for ITEM in OLDITEMS as I from 2 to DINFO.HISTORY.LENGTH
                                    collect ITEM))
                    else OLDITEMS)))
          (replace (DINFOGRAPH HISTORY.ITEMS) of GRAPH with ITEMS)
          (AND OLDWINDOW (PROGN (DETACHWINDOW OLDWINDOW)
                                (CLOSEW OLDWINDOW)))
          (AND DISPLAY? ITEMS
               (LET [(HISTORYW (ATTACHMENU (create MENU
                                                  MENUFONT _ (OR (FONTP (fetch (DINFOGRAPH MENUFONT)
                                                                           of GRAPH))
                                                                 MENUFONT)
                                                  TITLE _ "History"
                                                  CENTERFLG _ T
                                                  MENUCOLUMNS _ 1
                                                  ITEMS _ ITEMS
                                                  WHENSELECTEDFN _ (FUNCTION DINFO.HISTORIC.UPDATE))
                                      DINFOW
                                      'LEFT
                                      'TOP]
                    (replace (DINFOGRAPH HISTORY.MENU.WINDOW) of GRAPH with HISTORYW])

(DINFO.HISTORIC.UPDATE
  [LAMBDA (ITEM MENU BUTTONS)                                (* drc%: "25-Jan-86 18:24")
    (LET* [(ID (CAADR ITEM))
           (SEL (CADADR ITEM))
           (WINDOW (WINDOWPROP (WFROMMENU MENU)
                          'MAINWINDOW))
           (GRAPH (WINDOWPROP WINDOW 'DINFOGRAPH))
           (NODE (FASSOC ID (fetch (DINFOGRAPH NODELST) of GRAPH]
          (if (NOT (OBTAIN.MONITORLOCK (fetch (DINFOGRAPH MONITORLOCK) of GRAPH)
                          T))
              then (FLASHWINDOW WINDOW)
                   (PROMPTPRINT "DInfo is busy")
            elseif (NULL NODE)
              then (PRINTOUT (GETPROMPTWINDOW WINDOW)
                          T "This node no longer exists")
            else (DINFO.UPDATE GRAPH NODE SEL])
)
(DEFINEQ

(DINFO.UPDATE.GRAPH.DISPLAY
  [LAMBDA (DINFO.GRAPH NODE FORCE?)                          (* drc%: "27-Jan-86 16:19")
    (LET [(DINFOW (fetch (DINFOGRAPH WINDOW) of DINFO.GRAPH))
          (LOCATION (CONS (fetch (DINFONODE PARENT) of NODE)
                          (fetch (DINFONODE CHILDREN) of NODE]
         (if (AND (NOT FORCE?)
                  (EQUAL LOCATION (fetch (DINFOGRAPH LAST.GRAPH.LOCATION) of DINFO.GRAPH)))
             then 
          
          (* don't need to relayout grapher display --
          just change which node is inverted.)

                  (DINFO.INVERT.NODE (fetch (DINFOGRAPH GRAPH.WINDOW) of DINFO.GRAPH)
                         NODE DINFO.GRAPH)
           else (DINFO.SHOWGRAPH (DINFO.LAYOUTGRAPH DINFO.GRAPH NODE)
                       DINFO.GRAPH))
         (replace (DINFOGRAPH LAST.GRAPH.LOCATION) of DINFO.GRAPH with LOCATION)
         (WINDOWPROP (fetch (DINFOGRAPH GRAPH.WINDOW) of DINFO.GRAPH)
                'TITLE
                (CONCAT (fetch (DINFOGRAPH NAME) of DINFO.GRAPH)
                       " - "
                       (fetch (DINFONODE LABEL) of (fetch (DINFOGRAPH CURRENTNODE) of DINFO.GRAPH])

(DINFO.UPDATE.FROM.GRAPH
  [LAMBDA (GRAPHER.NODE GRAPH.WINDOW)                        (* drc%: "12-Dec-85 18:34")
    (AND GRAPHER.NODE (ADD.PROCESS `(DINFO.UPDATE (QUOTE %, (WINDOWPROP GRAPH.WINDOW 'DINFOGRAPH))
                                           (QUOTE %, (fetch (GRAPHNODE NODEID)
                                                            of GRAPHER.NODE))) 'NAME 
                             "DInfo From Graph"])

(DINFO.GET.GRAPH.WINDOW
  [LAMBDA (GRAPH REGION)                                     (* drc%: "25-Jan-86 18:05")
    (LET ((W (fetch (DINFOGRAPH GRAPH.WINDOW) of GRAPH)))
         (COND
            ((WINDOWP W))
            (T (SETQ W (DINFO.CREATE.GRAPH.WINDOW GRAPH REGION))
               [WINDOWPROP W 'CLOSEFN (FUNCTION (LAMBDA (W)
                                                  (WINDOWPROP W 'DINFOGRAPH NIL]
               (replace (DINFOGRAPH GRAPH.WINDOW) of GRAPH with W)))
         (WINDOWPROP W 'DINFOGRAPH GRAPH)
         W])

(DINFO.CREATE.GRAPH.WINDOW
  [LAMBDA (GRAPH REGION)                                     (* drc%: "25-Jan-86 17:49")
    (LET* ((DINFOW (fetch (DINFOGRAPH WINDOW) of GRAPH))
           (DINFOREGION (WINDOWPROP DINFOW 'REGION))
           (LEFT (DIFFERENCE (DIFFERENCE (fetch (REGION LEFT) of DINFOREGION)
                                    (fetch (REGION WIDTH) of REGION))
                        10))
           (BOTTOM (DIFFERENCE (DIFFERENCE (fetch (REGION BOTTOM) of DINFOREGION)
                                      (fetch (REGION HEIGHT) of REGION))
                          50)))
          (CREATEW (CREATEREGION (if (GEQ LEFT 0)
                                     then LEFT
                                   else (RAND 0 10))
                          (if (GEQ BOTTOM 0)
                              then BOTTOM
                            else (RAND 0 10))
                          (fetch (REGION WIDTH) of REGION)
                          (fetch (REGION HEIGHT) of REGION))
                 NIL NIL T])

(DINFO.SHOWGRAPH
  [LAMBDA (GRAPHER.GRAPH DINFO.GRAPH)                        (* drc%: "27-Jan-86 16:15")
    (LET* [(GRAPH.REGION (GRAPHREGION GRAPHER.GRAPH))
           (GRAPH.WINDOW (DINFO.GET.GRAPH.WINDOW DINFO.GRAPH GRAPH.REGION))
           (WINDOW.REGION (WINDOWPROP GRAPH.WINDOW 'REGION]
          [SHAPEW GRAPH.WINDOW (LET [(LEFT (fetch (REGION LEFT) of WINDOW.REGION))
                                     (BOTTOM (fetch (REGION BOTTOM) of WINDOW.REGION))
                                     (HEIGHT (HEIGHTIFWINDOW (fetch (REGION HEIGHT) of GRAPH.REGION)
                                                    T))
                                     (WIDTH (WIDTHIFWINDOW (fetch (REGION WIDTH) of GRAPH.REGION]
                                    (create REGION
                                           LEFT _ LEFT
                                           BOTTOM _ BOTTOM
                                           HEIGHT _ (if (GEQ (IPLUS BOTTOM HEIGHT)
                                                             SCREENHEIGHT)
                                                        then (IDIFFERENCE SCREENHEIGHT BOTTOM)
                                                      else HEIGHT)
                                           WIDTH _ (if (GEQ (IPLUS LEFT WIDTH)
                                                            SCREENWIDTH)
                                                       then (IDIFFERENCE SCREENWIDTH LEFT)
                                                     else WIDTH]
          (SHOWGRAPH GRAPHER.GRAPH GRAPH.WINDOW (FUNCTION DINFO.UPDATE.FROM.GRAPH)
                 (FUNCTION DINFO.UPDATE.FROM.GRAPH])

(DINFO.INVERT.NODE
  [LAMBDA (WINDOW DINFO.NODE DINFO.GRAPH)                    (* drc%: "25-Jan-86 18:24")
    (LET* ((NODE (for NODE in (fetch (GRAPH GRAPHNODES) of (WINDOWPROP WINDOW 'GRAPH))
                    thereis (EQ (fetch (GRAPHNODE NODEID) of NODE)
                                DINFO.NODE)))
           (LAST.NODE (fetch (DINFOGRAPH LAST.INVERTED.NODE) of DINFO.GRAPH)))
          (replace (DINFOGRAPH LAST.INVERTED.NODE) of DINFO.GRAPH with NODE)
          (if (NEQ NODE LAST.NODE)
              then (replace (GRAPHNODE NODELABELSHADE) of NODE with BLACKSHADE) 
                                                             (* (PRINTDISPLAYNODE NODE
                                                             (create POSITION XCOORD _ 0 YCOORD _ 0) 
                                                             WINDOW))
                   (replace (GRAPHNODE NODELABELSHADE) of LAST.NODE with WHITESHADE) 
                                                             (* (PRINTDISPLAYNODE LAST.NODE
                                                             (create POSITION XCOORD _ 0 YCOORD _ 0) 
                                                             WINDOW))
                   (REDISPLAYW WINDOW)
            else (OPENW WINDOW])

(DINFO.LAYOUTGRAPH
  [LAMBDA (DINFO.GRAPH NODE)                                 (* drc%: "25-Jan-86 18:20")
    (LET* [(WINDOW (fetch (DINFOGRAPH WINDOW) of DINFO.GRAPH))
           (FONT (OR (FONTP (fetch (DINFOGRAPH MENUFONT) of DINFO.GRAPH))
                     MENUFONT))
           (NODELST (fetch (DINFOGRAPH NODELST) of DINFO.GRAPH))
           (CHILDREN (for ID in (fetch (DINFONODE CHILDREN) of NODE) collect (FASSOC ID NODELST)))
           [CHILD.GRAPHER.NODES (for CHILD in CHILDREN
                                   collect (create GRAPHNODE
                                                  NODEID _ CHILD
                                                  NODELABEL _ (fetch (DINFONODE LABEL) of CHILD]
           (GRAPHER.NODE (create GRAPHNODE
                                NODELABELSHADE _ BLACKSHADE
                                NODEID _ NODE
                                TONODES _ CHILDREN
                                NODELABEL _ (fetch (DINFONODE LABEL) of NODE]
          (replace (DINFOGRAPH LAST.INVERTED.NODE) of DINFO.GRAPH with GRAPHER.NODE)
                                                             (* so DINFO.INVERT.NODE will work 
                                                             right)
          (if (fetch (DINFONODE PARENT) of NODE)
              then (LET* ((PARENT (FASSOC (fetch (DINFONODE PARENT) of NODE)
                                         NODELST))
                          (SIBLINGS (for ID in (fetch (DINFONODE CHILDREN) of PARENT)
                                       collect (FASSOC ID NODELST)))
                          [SIBLING.GRAPHER.NODES (for SIBLING in SIBLINGS
                                                    collect (if (EQ (fetch (DINFONODE ID)
                                                                       of SIBLING)
                                                                    (fetch (DINFONODE ID)
                                                                       of NODE))
                                                                then GRAPHER.NODE
                                                              else (create GRAPHNODE
                                                                          NODEID _ SIBLING
                                                                          NODELABEL _
                                                                          (fetch (DINFONODE LABEL)
                                                                             of SIBLING]
                          (PARENT.GRAPHER.NODE (create GRAPHNODE
                                                      NODEID _ PARENT
                                                      NODELABEL _ (fetch (DINFONODE LABEL)
                                                                     of PARENT)
                                                      TONODES _ SIBLINGS)))
                         (LAYOUTGRAPH (CONS PARENT.GRAPHER.NODE (NCONC SIBLING.GRAPHER.NODES 
                                                                       CHILD.GRAPHER.NODES))
                                (LIST PARENT)
                                NIL FONT))
            else (LAYOUTGRAPH (CONS GRAPHER.NODE CHILD.GRAPHER.NODES)
                        (LIST NODE)
                        NIL FONT])
)
(DEFINEQ

(DINFO.UPDATE.TEXT.DISPLAY
  [LAMBDA (GRAPH NODE SEL OFF?)                              (* drc%: "25-Jan-86 18:18")
    (LET ((WINDOW (fetch (DINFOGRAPH WINDOW) of GRAPH))
          (FILENAME (DINFO.GET.FILENAME GRAPH NODE))
          (FROM (fetch (DINFONODE FROMBYTE) of NODE))
          (TO (fetch (DINFONODE TOBYTE) of NODE))
          (PROPS (APPEND (LIST 'READONLY T 'NOTITLE T 'TITLEMENUFN 'DINFO.TITLEMENUFN)
                        (fetch (DINFOGRAPH TEXTPROPS) of GRAPH)))
          (OLD.TEXTSTREAM (WINDOWPROP (fetch (DINFOGRAPH WINDOW) of GRAPH)
                                 'TEXTSTREAM))
          TEXTSTREAM FULLFILENAME)                           (* Default directory and host.)
         (if (OR OFF? (NULL FILENAME))
             then (OPENTEXTSTREAM (if OFF?
                                      then ""
                                    else "This node has no text")
                         WINDOW NIL NIL PROPS)
                  (replace (DINFOGRAPH LAST.TEXT) of GRAPH with NIL)
           elseif (SETQ FULLFILENAME (MKATOM (INFILEP FILENAME)))
             then (SETQ TEXTSTREAM (DINFO.OPENTEXTSTREAM FULLFILENAME WINDOW FROM TO PROPS))
                  (DINFO.SHOWSEL TEXTSTREAM SEL)
           else (OPENTEXTSTREAM (CONCAT "Sorry, can't find the text for this node."
                                       (MKSTRING (CHARACTER (CHARCODE CR)))
                                       "Missing file is: " FILENAME)
                       WINDOW NIL NIL PROPS)
                (replace (DINFOGRAPH LAST.TEXT) of GRAPH with NIL))
         (CLOSEF? OLD.TEXTSTREAM)
         (WINDOWPROP WINDOW 'ICONFN 'DINFO.ICONFN)
         (WINDOWPROP WINDOW 'TEDIT.TITLEMENUFN 'DINFO.TITLEMENUFN])

(DINFO.TITLEMENUFN
  [LAMBDA (DINFOW)                                           (* drc%: "25-Jan-86 18:19")
          
          (* * This is the TEdit TITLEMENUFN for a DInfo Window.
          Uses the MENUFN of graph, defaulting to DINFO.DEFAULT.MENU.)

    (LET [(GRAPH (WINDOWPROP DINFOW 'DINFOGRAPH]
         (if (OBTAIN.MONITORLOCK (fetch (DINFOGRAPH MONITORLOCK) of GRAPH)
                    T)
             then [LET ((MENUFN (fetch (DINFOGRAPH MENUFN) of GRAPH)))
                       (if (FGETD MENUFN)
                           then (OR (fetch (DINFOGRAPH FMENU.WINDOW) of GRAPH)
                                    (DINFO.ADD.FMENU GRAPH))
                                (RESETFORM (TTYDISPLAYSTREAM (GETPROMPTWINDOW DINFOW))
                                       (APPLY* MENUFN GRAPH))
                         else (RESETFORM (TTYDISPLAYSTREAM (GETPROMPTWINDOW DINFOW))
                                     (DINFO.DEFAULT.MENU GRAPH]
           else (FLASHWINDOW DINFOW)
                (PROMPTPRINT "DInfo is busy"])

(DINFO.OPENTEXTSTREAM
  [LAMBDA (FILE WINDOW FROM TO PROPS)                        (* drc%: "25-Jan-86 18:24")
    (RESETFORM (TTYDISPLAYSTREAM (GETPROMPTWINDOW WINDOW))
           (LET ((TEXTSTREAM (WINDOWPROP WINDOW 'TEXTSTREAM))
                 (THIS.TEXT (LIST FILE FROM TO)))
                (if (AND (EQUAL THIS.TEXT (fetch (DINFOGRAPH LAST.TEXT) of (DINFOGRAPH WINDOW)))
                         TEXTSTREAM)
                    then                                     (* Same text, and its still there, so 
                                                             do nothing.)
                         TEXTSTREAM
                  else (AND TEXTSTREAM (TEDIT.KILL TEXTSTREAM))
                       (CLEARW T)
                       (CLEARW WINDOW)
                       [RESETSAVE NIL `(AND RESETSTATE (WINDOWPROP %, WINDOW 'LAST.TEXT NIL]
                       (PRINTOUT T "Fetching text from " FILE "...")
                       (PROG1 (OPENTEXTSTREAM FILE WINDOW FROM TO PROPS)
                              (PRINTOUT T "OK.")
                              (replace (DINFOGRAPH LAST.TEXT) of (DINFOGRAPH WINDOW) with THIS.TEXT])

(DINFO.SHOWSEL
  [LAMBDA (TEXTSTREAM SEL)                                   (* drc%: "16-Jan-86 21:30")
    (if (LISTP SEL)
        then (TEDIT.NORMALIZECARET TEXTSTREAM (TEDIT.SETSEL TEXTSTREAM (CADR SEL)
                                                     0))
      elseif (STRINGP SEL)
        then [LET ((CHAR# (TEDIT.FIND TEXTSTREAM SEL)))
                  (if CHAR#
                      then (TEDIT.NORMALIZECARET TEXTSTREAM (TEDIT.SETSEL TEXTSTREAM CHAR#
                                                                   (NCHARS SEL)
                                                                   NIL T]
      else (TEDIT.NORMALIZECARET TEXTSTREAM (TEDIT.SETSEL TEXTSTREAM 0 0])

(DINFO.GET.FILENAME
  [LAMBDA (GRAPH NODE)                                       (* drc%: "10-Jan-86 14:47")
          
          (* * returns the filename of the documentation for NODE in GRAPH.
          Defaults HOST and DIRECTORY to that of graph)

    (LET ((FILE (fetch (DINFONODE FILE) of NODE)))
         (AND FILE (PACKFILENAME 'HOST (OR (FILENAMEFIELD FILE 'HOST)
                                           (fetch (DINFOGRAPH DEFAULTHOST) of GRAPH))
                          'DEVICE
                          (OR (FILENAMEFIELD FILE 'DEVICE)
                              (fetch (DINFOGRAPH DEFAULTDEVICE) of GRAPH))
                          'DIRECTORY
                          (OR (FILENAMEFIELD FILE 'DIRECTORY)
                              (fetch (DINFOGRAPH DEFAULTDIR) of GRAPH))
                          'BODY FILE])
)

(ADDTOVAR BackgroundMenuCommands (DInfo (DINFO.SELECT.GRAPH)
                                        "Open a DInfo window for browsing documentation."))

(RPAQQ BackgroundMenu NIL)

(RPAQ? DINFO.GRAPHS )

(RPAQ? DINFOMODES '(TEXT GRAPH))

(RPAQ? DINFO.HISTORY.LENGTH 20)

(RPAQ? \DINFO.MAX.MENU.LEN 10)
(DECLARE%: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS DINFO.GRAPH.FILES DINFOMODES DINFO.HISTORY.LENGTH \DINFO.MAX.MENU.LEN)
)

(PUTPROPS DINFO FILETYPE :COMPILE-FILE)
(PUTPROPS DINFO COPYRIGHT ("Xerox Corporation" 1985 1986 1987))
(DECLARE%: DONTCOPY
  (FILEMAP (NIL (6293 23119 (DINFO 6303 . 7917) (DINFO.UPDATE 7919 . 10783) (DINFOGRAPH 10785 . 11203) (
DINFO.SPECIAL.UPDATE 11205 . 12903) (DINFO.READ.GRAPH 12905 . 14760) (DINFO.WRITE.GRAPH 14762 . 15852)
 (DINFO.SELECT.GRAPH 15854 . 16761) (DINFO.DEFAULT.MENU 16763 . 19287) (DINFO.FIND 19289 . 21673) (
DINFO.LOOKUP 21675 . 23117)) (23120 25814 (DINFO.READ.KOTO.GRAPH 23130 . 25812)) (25815 28129 (
DINFO.SETUP.WINDOW 25825 . 26506) (DINFO.CLOSEFN 26508 . 26941) (DINFO.SHRINKFN 26943 . 27139) (
DINFO.EXPANDFN 27141 . 27698) (DINFO.ICONFN 27700 . 28127)) (28130 38978 (DINFO.ADD.FMENU 28140 . 
29235) (DINFO.CREATE.FMENU 29237 . 32774) (DINFO.FMW.CLOSEFN 32776 . 33621) (DINFO.FMENU.HANDLER 33623
 . 34262) (DINFO.UPDATE.FMENU 34264 . 36469) (DINFO.TOGGLE.MENU 36471 . 37061) (DINFO.TOGGLE.GRAPH 
37063 . 37562) (DINFO.TOGGLE.HISTORY 37564 . 38108) (DINFO.TOGGLE.TEXT 38110 . 38976)) (38979 46677 (
DINFO.UPDATE.MENU.DISPLAY 38989 . 43009) (DINFO.UPDATE.FROM.MENU 43011 . 43310) (DINFO.UPDATE.HISTORY 
43312 . 45846) (DINFO.HISTORIC.UPDATE 45848 . 46675)) (46678 56844 (DINFO.UPDATE.GRAPH.DISPLAY 46688
 . 48006) (DINFO.UPDATE.FROM.GRAPH 48008 . 48451) (DINFO.GET.GRAPH.WINDOW 48453 . 49038) (
DINFO.CREATE.GRAPH.WINDOW 49040 . 50157) (DINFO.SHOWGRAPH 50159 . 51884) (DINFO.INVERT.NODE 51886 . 
53274) (DINFO.LAYOUTGRAPH 53276 . 56842)) (56845 62701 (DINFO.UPDATE.TEXT.DISPLAY 56855 . 58716) (
DINFO.TITLEMENUFN 58718 . 59843) (DINFO.OPENTEXTSTREAM 59845 . 61061) (DINFO.SHOWSEL 61063 . 61796) (
DINFO.GET.FILENAME 61798 . 62699)))))
STOP
\ No newline at end of file
+(DEFINE-FILE-INFO PACKAGE "INTERLISP" READTABLE "INTERLISP" BASE 10)
(FILECREATED "27-Nov-2020 09:14:02" {DSK}<home>larry>ilisp>medley>lispusers>DINFO.;3 63476  

      changes to%:  (VARS DINFOCOMS)
                    (TEMPLATES DINFOGRAPHPROP)

      previous date%: " 1-Oct-87 10:11:04" {DSK}<home>larry>ilisp>medley>lispusers>DINFO.;1)


(* ; "
Copyright (c) 1985, 1986, 1987, 2020 by Xerox Corporation.  All rights reserved.
")

(PRETTYCOMPRINT DINFOCOMS)

(RPAQQ DINFOCOMS
       ((FILES TEDIT GRAPHER)
        (DECLARE%: EVAL@COMPILE (RECORDS DINFOGRAPH DINFONODE)
               (FUNCTIONS DINFOGRAPHPROP))
        (FNS                                                 (* ; "Primary functions")
             DINFO DINFO.UPDATE DINFOGRAPH DINFO.SPECIAL.UPDATE DINFO.READ.GRAPH DINFO.WRITE.GRAPH 
             DINFO.SELECT.GRAPH DINFO.DEFAULT.MENU DINFO.FIND DINFO.LOOKUP)
        (FNS                                                 (* ; "Koto compatability")
             DINFO.READ.KOTO.GRAPH)
        (FNS                                                 (* ; "Window functions")
             DINFO.SETUP.WINDOW DINFO.CLOSEFN DINFO.SHRINKFN DINFO.EXPANDFN DINFO.ICONFN)
        (FNS                                                 (* ; "FreeMenu functions")
             DINFO.ADD.FMENU DINFO.CREATE.FMENU DINFO.FMW.CLOSEFN DINFO.FMENU.HANDLER 
             DINFO.UPDATE.FMENU DINFO.TOGGLE.MENU DINFO.TOGGLE.GRAPH DINFO.TOGGLE.HISTORY 
             DINFO.TOGGLE.TEXT)
        (FNS                                                 (* ; "Other menu functions")
             DINFO.UPDATE.MENU.DISPLAY DINFO.UPDATE.FROM.MENU DINFO.UPDATE.HISTORY 
             DINFO.HISTORIC.UPDATE)
        (FNS                                                 (* ; "Interface to GRAPHER")
             DINFO.UPDATE.GRAPH.DISPLAY DINFO.UPDATE.FROM.GRAPH DINFO.GET.GRAPH.WINDOW 
             DINFO.CREATE.GRAPH.WINDOW DINFO.SHOWGRAPH DINFO.INVERT.NODE DINFO.LAYOUTGRAPH)
        (FNS                                                 (* ; "Interface to TEdit")
             DINFO.UPDATE.TEXT.DISPLAY DINFO.TITLEMENUFN DINFO.OPENTEXTSTREAM DINFO.SHOWSEL 
             DINFO.GET.FILENAME)
        (ADDVARS (BackgroundMenuCommands (DInfo (DINFO.SELECT.GRAPH)
                                                "Open a DInfo window for browsing documentation.")))
        (VARS (BackgroundMenu))
        (INITVARS (DINFO.GRAPHS)
               (DINFOMODES '(TEXT GRAPH))
               (DINFO.HISTORY.LENGTH 20)
               (\DINFO.MAX.MENU.LEN 10))
        (GLOBALVARS DINFO.GRAPH.FILES DINFOMODES DINFO.HISTORY.LENGTH \DINFO.MAX.MENU.LEN)
        (PROP (FILETYPE)
              DINFO)
        (TEMPLATES DINFOGRAPHPROP)))

(FILESLOAD TEDIT GRAPHER)
(DECLARE%: EVAL@COMPILE 
(DECLARE%: EVAL@COMPILE

(DATATYPE DINFOGRAPH 
          (NAME NODELST TOPNODEID CURRENTNODE USERDATA TEXTPROPS FREEMENUITEMS LOOKUPFN MENUFN 
                DEFAULTHOST DEFAULTDEVICE DEFAULTDIR MONITORLOCK DINFO.MENU WINDOW MENUFONT 
                FMENU.WINDOW GRAPH.WINDOW HISTORY.MENU.WINDOW SUBNODE.MENU.WINDOW LAST.TEXT 
                LAST.INVERTED.NODE LAST.GRAPH.LOCATION HISTORY.ITEMS FIND.STRING LOOKUP.STRING)
          (SYSTEM))

(RECORD DINFONODE (ID LABEL FILE FROMBYTE TOBYTE PARENT CHILDREN NEXTNODE PREVIOUSNODE USERDATA)
                      (SYSTEM))
)

(/DECLAREDATATYPE 'DINFOGRAPH
       '(POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER 
               POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER 
               POINTER POINTER POINTER POINTER POINTER)
       '((DINFOGRAPH 0 POINTER)
         (DINFOGRAPH 2 POINTER)
         (DINFOGRAPH 4 POINTER)
         (DINFOGRAPH 6 POINTER)
         (DINFOGRAPH 8 POINTER)
         (DINFOGRAPH 10 POINTER)
         (DINFOGRAPH 12 POINTER)
         (DINFOGRAPH 14 POINTER)
         (DINFOGRAPH 16 POINTER)
         (DINFOGRAPH 18 POINTER)
         (DINFOGRAPH 20 POINTER)
         (DINFOGRAPH 22 POINTER)
         (DINFOGRAPH 24 POINTER)
         (DINFOGRAPH 26 POINTER)
         (DINFOGRAPH 28 POINTER)
         (DINFOGRAPH 30 POINTER)
         (DINFOGRAPH 32 POINTER)
         (DINFOGRAPH 34 POINTER)
         (DINFOGRAPH 36 POINTER)
         (DINFOGRAPH 38 POINTER)
         (DINFOGRAPH 40 POINTER)
         (DINFOGRAPH 42 POINTER)
         (DINFOGRAPH 44 POINTER)
         (DINFOGRAPH 46 POINTER)
         (DINFOGRAPH 48 POINTER)
         (DINFOGRAPH 50 POINTER))
       '52)


(DEFMACRO DINFOGRAPHPROP (GRAPH PROP &OPTIONAL (NEW-VALUE NIL NEW-VALUE-SUPPLIED))
   [LET [(REAL-FIELD (AND (LISTP PROP)
                          (EQ (CAR PROP)
                              'QUOTE)
                          (FMEMB (CADR PROP)
                                 (RECORDFIELDNAMES 'DINFOGRAPH T))
                          (CADR PROP]
        (IF NEW-VALUE-SUPPLIED
            THEN [IF REAL-FIELD
                         THEN `(REPLACE (DINFOGRAPH ,REAL-FIELD) OF ,GRAPH
                                      WITH ,NEW-VALUE)
                       ELSE `(LET* ((SI::$GRAPH$ ,GRAPH)
                                        (SI::$USERDATA$ (FETCH (DINFOGRAPH USERDATA)
                                                           OF SI::$GRAPH$))
                                        (SI::$PROP$ ,PROP)
                                        (SI::$NEW-VALUE$ ,NEW-VALUE))
                                       (IF (LISTP SI::$USERDATA$)
                                           THEN (LISTPUT SI::$USERDATA$ SI::$PROP$ 
                                                           SI::$NEW-VALUE$)
                                         ELSE (REPLACE (DINFOGRAPH USERDATA) OF
                                                                                         SI::$GRAPH$
                                                     WITH (LIST SI::$PROP$ SI::$NEW-VALUE$))
                                               SI::$NEW-VALUE$]
          ELSE (IF REAL-FIELD
                       THEN `(FETCH (DINFOGRAPH ,REAL-FIELD) OF ,GRAPH)
                     ELSE `(LISTGET (FETCH (DINFOGRAPH USERDATA) OF ,GRAPH)
                                      ,PROP])
)
(DEFINEQ

(DINFO
  [LAMBDA (GRAPH.OR.FILE WINDOW.OR.REGION SETUP.ONLY? NO.FREEMENU?)
                                                             (* drc%: "25-Jan-86 18:23")
                                                             (* Starts a DInfo browser.)
    (RESETLST (LET ((W (OR (WINDOWP WINDOW.OR.REGION)
                           (AND (REGIONP WINDOW.OR.REGION)
                                (CREATEW WINDOW.OR.REGION "DInfo" NIL T))
                           (AND (type? DINFOGRAPH GRAPH.OR.FILE)
                                (WINDOWP (fetch (DINFOGRAPH WINDOW) of GRAPH.OR.FILE)))
                           (CREATEW NIL "DInfo")))
                    GRAPH MONITORLOCK)
                   (OPENW W)
                   [SETQ GRAPH (if (type? DINFOGRAPH GRAPH.OR.FILE)
                                   then GRAPH.OR.FILE
                                 else (RESETFORM (TTYDISPLAYSTREAM (GETPROMPTWINDOW W))
                                             (DINFO.READ.GRAPH GRAPH.OR.FILE]
                   [SETQ MONITORLOCK (OR (fetch (DINFOGRAPH MONITORLOCK) of GRAPH)
                                         (replace (DINFOGRAPH MONITORLOCK) of GRAPH
                                            with (CREATE.MONITORLOCK "DInfo"]
                   (RESETSAVE NIL (LIST 'RELEASE.MONITORLOCK MONITORLOCK))
                   (OBTAIN.MONITORLOCK MONITORLOCK)
                   (DINFO.SETUP.WINDOW GRAPH W NO.FREEMENU?)
                   (OR SETUP.ONLY? (DINFO.UPDATE GRAPH NIL NIL T))
                   GRAPH])

(DINFO.UPDATE
  [LAMBDA (GRAPH NEW.NODE SEL FORCE?)                        (* jow "20-May-86 15:14")
          
          (* * Called to visit a NEW.NODE in GRAPH, or to just make sure that the display 
          of GRAPH is current.)

    (LET ([NODE (OR NEW.NODE (fetch (DINFOGRAPH CURRENTNODE) of GRAPH)
                    (FASSOC (fetch (DINFOGRAPH TOPNODEID) of GRAPH)
                           (fetch (DINFOGRAPH NODELST) of GRAPH]
          (PREVIOUS.NODE (fetch (DINFOGRAPH CURRENTNODE) of GRAPH))
          (WINDOW (fetch (DINFOGRAPH WINDOW) of GRAPH)))
         (OPENW WINDOW)
         (WINDOWPROP WINDOW 'DINFOGRAPH GRAPH)
         (OR (FMEMB NODE (fetch (DINFOGRAPH NODELST) of GRAPH))
             (ERROR NODE "NOT IN NODELST"))
         (LET ((FMENU.WINDOW (fetch (DINFOGRAPH FMENU.WINDOW) of GRAPH))
               (MONITORLOCK (fetch (DINFOGRAPH MONITORLOCK) of GRAPH)))
              [RESETLST (RESETSAVE NIL (LIST 'RELEASE.MONITORLOCK MONITORLOCK))
                     (if (NOT (OBTAIN.MONITORLOCK MONITORLOCK T))
                         then                                (* somebody else is messing with this 
                                                             graph.)
                              (FLASHWINDOW WINDOW)
                              (PROMPTPRINT "DInfo is busy")
                       elseif (NULL FMENU.WINDOW)
                         then (replace (DINFOGRAPH CURRENTNODE) of GRAPH with NODE) 
                                                             (* FreeMenu turned off, so just 
                                                             display text)
                              (DINFO.UPDATE.TEXT.DISPLAY GRAPH NODE SEL)
                       else                                  (* We've got a FreeMenu, so update 
                                                             away!)
                            (DINFO.UPDATE.FMENU GRAPH NODE)
                            (LET ((STATUS (FM.GETSTATE FMENU.WINDOW)))
                                 (replace (DINFOGRAPH CURRENTNODE) of GRAPH with NODE)
                                 (AND (LISTGET STATUS 'GRAPH)
                                      (DINFO.UPDATE.GRAPH.DISPLAY GRAPH NODE FORCE?))
                                 (AND (LISTGET STATUS 'MENU)
                                      (DINFO.UPDATE.MENU.DISPLAY GRAPH NODE))
                                 (AND (LISTGET STATUS 'TEXT)
                                      (DINFO.UPDATE.TEXT.DISPLAY GRAPH NODE SEL))
                                 (DINFO.UPDATE.HISTORY GRAPH NODE SEL (LISTGET STATUS 'HISTORY]
              (CLEARW (GETPROMPTWINDOW WINDOW])

(DINFOGRAPH
  [LAMBDA (X)                                                (* drc%: " 8-Jan-86 11:12")
    (if (type? DINFOGRAPH X)
        then X
      elseif (AND (WINDOWP X)
                  (WINDOWPROP X 'DINFOGRAPH))
      elseif (AND (WINDOWP X)
                  (WINDOWPROP X 'MAINWINDOW))
        then (WINDOWPROP (WINDOWPROP X 'MAINWINDOW)
                    'DINFOGRAPH])

(DINFO.SPECIAL.UPDATE
  [LAMBDA (TYPE GRAPH)                                       (* drc%: "25-Jan-86 18:26")
          
          (* * Do a TYPE update of Graph, where TYPE is one of Top, Parent, Previous or 
          Next.)

    (LET* [(DINFOW (fetch (DINFOGRAPH WINDOW) of GRAPH))
           (CURRENT.NODE (fetch (DINFOGRAPH CURRENTNODE) of GRAPH))
           (NEW.NODE (FASSOC (SELECTQ TYPE
                                 (Top (fetch (DINFOGRAPH TOPNODEID) of GRAPH))
                                 (Parent (fetch (DINFONODE PARENT) of CURRENT.NODE))
                                 (Next (fetch (DINFONODE NEXTNODE) of CURRENT.NODE))
                                 (Previous (fetch (DINFONODE PREVIOUSNODE) of CURRENT.NODE))
                                 NIL)
                            (fetch (DINFOGRAPH NODELST) of GRAPH]
          (if (OBTAIN.MONITORLOCK (fetch (DINFOGRAPH MONITORLOCK) of GRAPH)
                     T)
              then (if NEW.NODE
                       then (PROCESSPROP (THIS.PROCESS)
                                   'NAME
                                   (CONCAT "DInfo " TYPE))
                            (DINFO.UPDATE GRAPH NEW.NODE)
                     else 
          
          (* TYPE of Top! or Node! will sound silly here, but should never happen.)

                          (printout (GETPROMPTWINDOW (fetch (DINFOGRAPH WINDOW) of GRAPH))
                                 T "This node has no " TYPE))
            else (FLASHWINDOW DINFOW)
                 (PROMPTPRINT "DInfo is busy"])

(DINFO.READ.GRAPH
  [LAMBDA (FILE QUIETFLG)                                    (* drc%: "25-Jan-86 18:17")
          
          (* Reads a file written by DINFO.WRITE.GRAPH.
          Returns the DInfo graph stored on FILE.)

    (OR QUIETFLG (printout T T "Reading " (FILENAMEFIELD FILE 'NAME)
                        " graph..."))
    (LET* ((FULLFILENAME (INFILEP FILE))
           [DATA (CDR (READFILE (OR FULLFILENAME (ERROR "FILE NOT FOUND" FILE]
           (GRAPH (create DINFOGRAPH)))                      (* fields stored on file)
          (replace (DINFOGRAPH TOPNODEID) of GRAPH with (LISTGET DATA 'TOPNODEID))
          (replace (DINFOGRAPH TEXTPROPS) of GRAPH with (LISTGET DATA 'TEXTPROPS))
          (replace (DINFOGRAPH LOOKUPFN) of GRAPH with (LISTGET DATA 'LOOKUPFN))
          (replace (DINFOGRAPH MENUFN) of GRAPH with (LISTGET DATA 'MENUFN))
          (replace (DINFOGRAPH FREEMENUITEMS) of GRAPH with (LISTGET DATA 'FREEMENUITEMS))
          (replace (DINFOGRAPH NODELST) of GRAPH with (LISTGET DATA 'NODELST))
          (replace (DINFOGRAPH USERDATA) of GRAPH with (LISTGET DATA 'USERDATA))
                                                             (* fields filled in at read time)
          (replace (DINFOGRAPH NAME) of GRAPH with (FILENAMEFIELD FULLFILENAME 'NAME))
          (replace (DINFOGRAPH DEFAULTHOST) of GRAPH with (FILENAMEFIELD FULLFILENAME 'HOST))
          (replace (DINFOGRAPH DEFAULTDEVICE) of GRAPH with (FILENAMEFIELD FULLFILENAME 'DEVICE))
          (replace (DINFOGRAPH DEFAULTDIR) of GRAPH with (FILENAMEFIELD FULLFILENAME 'DIRECTORY))
          (OR QUIETFLG (printout T "OK."))
          GRAPH])

(DINFO.WRITE.GRAPH
  [LAMBDA (GRAPH FILE)                                       (* drc%: "25-Jan-86 18:16")
          
          (* Writes a DInfo graph to a file for reading by DINFO.READ.GRAPH.
          Returns the full file name of the file.)
                                                             (* dump it out as a props list)
    (WRITEFILE (LIST 'TOPNODEID (fetch (DINFOGRAPH TOPNODEID) of GRAPH)
                     'TEXTPROPS
                     (fetch (DINFOGRAPH TEXTPROPS) of GRAPH)
                     'LOOKUPFN
                     (fetch (DINFOGRAPH LOOKUPFN) of GRAPH)
                     'MENUFN
                     (fetch (DINFOGRAPH MENUFN) of GRAPH)
                     'FREEMENUITEMS
                     (fetch (DINFOGRAPH FREEMENUITEMS) of GRAPH)
                     'NODELST
                     (fetch (DINFOGRAPH NODELST) of GRAPH)
                     'USERDATA
                     (fetch (DINFOGRAPH USERDATA) of GRAPH))
           FILE])

(DINFO.SELECT.GRAPH
  [LAMBDA NIL                                                (* drc%: "24-Jan-86 13:25")
          
          (* * This is called when DInfo is selected from the Background Menu.)

    (DECLARE (GLOBALVARS DINFO.GRAPHS))
    (ALLOW.BUTTON.EVENTS)
    (RESETFORM (TTY.PROCESS (THIS.PROCESS))
           (LET [(GRAPH (if (NULL DINFO.GRAPHS)
                            then (PROMPTPRINT "No Graphs installed -- load HelpSys or DInfoEdit")
                          elseif (NULL (CDR DINFO.GRAPHS))
                            then (EVAL (CADAR DINFO.GRAPHS))
                          else (MENU (create MENU
                                            CENTERFLG _ T
                                            TITLE _ "Select Graph"
                                            ITEMS _ DINFO.GRAPHS]
                (AND GRAPH (DINFO GRAPH])

(DINFO.DEFAULT.MENU
  [LAMBDA (GRAPH)                                            (* jow "15-Jul-86 17:36")
          
          (* * This is the default MENUFN for DInfo graphs.)

    (LET ((DINFOW (fetch (DINFOGRAPH WINDOW) of GRAPH)))
         (CLEARW (GETPROMPTWINDOW DINFOW))
         (LET [(TYPE (MENU (OR (fetch (DINFOGRAPH DINFO.MENU) of GRAPH)
                               (replace (DINFOGRAPH DINFO.MENU) of GRAPH
                                  with (create MENU
                                              ITEMS _ '(("Top" 'Top "Visit the top node in the graph"
                                                               )
                                                        ("Parent" 'Parent 
                                                               "Visit the parent of the current node"
                                                               )
                                                        ("Previous" 'Previous 
                                                               "Visit the node before this node")
                                                        ("Next " 'Next 
                                                               "Visit the node following this node")
                                                        ("Find" 'Find "Search the text of this node")
                                                        ("Lookup" 'Lookup 
                                                               "Lookup a new term in this graph")
                                                        ("Expanded Menu" 'FreeMenu 
                                                               "Add an expanded options menu."))
                                              CENTERFLG _ T
                                              MENUFONT _ (FONTCREATE 'HELVETICA 10 'BOLD]
              (if TYPE
                  then (PROCESSPROP (THIS.PROCESS)
                              'NAME
                              (CONCAT "DInfo " TYPE))
                       (SELECTQ TYPE
                           ((Top Parent Previous Next) 
                                (DINFO.SPECIAL.UPDATE TYPE GRAPH))
                           (Find (DINFO.FIND GRAPH))
                           (Lookup (DINFO.LOOKUP GRAPH '(LEFT)))
                           (FreeMenu (DINFO.ADD.FMENU GRAPH)
                                     (DINFO.UPDATE GRAPH))
                           NIL])

(DINFO.FIND
  [LAMBDA (GRAPH BUTTONS)                                    (* drc%: "25-Jan-86 18:23")
    (LET ((DINFOW (fetch (DINFOGRAPH WINDOW) of GRAPH)))
         (if (NOT (OBTAIN.MONITORLOCK (fetch (DINFOGRAPH MONITORLOCK) of GRAPH)
                         T))
             then (FLASHWINDOW DINFOW)
                  (PROMPTPRINT "DInfo is busy")
           else (RESETFORM (TTYDISPLAYSTREAM (GETPROMPTWINDOW DINFOW))
                       (TERPRI T)
                       (LET ([STRING (if (AND (FMEMB 'MIDDLE BUTTONS)
                                              (fetch (DINFOGRAPH FIND.STRING) of GRAPH))
                                       else (PROMPTFORWORD "Find: " (fetch (DINFOGRAPH FIND.STRING)
                                                                       of GRAPH)
                                                   NIL NIL NIL 'TTY (CONSTANT (CHARCODE (EOL ESCAPE 
                                                                                             LF]
                             (TEXTSTREAM (WINDOWPROP DINFOW 'TEXTSTREAM))
                             PAIR)
                            (replace (DINFOGRAPH FIND.STRING) of GRAPH with STRING)
                            (if STRING
                                then (PRINTOUT T " Searching...")
                                     (if (SETQ PAIR (TEDIT.FIND TEXTSTREAM STRING NIL NIL T))
                                         then (printout T "OK.")
                                              (TEDIT.NORMALIZECARET TEXTSTREAM
                                                     (TEDIT.SHOWSEL TEXTSTREAM T (TEDIT.SETSEL
                                                                                  TEXTSTREAM
                                                                                  (CAR PAIR)
                                                                                  (NCHARS STRING)
                                                                                  'RIGHT T)))
                                       else (printout T "not found.")
                                            (TEDIT.NORMALIZECARET TEXTSTREAM (TEDIT.SETSEL TEXTSTREAM 
                                                                                    0 0])

(DINFO.LOOKUP
  [LAMBDA (GRAPH BUTTONS)                                    (* drc%: "25-Jan-86 18:22")
    (LET
     ((DINFOW (fetch (DINFOGRAPH WINDOW) of GRAPH)))
     (if (OBTAIN.MONITORLOCK (fetch (DINFOGRAPH MONITORLOCK) of GRAPH)
                T)
         then
         [RESETFORM
          (TTYDISPLAYSTREAM (GETPROMPTWINDOW DINFOW))
          (LET ((LOOKUPFN (fetch (DINFOGRAPH LOOKUPFN) of GRAPH)))
               (if LOOKUPFN
                   then (CLEARW T)
                        (LET* [(OLD.STRING (fetch (DINFOGRAPH LOOKUP.STRING) of GRAPH))
                               (STRING (if (AND OLD.STRING (FMEMB 'MIDDLE BUTTONS))
                                           then OLD.STRING
                                         else (PROMPTFORWORD "Lookup: " OLD.STRING NIL NIL NIL
                                                     'TTY
                                                     (CONSTANT (CHARCODE (EOL ESCAPE LF]
                              (replace (DINFOGRAPH LOOKUP.STRING) of GRAPH with STRING)
                              (AND STRING (APPLY* LOOKUPFN STRING GRAPH)))
                 else (PRINTOUT T T "The " (fetch (DINFOGRAPH NAME) of GRAPH)
                             " graph has no LOOKUPFN."]
       else (FLASHWINDOW DINFOW)
            (PROMPTPRINT "DInfo is busy"])
)
(DEFINEQ

(DINFO.READ.KOTO.GRAPH
  [LAMBDA (FILE QUIETFLG)                                    (* drc%: " 4-Feb-86 11:27")
          
          (* Reads a file written by Koto DINFO.WRITE.GRAPH and returns a Lute 
          DINFOGRAPH. Thus, (DINFO.WRITE.GRAPH (DINFO.READ.KOTO.GRAPH <file1>) <file2>) 
          will convert the Koto format graph in <file1> to a Lute format graph in 
          <file2>.)

    (OR QUIETFLG (printout T T "Reading " (FILENAMEFIELD FILE 'NAME)
                        " graph..."))
    (LET* ((FULLFILENAME (INFILEP FILE))
           [DATA (CDR (READFILE (OR FULLFILENAME (ERROR "FILE NOT FOUND" FILE]
           (GRAPH (create DINFOGRAPH)))                      (* in Koto we just wrote out the 
                                                             DINFOGRAPH record)
          (for FIELD in DATA as N from 1 to 11 do            (* fields stored on file)
                                                  (SELECTQ N
                                                      ((1 4 5 6 10 11))
                                                      (2 (replace (DINFOGRAPH NODELST) of GRAPH
                                                            with FIELD))
                                                      (3 (replace (DINFOGRAPH TOPNODEID) of GRAPH
                                                            with FIELD))
                                                      (7 (replace (DINFOGRAPH TEXTPROPS) of GRAPH
                                                            with FIELD))
                                                      (8 (replace (DINFOGRAPH LOOKUPFN) of GRAPH
                                                            with FIELD))
                                                      (9 (replace (DINFOGRAPH MENUFN) of GRAPH
                                                            with FIELD))
                                                      (SHOULDNT)))
                                                             (* fields filled in at read time)
          (replace (DINFOGRAPH NAME) of GRAPH with (FILENAMEFIELD FULLFILENAME 'NAME))
          (replace (DINFOGRAPH DEFAULTHOST) of GRAPH with (FILENAMEFIELD FULLFILENAME 'HOST))
          (replace (DINFOGRAPH DEFAULTDEVICE) of GRAPH with (FILENAMEFIELD FULLFILENAME 'DEVICE))
          (replace (DINFOGRAPH DEFAULTDIR) of GRAPH with (FILENAMEFIELD FULLFILENAME 'DIRECTORY))
          (OR QUIETFLG (printout T "OK."))
          GRAPH])
)
(DEFINEQ

(DINFO.SETUP.WINDOW
  [LAMBDA (GRAPH WINDOW NO.FREEMENU?)                        (* jow "10-Jun-86 15:29")
    (replace (DINFOGRAPH WINDOW) of GRAPH with WINDOW)
    (WINDOWPROP WINDOW 'DINFOGRAPH GRAPH)
    (DETACHALLWINDOWS WINDOW)
    (if (NOT NO.FREEMENU?)
        then (DINFO.ADD.FMENU GRAPH))
    (DINFO.UPDATE.TEXT.DISPLAY GRAPH NIL NIL T)
    (WINDOWPROP WINDOW 'TITLE (CONCAT (fetch (DINFOGRAPH NAME) of GRAPH)
                                     " DInfo"))
    (WINDOWADDPROP WINDOW 'CLOSEFN 'DINFO.CLOSEFN)
    (WINDOWADDPROP WINDOW 'SHRINKFN 'DINFO.SHRINKFN)
    (WINDOWADDPROP WINDOW 'EXPANDFN 'DINFO.EXPANDFN])

(DINFO.CLOSEFN
  [LAMBDA (W)                                                (* drc%: "25-Jan-86 18:26")
    (LET [(GRAPH (WINDOWPROP W 'DINFOGRAPH]
         (if (type? DINFOGRAPH GRAPH)
             then (CLOSEW (fetch (DINFOGRAPH GRAPH.WINDOW) of GRAPH)) 
                                                             (* remove circularity...)
                  (WINDOWPROP W 'DINFOGRAPH NIL])

(DINFO.SHRINKFN
  [LAMBDA (W)                                                (* drc%: "25-Jan-86 18:26")
    (CLOSEW (fetch (DINFOGRAPH GRAPH.WINDOW) of (DINFOGRAPH W])

(DINFO.EXPANDFN
  [LAMBDA (W)                                                (* jow "15-Jul-86 17:00")
    (LET* ((GRAPH (DINFOGRAPH W))
           (FMENU (fetch (DINFOGRAPH FMENU.WINDOW) of GRAPH)))
          (if (AND FMENU (LISTGET (FM.GETSTATE FMENU)
                                'GRAPH))
              then (LET ((GRAPHW (fetch (DINFOGRAPH GRAPH.WINDOW) of GRAPH)))
                        (OPENW GRAPHW)
                        (TOTOPW W)
                        (WINDOWPROP GRAPHW 'DINFOGRAPH GRAPH])

(DINFO.ICONFN
  [LAMBDA (W)                                                (* drc%: "25-Jan-86 16:33")
    (OR (WINDOWPROP WINDOW 'ICON)
        (WINDOWPROP WINDOW 'ICON (TITLEDICONW TEDIT.TITLED.ICON.TEMPLATE (WINDOWPROP WINDOW
                                                                                'TITLE)
                                        TEDIT.ICON.FONT NIL T))
        (WINDOWPROP WINDOW 'ICON])
)
(DEFINEQ

(DINFO.ADD.FMENU
  [LAMBDA (GRAPH)                                            (* jow "20-May-86 15:41")
          
          (* * Add a DInfo FreeMenu to WINDOW. then update the FreeMenu's display.)

    (LET ((WINDOW (fetch (DINFOGRAPH WINDOW) of GRAPH))
          (FM.WINDOW (fetch (DINFOGRAPH FMENU.WINDOW) of GRAPH)))
         (if [AND (WINDOWP FM.WINDOW)
                  (FMEMB FM.WINDOW (WINDOWPROP WINDOW 'ATTACHEDWINDOWS]
             then (OPENW FM.WINDOW)
           else (REMOVEPROMPTWINDOW WINDOW)
                (SETQ FM.WINDOW (OR (WINDOWP FM.WINDOW)
                                    (DINFO.CREATE.FMENU GRAPH)))
                (replace (DINFOGRAPH FMENU.WINDOW) of GRAPH with FM.WINDOW)
                (ATTACHWINDOW FM.WINDOW WINDOW)
                (WINDOWPROP FM.WINDOW 'FM.PROMPTWINDOW (GETPROMPTWINDOW WINDOW))
                (WINDOWDELPROP FM.WINDOW 'PASSTOMAINCOMS 'CLOSEW)
                (WINDOWADDPROP FM.WINDOW 'CLOSEFN 'DINFO.FMW.CLOSEFN T)
                (DINFO.UPDATE.FMENU GRAPH])

(DINFO.CREATE.FMENU
  [LAMBDA (GRAPH)                                            (* jow "15-Jul-86 17:39")
          
          (* * Makes a DInfo FreeMenu for GRAPH)

    (LET* [(ADD.ITEMS (fetch (DINFOGRAPH FREEMENUITEMS) of GRAPH))
           (FONT (OR (FONTP (fetch (DINFOGRAPH MENUFONT) of GRAPH))
                     MENUFONT))
           (FM (FREEMENU `((PROPS FONT %, FONT)
                           ((LABEL Node%: TYPE DISPLAY FONT (HELVETICA 10))
                            (ID NODE LABEL "" TYPE DISPLAY))
                           ((LABEL Top! SELECTEDFN DINFO.FMENU.HANDLER FONT (HELVETICA 10 BOLD)
                                   MESSAGE "Visit the top node")
                            (ID TOP LABEL "" TYPE DISPLAY))
                           ((LABEL Parent! SELECTEDFN DINFO.FMENU.HANDLER FONT (HELVETICA 10 BOLD)
                                   MESSAGE "Visit the parent of the current node")
                            (ID PARENT LABEL "" TYPE DISPLAY))
                           ((LABEL Previous! SELECTEDFN DINFO.FMENU.HANDLER FONT (HELVETICA 10 BOLD)
                                   MESSAGE "Visit the node previous to the current node")
                            (ID PREVIOUS LABEL "" TYPE DISPLAY))
                           ((LABEL Next! SELECTEDFN DINFO.FMENU.HANDLER FONT (HELVETICA 10 BOLD)
                                   MESSAGE "Visit the node after the current node")
                            (ID NEXT LABEL "" TYPE DISPLAY))
                           ((LABEL Display%: TYPE DISPLAY FONT (HELVETICA 10))
                            (LABEL Graph ID GRAPH INITSTATE %, (MEMB 'GRAPH DINFOMODES)
                                   TYPE TOGGLE SELECTEDFN DINFO.TOGGLE.GRAPH FONT (HELVETICA 10 BOLD)
                                   MESSAGE "Toggle display of the graph")
                            (LABEL Menu ID MENU INITSTATE %, (MEMB 'MENU DINFOMODES)
                                   TYPE TOGGLE SELECTEDFN DINFO.TOGGLE.MENU FONT (HELVETICA 10 BOLD)
                                   MESSAGE "Toggle display of the subnode menu")
                            (LABEL Text ID TEXT INITSTATE %, (MEMB 'TEXT DINFOMODES)
                                   TYPE TOGGLE SELECTEDFN DINFO.TOGGLE.TEXT FONT (HELVETICA 10 BOLD)
                                   MESSAGE "Toggle display of the text of the current node")
                            (LABEL History ID HISTORY INITSTATE %, (MEMB 'HISTORY DINFOMODES)
                                   TYPE TOGGLE FONT (HELVETICA 10 BOLD)
                                   SELECTEDFN DINFO.TOGGLE.HISTORY MESSAGE 
                                   "Toggle the display of the History Menu"))
                           %,
                           (APPEND '((LABEL Find! SELECTEDFN DINFO.FMENU.HANDLER FONT
                                            (HELVETICA 10 BOLD)
                                            MESSAGE 
                                   "Perform a string search in the selected text of the current node"
                                            )
                                     (LABEL Lookup! SELECTEDFN DINFO.FMENU.HANDLER FONT
                                            (HELVETICA 10 BOLD)
                                            MESSAGE 
                            "Lookup a term in this graph.  LEFT for new term, MIDDLE to repeat last."
                                            )) ADD.ITEMS]
          (WINDOWPROP FM 'FM.DONTRESHAPE T)
          FM])

(DINFO.FMW.CLOSEFN
  [LAMBDA (W)                                                (* drc%: "25-Jan-86 18:19")
          
          (* * CLOSEFN for a DInfo FreeMenu window.)

    (LET* ((DINFOW (WINDOWPROP W 'MAINWINDOW))
           (GRAPH (DINFOGRAPH DINFOW)))
          (if GRAPH
              then (DETACHWINDOW W)
                   (replace (DINFOGRAPH FMENU.WINDOW) of GRAPH with NIL)
                   (DETACHWINDOW (fetch (DINFOGRAPH SUBNODE.MENU.WINDOW) of GRAPH))
                   (CLOSEW (fetch (DINFOGRAPH SUBNODE.MENU.WINDOW) of GRAPH))
                   (DETACHWINDOW (fetch (DINFOGRAPH HISTORY.MENU.WINDOW) of GRAPH))
                   (CLOSEW (fetch (DINFOGRAPH GRAPH.WINDOW) of GRAPH))
                   (REMOVEPROMPTWINDOW DINFOW])

(DINFO.FMENU.HANDLER
  [LAMBDA (ITEM WINDOW BUTTONS)                              (* drc%: "16-Jan-86 11:42")
          
          (* * Handle a command from the FreeMenu.)

    (LET [(GRAPH (WINDOWPROP (WINDOWPROP WINDOW 'MAINWINDOW)
                        'DINFOGRAPH))
          (TYPE (MKATOM (SUBSTRING (FM.ITEMPROP ITEM 'LABEL)
                               1 -2]
         (SELECTQ TYPE
             ((Top Parent Previous Next) 
                  (DINFO.SPECIAL.UPDATE TYPE GRAPH))
             (Find (DINFO.FIND GRAPH BUTTONS))
             (Lookup (DINFO.LOOKUP GRAPH BUTTONS))
             (SHOULDNT])

(DINFO.UPDATE.FMENU
  [LAMBDA (GRAPH NEW.NODE)                                   (* jow "20-May-86 15:13")
          
          (* * Update the display of GRAPH's FreeMenu.
          If NEW.NODE is not specified, use Top node of GRAPH, and change Top node title.)

    (LET* [(W (fetch (DINFOGRAPH FMENU.WINDOW) of GRAPH))
           (NODELST (fetch (DINFOGRAPH NODELST) of GRAPH))
           (NODE (OR NEW.NODE (FASSOC (fetch (DINFONODE ID) of (fetch (DINFOGRAPH CURRENTNODE)
                                                                  of GRAPH))
                                     NODELST)
                     (FASSOC (fetch (DINFOGRAPH TOPNODEID) of GRAPH)
                            NODELST]
          (OR NEW.NODE (FM.CHANGELABEL (FM.GETITEM 'TOP NIL W)
                              (fetch (DINFONODE LABEL) of (FASSOC (fetch (DINFOGRAPH TOPNODEID)
                                                                     of GRAPH)
                                                                 (fetch (DINFOGRAPH NODELST)
                                                                    of GRAPH)))
                              W))
          (FM.CHANGELABEL (FM.GETITEM 'NODE NIL W)
                 (fetch (DINFONODE LABEL) of NODE)
                 W)
          (FM.CHANGELABEL (FM.GETITEM 'PARENT NIL W)
                 (fetch (DINFONODE LABEL) of NODE (FASSOC (fetch (DINFONODE PARENT) of NODE)
                                                         NODELST))
                 W)
          (FM.CHANGELABEL (FM.GETITEM 'NEXT NIL W)
                 (fetch (DINFONODE LABEL) of NODE (FASSOC (fetch (DINFONODE NEXTNODE) of NODE)
                                                         NODELST))
                 W)
          (FM.CHANGELABEL (FM.GETITEM 'PREVIOUS NIL W)
                 (fetch (DINFONODE LABEL) of NODE (FASSOC (fetch (DINFONODE PREVIOUSNODE)
                                                             of NODE)
                                                         NODELST))
                 W])

(DINFO.TOGGLE.MENU
  [LAMBDA (ITEM WINDOW)                                      (* jow "10-Jun-86 14:15")
    (LET [(GRAPH (WINDOWPROP (WINDOWPROP WINDOW 'MAINWINDOW)
                        'DINFOGRAPH]
         (if (FM.ITEMPROP ITEM 'STATE)
             then (DINFO.UPDATE.MENU.DISPLAY GRAPH (fetch (DINFOGRAPH CURRENTNODE) of GRAPH))
           else (LET ((SUBNODE.MENU.WINDOW (fetch (DINFOGRAPH SUBNODE.MENU.WINDOW) of GRAPH)))
                     (DETACHWINDOW SUBNODE.MENU.WINDOW)
                     (CLOSEW SUBNODE.MENU.WINDOW])

(DINFO.TOGGLE.GRAPH
  [LAMBDA (ITEM WINDOW)                                      (* ; "Edited  1-Oct-87 09:56 by drc:")

    (LET [(GRAPH (WINDOWPROP (WINDOWPROP WINDOW 'MAINWINDOW)
                        'DINFOGRAPH]
         (if (FM.ITEMPROP ITEM 'STATE)
             then (DINFO.UPDATE.GRAPH.DISPLAY GRAPH (fetch CURRENTNODE of GRAPH)
                         T)
           else (CLOSEW (fetch (DINFOGRAPH GRAPH.WINDOW) of GRAPH)))
         ITEM])

(DINFO.TOGGLE.HISTORY
  [LAMBDA (ITEM WINDOW)                                      (* jow "10-Jun-86 14:22")
    (LET [(GRAPH (WINDOWPROP (WINDOWPROP WINDOW 'MAINWINDOW)
                        'DINFOGRAPH]
         (if (FM.ITEMPROP ITEM 'STATE)
             then (DINFO.UPDATE.HISTORY GRAPH NIL NIL T)
           else (LET ((HISTORY.MENU.WINDOW (fetch (DINFOGRAPH HISTORY.MENU.WINDOW) of GRAPH)))
                     (DETACHWINDOW HISTORY.MENU.WINDOW)
                     (CLOSEW HISTORY.MENU.WINDOW])

(DINFO.TOGGLE.TEXT
  [LAMBDA (ITEM WINDOW)                                      (* drc%: "25-Jan-86 18:26")
    (LET* ((DINFOW (WINDOWPROP WINDOW 'MAINWINDOW))
           (GRAPH (WINDOWPROP DINFOW 'DINFOGRAPH))
           (MONITORLOCK (fetch (DINFOGRAPH MONITORLOCK) of GRAPH)))
          (if (NOT (OBTAIN.MONITORLOCK MONITORLOCK T))
              then (FLASHWINDOW DINFOW)
                   (PROMPTPRINT "DInfo is busy")
            elseif (FM.ITEMPROP ITEM 'STATE)
              then (DINFO.UPDATE.TEXT.DISPLAY GRAPH (fetch (DINFOGRAPH CURRENTNODE) of GRAPH))
                   (RELEASE.MONITORLOCK MONITORLOCK)
            else (DINFO.UPDATE.TEXT.DISPLAY GRAPH (fetch (DINFOGRAPH CURRENTNODE) of GRAPH)
                        NIL T)
                 (RELEASE.MONITORLOCK MONITORLOCK])
)
(DEFINEQ

(DINFO.UPDATE.MENU.DISPLAY
  [LAMBDA (GRAPH NODE)                                       (* drc%: "25-Jan-86 18:20")
    (LET* [(DINFOW (fetch (DINFOGRAPH WINDOW) of GRAPH))
           (WINDOW (fetch (DINFOGRAPH SUBNODE.MENU.WINDOW) of GRAPH))
           [CHILDREN (DREVERSE (for ID in (fetch (DINFONODE CHILDREN) of NODE)
                                  bind (NODELST _ (fetch (DINFOGRAPH NODELST) of GRAPH))
                                  collect (FASSOC ID NODELST]
           (LENGTH (FLENGTH CHILDREN))
           (SCROLLABLE (GREATERP LENGTH \DINFO.MAX.MENU.LEN))
           (MENU (create MENU
                        MENUFONT _ (OR (FONTP (fetch (DINFOGRAPH MENUFONT) of GRAPH))
                                       MENUFONT)
                        ITEMWIDTH _ (WINDOWPROP DINFOW 'WIDTH)
                        CENTERFLG _ T
                        MENUCOLUMNS _ 1
                        MENUOUTLINESIZE _ 0
                        ITEMS _ (for CHILD in CHILDREN collect (LIST (fetch (DINFONODE LABEL)
                                                                        of CHILD)
                                                                     CHILD 
                                                                  "Will visit this node if selected."
                                                                     ))
                        WHENSELECTEDFN _ (FUNCTION DINFO.UPDATE.FROM.MENU]
          (AND WINDOW (PROGN (DETACHWINDOW WINDOW)
                             (CLOSEW WINDOW)))
          (if CHILDREN
              then (UPDATE/MENU/IMAGE MENU)
                   (SETQ WINDOW (CREATEW (create REGION
                                                LEFT _ 0
                                                BOTTOM _ 0
                                                WIDTH _ (WINDOWPROP DINFOW 'WIDTH)
                                                HEIGHT _
                                                (HEIGHTIFWINDOW
                                                 (if SCROLLABLE
                                                     then (TIMES \DINFO.MAX.MENU.LEN
                                                                 (fetch (MENU ITEMHEIGHT)
                                                                    of MENU))
                                                   else (fetch (MENU IMAGEHEIGHT) of MENU))
                                                 T))
                                       "Subnodes" NIL T))
                   (ADDMENU MENU WINDOW (create POSITION
                                               XCOORD _ 0
                                               YCOORD _ (if SCROLLABLE
                                                            then (TIMES (DIFFERENCE 
                                                                               \DINFO.MAX.MENU.LEN 
                                                                               LENGTH)
                                                                        (fetch (MENU ITEMHEIGHT)
                                                                           of MENU))
                                                          else 0))
                          T)
                   (ATTACHWINDOW WINDOW DINFOW 'BOTTOM)
                   (REDISPLAYW WINDOW)
                   (replace (DINFOGRAPH SUBNODE.MENU.WINDOW) of GRAPH with WINDOW)
                   (LET [(BITS (fetch (REGION BOTTOM) of (WINDOWPROP WINDOW 'REGION]
          
          (* Slide DINFOW up if our new menu is off the screen)

                        (AND (ILESSP BITS 0)
                             (RELMOVEW DINFOW (create POSITION
                                                     XCOORD _ 0
                                                     YCOORD _ (IDIFFERENCE 0 BITS])

(DINFO.UPDATE.FROM.MENU
  [LAMBDA (ITEM MENU BUTTONS)                                (* drc%: "12-Dec-85 14:49")
    (DINFO.UPDATE (WINDOWPROP (WINDOWPROP (WFROMMENU MENU)
                                     'MAINWINDOW)
                         'DINFOGRAPH)
           (CADR ITEM])

(DINFO.UPDATE.HISTORY
  [LAMBDA (GRAPH NODE SEL DISPLAY?)                          (* drc%: "25-Jan-86 18:21")
    (LET* ((DINFOW (fetch (DINFOGRAPH WINDOW) of GRAPH))
           (OLDWINDOW (fetch (DINFOGRAPH HISTORY.MENU.WINDOW) of GRAPH))
           (OLDITEMS (fetch (DINFOGRAPH HISTORY.ITEMS) of GRAPH))
           (NEWITEM (if SEL
                        then (LIST (if (LISTP SEL)
                                       then (CAR SEL)
                                     else SEL)
                                   (LIST (fetch (DINFONODE ID) of NODE)
                                         SEL)
                                   "Will re-lookup this term")
                      elseif NODE
                        then (LIST (fetch (DINFONODE LABEL) of NODE)
                                   (LIST (fetch (DINFONODE ID) of NODE)
                                         SEL)
                                   "Will re-visit this node")))
           (ITEMS (if [AND NEWITEM (NOT (EQUAL NEWITEM (CAR OLDITEMS]
                      then (CONS NEWITEM
                                 (for ITEM in OLDITEMS as I from 2 to DINFO.HISTORY.LENGTH
                                    collect ITEM))
                    else OLDITEMS)))
          (replace (DINFOGRAPH HISTORY.ITEMS) of GRAPH with ITEMS)
          (AND OLDWINDOW (PROGN (DETACHWINDOW OLDWINDOW)
                                (CLOSEW OLDWINDOW)))
          (AND DISPLAY? ITEMS
               (LET [(HISTORYW (ATTACHMENU (create MENU
                                                  MENUFONT _ (OR (FONTP (fetch (DINFOGRAPH MENUFONT)
                                                                           of GRAPH))
                                                                 MENUFONT)
                                                  TITLE _ "History"
                                                  CENTERFLG _ T
                                                  MENUCOLUMNS _ 1
                                                  ITEMS _ ITEMS
                                                  WHENSELECTEDFN _ (FUNCTION DINFO.HISTORIC.UPDATE))
                                      DINFOW
                                      'LEFT
                                      'TOP]
                    (replace (DINFOGRAPH HISTORY.MENU.WINDOW) of GRAPH with HISTORYW])

(DINFO.HISTORIC.UPDATE
  [LAMBDA (ITEM MENU BUTTONS)                                (* drc%: "25-Jan-86 18:24")
    (LET* [(ID (CAADR ITEM))
           (SEL (CADADR ITEM))
           (WINDOW (WINDOWPROP (WFROMMENU MENU)
                          'MAINWINDOW))
           (GRAPH (WINDOWPROP WINDOW 'DINFOGRAPH))
           (NODE (FASSOC ID (fetch (DINFOGRAPH NODELST) of GRAPH]
          (if (NOT (OBTAIN.MONITORLOCK (fetch (DINFOGRAPH MONITORLOCK) of GRAPH)
                          T))
              then (FLASHWINDOW WINDOW)
                   (PROMPTPRINT "DInfo is busy")
            elseif (NULL NODE)
              then (PRINTOUT (GETPROMPTWINDOW WINDOW)
                          T "This node no longer exists")
            else (DINFO.UPDATE GRAPH NODE SEL])
)
(DEFINEQ

(DINFO.UPDATE.GRAPH.DISPLAY
  [LAMBDA (DINFO.GRAPH NODE FORCE?)                          (* drc%: "27-Jan-86 16:19")
    (LET [(DINFOW (fetch (DINFOGRAPH WINDOW) of DINFO.GRAPH))
          (LOCATION (CONS (fetch (DINFONODE PARENT) of NODE)
                          (fetch (DINFONODE CHILDREN) of NODE]
         (if (AND (NOT FORCE?)
                  (EQUAL LOCATION (fetch (DINFOGRAPH LAST.GRAPH.LOCATION) of DINFO.GRAPH)))
             then 
          
          (* don't need to relayout grapher display --
          just change which node is inverted.)

                  (DINFO.INVERT.NODE (fetch (DINFOGRAPH GRAPH.WINDOW) of DINFO.GRAPH)
                         NODE DINFO.GRAPH)
           else (DINFO.SHOWGRAPH (DINFO.LAYOUTGRAPH DINFO.GRAPH NODE)
                       DINFO.GRAPH))
         (replace (DINFOGRAPH LAST.GRAPH.LOCATION) of DINFO.GRAPH with LOCATION)
         (WINDOWPROP (fetch (DINFOGRAPH GRAPH.WINDOW) of DINFO.GRAPH)
                'TITLE
                (CONCAT (fetch (DINFOGRAPH NAME) of DINFO.GRAPH)
                       " - "
                       (fetch (DINFONODE LABEL) of (fetch (DINFOGRAPH CURRENTNODE) of DINFO.GRAPH])

(DINFO.UPDATE.FROM.GRAPH
  [LAMBDA (GRAPHER.NODE GRAPH.WINDOW)                        (* drc%: "12-Dec-85 18:34")
    (AND GRAPHER.NODE (ADD.PROCESS `(DINFO.UPDATE (QUOTE %, (WINDOWPROP GRAPH.WINDOW 'DINFOGRAPH))
                                           (QUOTE %, (fetch (GRAPHNODE NODEID)
                                                            of GRAPHER.NODE))) 'NAME 
                             "DInfo From Graph"])

(DINFO.GET.GRAPH.WINDOW
  [LAMBDA (GRAPH REGION)                                     (* drc%: "25-Jan-86 18:05")
    (LET ((W (fetch (DINFOGRAPH GRAPH.WINDOW) of GRAPH)))
         (COND
            ((WINDOWP W))
            (T (SETQ W (DINFO.CREATE.GRAPH.WINDOW GRAPH REGION))
               [WINDOWPROP W 'CLOSEFN (FUNCTION (LAMBDA (W)
                                                  (WINDOWPROP W 'DINFOGRAPH NIL]
               (replace (DINFOGRAPH GRAPH.WINDOW) of GRAPH with W)))
         (WINDOWPROP W 'DINFOGRAPH GRAPH)
         W])

(DINFO.CREATE.GRAPH.WINDOW
  [LAMBDA (GRAPH REGION)                                     (* drc%: "25-Jan-86 17:49")
    (LET* ((DINFOW (fetch (DINFOGRAPH WINDOW) of GRAPH))
           (DINFOREGION (WINDOWPROP DINFOW 'REGION))
           (LEFT (DIFFERENCE (DIFFERENCE (fetch (REGION LEFT) of DINFOREGION)
                                    (fetch (REGION WIDTH) of REGION))
                        10))
           (BOTTOM (DIFFERENCE (DIFFERENCE (fetch (REGION BOTTOM) of DINFOREGION)
                                      (fetch (REGION HEIGHT) of REGION))
                          50)))
          (CREATEW (CREATEREGION (if (GEQ LEFT 0)
                                     then LEFT
                                   else (RAND 0 10))
                          (if (GEQ BOTTOM 0)
                              then BOTTOM
                            else (RAND 0 10))
                          (fetch (REGION WIDTH) of REGION)
                          (fetch (REGION HEIGHT) of REGION))
                 NIL NIL T])

(DINFO.SHOWGRAPH
  [LAMBDA (GRAPHER.GRAPH DINFO.GRAPH)                        (* drc%: "27-Jan-86 16:15")
    (LET* [(GRAPH.REGION (GRAPHREGION GRAPHER.GRAPH))
           (GRAPH.WINDOW (DINFO.GET.GRAPH.WINDOW DINFO.GRAPH GRAPH.REGION))
           (WINDOW.REGION (WINDOWPROP GRAPH.WINDOW 'REGION]
          [SHAPEW GRAPH.WINDOW (LET [(LEFT (fetch (REGION LEFT) of WINDOW.REGION))
                                     (BOTTOM (fetch (REGION BOTTOM) of WINDOW.REGION))
                                     (HEIGHT (HEIGHTIFWINDOW (fetch (REGION HEIGHT) of GRAPH.REGION)
                                                    T))
                                     (WIDTH (WIDTHIFWINDOW (fetch (REGION WIDTH) of GRAPH.REGION]
                                    (create REGION
                                           LEFT _ LEFT
                                           BOTTOM _ BOTTOM
                                           HEIGHT _ (if (GEQ (IPLUS BOTTOM HEIGHT)
                                                             SCREENHEIGHT)
                                                        then (IDIFFERENCE SCREENHEIGHT BOTTOM)
                                                      else HEIGHT)
                                           WIDTH _ (if (GEQ (IPLUS LEFT WIDTH)
                                                            SCREENWIDTH)
                                                       then (IDIFFERENCE SCREENWIDTH LEFT)
                                                     else WIDTH]
          (SHOWGRAPH GRAPHER.GRAPH GRAPH.WINDOW (FUNCTION DINFO.UPDATE.FROM.GRAPH)
                 (FUNCTION DINFO.UPDATE.FROM.GRAPH])

(DINFO.INVERT.NODE
  [LAMBDA (WINDOW DINFO.NODE DINFO.GRAPH)                    (* drc%: "25-Jan-86 18:24")
    (LET* ((NODE (for NODE in (fetch (GRAPH GRAPHNODES) of (WINDOWPROP WINDOW 'GRAPH))
                    thereis (EQ (fetch (GRAPHNODE NODEID) of NODE)
                                DINFO.NODE)))
           (LAST.NODE (fetch (DINFOGRAPH LAST.INVERTED.NODE) of DINFO.GRAPH)))
          (replace (DINFOGRAPH LAST.INVERTED.NODE) of DINFO.GRAPH with NODE)
          (if (NEQ NODE LAST.NODE)
              then (replace (GRAPHNODE NODELABELSHADE) of NODE with BLACKSHADE) 
                                                             (* (PRINTDISPLAYNODE NODE
                                                             (create POSITION XCOORD _ 0 YCOORD _ 0) 
                                                             WINDOW))
                   (replace (GRAPHNODE NODELABELSHADE) of LAST.NODE with WHITESHADE) 
                                                             (* (PRINTDISPLAYNODE LAST.NODE
                                                             (create POSITION XCOORD _ 0 YCOORD _ 0) 
                                                             WINDOW))
                   (REDISPLAYW WINDOW)
            else (OPENW WINDOW])

(DINFO.LAYOUTGRAPH
  [LAMBDA (DINFO.GRAPH NODE)                                 (* drc%: "25-Jan-86 18:20")
    (LET* [(WINDOW (fetch (DINFOGRAPH WINDOW) of DINFO.GRAPH))
           (FONT (OR (FONTP (fetch (DINFOGRAPH MENUFONT) of DINFO.GRAPH))
                     MENUFONT))
           (NODELST (fetch (DINFOGRAPH NODELST) of DINFO.GRAPH))
           (CHILDREN (for ID in (fetch (DINFONODE CHILDREN) of NODE) collect (FASSOC ID NODELST)))
           [CHILD.GRAPHER.NODES (for CHILD in CHILDREN
                                   collect (create GRAPHNODE
                                                  NODEID _ CHILD
                                                  NODELABEL _ (fetch (DINFONODE LABEL) of CHILD]
           (GRAPHER.NODE (create GRAPHNODE
                                NODELABELSHADE _ BLACKSHADE
                                NODEID _ NODE
                                TONODES _ CHILDREN
                                NODELABEL _ (fetch (DINFONODE LABEL) of NODE]
          (replace (DINFOGRAPH LAST.INVERTED.NODE) of DINFO.GRAPH with GRAPHER.NODE)
                                                             (* so DINFO.INVERT.NODE will work 
                                                             right)
          (if (fetch (DINFONODE PARENT) of NODE)
              then (LET* ((PARENT (FASSOC (fetch (DINFONODE PARENT) of NODE)
                                         NODELST))
                          (SIBLINGS (for ID in (fetch (DINFONODE CHILDREN) of PARENT)
                                       collect (FASSOC ID NODELST)))
                          [SIBLING.GRAPHER.NODES (for SIBLING in SIBLINGS
                                                    collect (if (EQ (fetch (DINFONODE ID)
                                                                       of SIBLING)
                                                                    (fetch (DINFONODE ID)
                                                                       of NODE))
                                                                then GRAPHER.NODE
                                                              else (create GRAPHNODE
                                                                          NODEID _ SIBLING
                                                                          NODELABEL _
                                                                          (fetch (DINFONODE LABEL)
                                                                             of SIBLING]
                          (PARENT.GRAPHER.NODE (create GRAPHNODE
                                                      NODEID _ PARENT
                                                      NODELABEL _ (fetch (DINFONODE LABEL)
                                                                     of PARENT)
                                                      TONODES _ SIBLINGS)))
                         (LAYOUTGRAPH (CONS PARENT.GRAPHER.NODE (NCONC SIBLING.GRAPHER.NODES 
                                                                       CHILD.GRAPHER.NODES))
                                (LIST PARENT)
                                NIL FONT))
            else (LAYOUTGRAPH (CONS GRAPHER.NODE CHILD.GRAPHER.NODES)
                        (LIST NODE)
                        NIL FONT])
)
(DEFINEQ

(DINFO.UPDATE.TEXT.DISPLAY
  [LAMBDA (GRAPH NODE SEL OFF?)                              (* drc%: "25-Jan-86 18:18")
    (LET ((WINDOW (fetch (DINFOGRAPH WINDOW) of GRAPH))
          (FILENAME (DINFO.GET.FILENAME GRAPH NODE))
          (FROM (fetch (DINFONODE FROMBYTE) of NODE))
          (TO (fetch (DINFONODE TOBYTE) of NODE))
          (PROPS (APPEND (LIST 'READONLY T 'NOTITLE T 'TITLEMENUFN 'DINFO.TITLEMENUFN)
                        (fetch (DINFOGRAPH TEXTPROPS) of GRAPH)))
          (OLD.TEXTSTREAM (WINDOWPROP (fetch (DINFOGRAPH WINDOW) of GRAPH)
                                 'TEXTSTREAM))
          TEXTSTREAM FULLFILENAME)                           (* Default directory and host.)
         (if (OR OFF? (NULL FILENAME))
             then (OPENTEXTSTREAM (if OFF?
                                      then ""
                                    else "This node has no text")
                         WINDOW NIL NIL PROPS)
                  (replace (DINFOGRAPH LAST.TEXT) of GRAPH with NIL)
           elseif (SETQ FULLFILENAME (MKATOM (INFILEP FILENAME)))
             then (SETQ TEXTSTREAM (DINFO.OPENTEXTSTREAM FULLFILENAME WINDOW FROM TO PROPS))
                  (DINFO.SHOWSEL TEXTSTREAM SEL)
           else (OPENTEXTSTREAM (CONCAT "Sorry, can't find the text for this node."
                                       (MKSTRING (CHARACTER (CHARCODE CR)))
                                       "Missing file is: " FILENAME)
                       WINDOW NIL NIL PROPS)
                (replace (DINFOGRAPH LAST.TEXT) of GRAPH with NIL))
         (CLOSEF? OLD.TEXTSTREAM)
         (WINDOWPROP WINDOW 'ICONFN 'DINFO.ICONFN)
         (WINDOWPROP WINDOW 'TEDIT.TITLEMENUFN 'DINFO.TITLEMENUFN])

(DINFO.TITLEMENUFN
  [LAMBDA (DINFOW)                                           (* drc%: "25-Jan-86 18:19")
          
          (* * This is the TEdit TITLEMENUFN for a DInfo Window.
          Uses the MENUFN of graph, defaulting to DINFO.DEFAULT.MENU.)

    (LET [(GRAPH (WINDOWPROP DINFOW 'DINFOGRAPH]
         (if (OBTAIN.MONITORLOCK (fetch (DINFOGRAPH MONITORLOCK) of GRAPH)
                    T)
             then [LET ((MENUFN (fetch (DINFOGRAPH MENUFN) of GRAPH)))
                       (if (FGETD MENUFN)
                           then (OR (fetch (DINFOGRAPH FMENU.WINDOW) of GRAPH)
                                    (DINFO.ADD.FMENU GRAPH))
                                (RESETFORM (TTYDISPLAYSTREAM (GETPROMPTWINDOW DINFOW))
                                       (APPLY* MENUFN GRAPH))
                         else (RESETFORM (TTYDISPLAYSTREAM (GETPROMPTWINDOW DINFOW))
                                     (DINFO.DEFAULT.MENU GRAPH]
           else (FLASHWINDOW DINFOW)
                (PROMPTPRINT "DInfo is busy"])

(DINFO.OPENTEXTSTREAM
  [LAMBDA (FILE WINDOW FROM TO PROPS)                        (* drc%: "25-Jan-86 18:24")
    (RESETFORM (TTYDISPLAYSTREAM (GETPROMPTWINDOW WINDOW))
           (LET ((TEXTSTREAM (WINDOWPROP WINDOW 'TEXTSTREAM))
                 (THIS.TEXT (LIST FILE FROM TO)))
                (if (AND (EQUAL THIS.TEXT (fetch (DINFOGRAPH LAST.TEXT) of (DINFOGRAPH WINDOW)))
                         TEXTSTREAM)
                    then                                     (* Same text, and its still there, so 
                                                             do nothing.)
                         TEXTSTREAM
                  else (AND TEXTSTREAM (TEDIT.KILL TEXTSTREAM))
                       (CLEARW T)
                       (CLEARW WINDOW)
                       [RESETSAVE NIL `(AND RESETSTATE (WINDOWPROP %, WINDOW 'LAST.TEXT NIL]
                       (PRINTOUT T "Fetching text from " FILE "...")
                       (PROG1 (OPENTEXTSTREAM FILE WINDOW FROM TO PROPS)
                              (PRINTOUT T "OK.")
                              (replace (DINFOGRAPH LAST.TEXT) of (DINFOGRAPH WINDOW) with THIS.TEXT])

(DINFO.SHOWSEL
  [LAMBDA (TEXTSTREAM SEL)                                   (* drc%: "16-Jan-86 21:30")
    (if (LISTP SEL)
        then (TEDIT.NORMALIZECARET TEXTSTREAM (TEDIT.SETSEL TEXTSTREAM (CADR SEL)
                                                     0))
      elseif (STRINGP SEL)
        then [LET ((CHAR# (TEDIT.FIND TEXTSTREAM SEL)))
                  (if CHAR#
                      then (TEDIT.NORMALIZECARET TEXTSTREAM (TEDIT.SETSEL TEXTSTREAM CHAR#
                                                                   (NCHARS SEL)
                                                                   NIL T]
      else (TEDIT.NORMALIZECARET TEXTSTREAM (TEDIT.SETSEL TEXTSTREAM 0 0])

(DINFO.GET.FILENAME
  [LAMBDA (GRAPH NODE)                                       (* drc%: "10-Jan-86 14:47")
          
          (* * returns the filename of the documentation for NODE in GRAPH.
          Defaults HOST and DIRECTORY to that of graph)

    (LET ((FILE (fetch (DINFONODE FILE) of NODE)))
         (AND FILE (PACKFILENAME 'HOST (OR (FILENAMEFIELD FILE 'HOST)
                                           (fetch (DINFOGRAPH DEFAULTHOST) of GRAPH))
                          'DEVICE
                          (OR (FILENAMEFIELD FILE 'DEVICE)
                              (fetch (DINFOGRAPH DEFAULTDEVICE) of GRAPH))
                          'DIRECTORY
                          (OR (FILENAMEFIELD FILE 'DIRECTORY)
                              (fetch (DINFOGRAPH DEFAULTDIR) of GRAPH))
                          'BODY FILE])
)

(ADDTOVAR BackgroundMenuCommands (DInfo (DINFO.SELECT.GRAPH)
                                            "Open a DInfo window for browsing documentation."))

(RPAQQ BackgroundMenu NIL)

(RPAQ? DINFO.GRAPHS )

(RPAQ? DINFOMODES '(TEXT GRAPH))

(RPAQ? DINFO.HISTORY.LENGTH 20)

(RPAQ? \DINFO.MAX.MENU.LEN 10)
(DECLARE%: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS DINFO.GRAPH.FILES DINFOMODES DINFO.HISTORY.LENGTH \DINFO.MAX.MENU.LEN)
)

(PUTPROPS DINFO FILETYPE :COMPILE-FILE)

(SETTEMPLATE 'DINFOGRAPHPROP 'MACRO)
(PUTPROPS DINFO COPYRIGHT ("Xerox Corporation" 1985 1986 1987 2020))
(DECLARE%: DONTCOPY
  (FILEMAP (NIL (6436 23262 (DINFO 6446 . 8060) (DINFO.UPDATE 8062 . 10926) (DINFOGRAPH 10928 . 11346) (
DINFO.SPECIAL.UPDATE 11348 . 13046) (DINFO.READ.GRAPH 13048 . 14903) (DINFO.WRITE.GRAPH 14905 . 15995)
 (DINFO.SELECT.GRAPH 15997 . 16904) (DINFO.DEFAULT.MENU 16906 . 19430) (DINFO.FIND 19432 . 21816) (
DINFO.LOOKUP 21818 . 23260)) (23263 25957 (DINFO.READ.KOTO.GRAPH 23273 . 25955)) (25958 28272 (
DINFO.SETUP.WINDOW 25968 . 26649) (DINFO.CLOSEFN 26651 . 27084) (DINFO.SHRINKFN 27086 . 27282) (
DINFO.EXPANDFN 27284 . 27841) (DINFO.ICONFN 27843 . 28270)) (28273 39121 (DINFO.ADD.FMENU 28283 . 
29378) (DINFO.CREATE.FMENU 29380 . 32917) (DINFO.FMW.CLOSEFN 32919 . 33764) (DINFO.FMENU.HANDLER 33766
 . 34405) (DINFO.UPDATE.FMENU 34407 . 36612) (DINFO.TOGGLE.MENU 36614 . 37204) (DINFO.TOGGLE.GRAPH 
37206 . 37705) (DINFO.TOGGLE.HISTORY 37707 . 38251) (DINFO.TOGGLE.TEXT 38253 . 39119)) (39122 46820 (
DINFO.UPDATE.MENU.DISPLAY 39132 . 43152) (DINFO.UPDATE.FROM.MENU 43154 . 43453) (DINFO.UPDATE.HISTORY 
43455 . 45989) (DINFO.HISTORIC.UPDATE 45991 . 46818)) (46821 56987 (DINFO.UPDATE.GRAPH.DISPLAY 46831
 . 48149) (DINFO.UPDATE.FROM.GRAPH 48151 . 48594) (DINFO.GET.GRAPH.WINDOW 48596 . 49181) (
DINFO.CREATE.GRAPH.WINDOW 49183 . 50300) (DINFO.SHOWGRAPH 50302 . 52027) (DINFO.INVERT.NODE 52029 . 
53417) (DINFO.LAYOUTGRAPH 53419 . 56985)) (56988 62844 (DINFO.UPDATE.TEXT.DISPLAY 56998 . 58859) (
DINFO.TITLEMENUFN 58861 . 59986) (DINFO.OPENTEXTSTREAM 59988 . 61204) (DINFO.SHOWSEL 61206 . 61939) (
DINFO.GET.FILENAME 61941 . 62842)))))
STOP
\ No newline at end of file
diff --git a/lispusers/DINFO.LCOM b/lispusers/DINFO.LCOM
index 65fdbb59..0cd47c56 100644
Binary files a/lispusers/DINFO.LCOM and b/lispusers/DINFO.LCOM differ
diff --git a/lispusers/dinfo.tedit b/lispusers/DINFO.TEDIT
similarity index 100%
rename from lispusers/dinfo.tedit
rename to lispusers/DINFO.TEDIT
diff --git a/lispusers/HELPSYS b/lispusers/HELPSYS
index 655f5961..29892d36 100644
--- a/lispusers/HELPSYS
+++ b/lispusers/HELPSYS
@@ -1 +1 @@
-(DEFINE-FILE-INFO READTABLE "INTERLISP" PACKAGE "INTERLISP")
(FILECREATED " 1-Oct-87 13:40:16" {ERINYES}<LISPUSERS>LYRIC>HELPSYS.;4 16138  

      changes to%:  (FUNCTIONS IRM.LOAD-GRAPH)

      previous date%: "14-Aug-87 17:39:39" {ERINYES}<LISPUSERS>LYRIC>HELPSYS.;3)


(* "
Copyright (c) 1985, 1986, 1987 by Xerox Corporation.  All rights reserved.
")

(PRETTYCOMPRINT HELPSYSCOMS)

(RPAQQ HELPSYSCOMS ((FILES DINFO HASH) (RECORDS IRMREFERENCE) (DECLARE%: EVAL@COMPILE DONTCOPY (FILES (LOADCOMP) DINFO HASH)) (COMS (COMMANDS "man") (FNS HELPSYS IRM.LOOKUP IRM.SMART.LOOKUP IRM.RESET) (INITVARS (IRM.HOST&DIR) (IRM.HASHFILE.NAME)) (GLOBALVARS IRM.HOST&DIR IRM.HASHFILE.NAME) (DECLARE%: DONTEVAL@LOAD DOCOPY (P (MOVD (QUOTE HELPSYS) (QUOTE XHELPSYS) NIL T)))) (COMS (* ;;; "Interface to DInfo") (FNS IRM.GET.DINFOGRAPH IRM.DISPLAY.REF) (FUNCTIONS IRM.LOAD-GRAPH) (ADDVARS (DINFO.GRAPHS ("Interlisp-D Reference Manual" (IRM.GET.DINFOGRAPH T)))) (INITVARS (IRM.DINFOGRAPH)) (GLOBALVARS IRM.DINFOGRAPH) (DECLARE%: DONTEVAL@LOAD DOCOPY (P (COND (IRM.HOST&DIR (SETQ IRM.DINFOGRAPH (IRM.LOAD-GRAPH)))))) (* ;;; "Cross reference imageobj") (FNS IRM.DISPLAY.CREF IRM.CREF.BOX IRM.PUT.CREF IRM.GET.CREF IRM.CREF.BUTTONEVENTFN) (INITVARS (IRM.CREF.FONT (FONTCREATE (QUOTE MODERN) 8 (QUOTE MRR))) (\IRM.CREF.IMAGEFNS (IMAGEFNSCREATE (FUNCTION IRM.DISPLAY.CREF) (FUNCTION IRM.CREF.BOX) (FUNCTION IRM.PUT.CREF) (FUNCTION IRM.GET.CREF) (FUNCTION NILL) (FUNCTION IRM.CREF.BUTTONEVENTFN)))) (GLOBALVARS IRM.CREF.FONT \IRM.CREF.IMAGEFNS)) (COMS (* ;;; "Internal functions and variables") (FNS \IRM.GET.REF \IRM.SMART.REF \IRM.CHOOSE.REF \IRM.WILD.REF \IRM.WILDCARD \IRM.WILD.MATCH \IRM.GET.HASHFILE \IRM.GET.KEYWORDS) (INITVARS (\IRM.HASHFILE) (\IRM.KEYWORDS)) (GLOBALVARS \IRM.HASHFILE \IRM.KEYWORDS) (FUNCTIONS \IRM.AROUND-EXIT) (ADDVARS (AROUNDEXITFNS \IRM.AROUND-EXIT))))
)
(FILESLOAD DINFO HASH)
(DECLARE%: EVAL@COMPILE

(RECORD IRMREFERENCE (* ;; "A reference to something in the IRM.  There is a list of these for each entry in the index of the IRM.  Each element of the list corresponds to one of the page references.  These lists are stored under the ITEM in a hash file. ")
 (TYPE (* ; "The type of index entry -- typically a capitalized symbol in IL, eg. il:|Functions|.  Yes, it's ugly.") ITEM (* ; "The name indexed") PRIMARYFLG (* ; "True iff this is the primary reference for this name/type") NODE (* ; "The ID of the node in the IRM DInfo graph containing this reference") CH# (* ; "The character number of the beginning of the reference.  If unspecified we search for the first existence of NAME in the text of the node."))
 (SYSTEM))
)
(DECLARE%: EVAL@COMPILE DONTCOPY 
(FILESLOAD (LOADCOMP) DINFO HASH)
)
(DEFCOMMAND "man" (ENTRY) "Lookup ENTRY in the IRM." (IRM.SMART.LOOKUP ENTRY))
(DEFINEQ

(HELPSYS
(LAMBDA (FN PROPS) (* drc%: "20-Jan-86 18:05") (if (NOT IRM.HOST&DIR) then (PROMPTPRINT "HELPSYS is unavailable.  Set IRM.HOST&DIR.") NIL else (SELECTQ PROPS (ARGS (* HELPSYS is called by SMARTARGLIST to get args, but this implementation does not support that.) NIL) (FromDEdit (* from ? under EditCom) (IRM.LOOKUP (if (LISTP FN) then (CAR FN) else FN)) NIL) (NIL (* called by TTYIN <actually XHELPSYS is...> when FN...? <CR> is typed.) (if (FGETD FN) then (IRM.LOOKUP FN (QUOTE Function)) elseif (for MACRO.TYPE in MACROPROPS thereis (GETPROP FN MACRO.TYPE)) then (IRM.LOOKUP FN (QUOTE Macro) IRMWINDOW) elseif (SELECTQ (CAR (GETPROP FN (QUOTE CLISPWORD))) (NIL) (FORWORD (IRM.LOOKUP FN (QUOTE I.S.Operator))) (RECORDTRAN (IRM.LOOKUP FN (QUOTE RecordOperator))) (PROGN (IRM.LOOKUP FN NIL))) else (BEEP))) NIL)))
)

(IRM.LOOKUP
(LAMBDA (KEYWORD TYPE GRAPH SMARTFLG) (* drc%: "17-Jan-86 14:09") (* * Does a lookup in the IRM index for KEYWORD (optionally of TYPE) and visits the DInfo node in GRAPH containing the reference. If SMARTFLG is non-NIL, wildcards will be enabled. GRAPH defaults to IRM.DINFOGRAPH.) (LET* ((GRAPH (if (type? DINFOGRAPH GRAPH) then GRAPH else (IRM.GET.DINFOGRAPH))) (KEYWORD (MKATOM (U-CASE KEYWORD))) (TYPE (MKATOM TYPE)) (WINDOW (fetch (DINFOGRAPH WINDOW) of GRAPH)) (MONITORLOCK (DINFOGRAPHPROP GRAPH (QUOTE MONITORLOCK)))) (OPENW WINDOW) (if (OBTAIN.MONITORLOCK MONITORLOCK T) then (RESETLST (RESETSAVE (TTYDISPLAYSTREAM (GETPROMPTWINDOW WINDOW))) (RESETSAVE NIL (LIST (QUOTE RELEASE.MONITORLOCK) MONITORLOCK)) (LET ((REF (if SMARTFLG then (\IRM.SMART.REF KEYWORD WINDOW) else (\IRM.GET.REF KEYWORD TYPE WINDOW)))) (AND REF (IRM.DISPLAY.REF REF GRAPH)))) else (FLASHWINDOW WINDOW))))
)

(IRM.SMART.LOOKUP
(LAMBDA (KEYWORD GRAPH) (* drc%: " 6-Jan-86 14:50") (IRM.LOOKUP KEYWORD NIL GRAPH T)))

(IRM.RESET
(LAMBDA NIL (* drc%: "27-Jan-86 11:19") (if (type? DINFOGRAPH IRM.DINFOGRAPH) then (LET ((W (fetch (DINFOGRAPH WINDOW) of IRM.DINFOGRAPH))) (OPENW W) (CLOSEW W))) (SETQ IRM.DINFOGRAPH) (CLOSEHASHFILE \IRM.HASHFILE) (SETQ \IRM.HASHFILE) (SETQ \IRM.KEYWORDS))
)
)

(RPAQ? IRM.HOST&DIR )

(RPAQ? IRM.HASHFILE.NAME )
(DECLARE%: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS IRM.HOST&DIR IRM.HASHFILE.NAME)
)
(DECLARE%: DONTEVAL@LOAD DOCOPY 
(MOVD (QUOTE HELPSYS) (QUOTE XHELPSYS) NIL T)
)



(* ;;; "Interface to DInfo")

(DEFINEQ

(IRM.GET.DINFOGRAPH
(LAMBDA (FROM.BACKGROUND?) (* ; "Edited 14-Aug-87 17:31 by drc:") (* ;; "returns the DInfo graph for the IRM, ensuring that it has been setup.") (CL:UNLESS (TYPEP IRM.DINFOGRAPH (QUOTE DINFOGRAPH)) (* ;; "graph has not been loaded -- load it") (RESETFORM (TTYDISPLAYSTREAM PROMPTWINDOW) (SETQ IRM.DINFOGRAPH (IRM.LOAD-GRAPH)))) (CL:UNLESS (WINDOWP (fetch (DINFOGRAPH WINDOW) of IRM.DINFOGRAPH)) (* ;; "graph has not been set up -- set it up") (DINFO IRM.DINFOGRAPH (CREATEW (GETBOXREGION 540 400 NIL NIL NIL "Specify region for IRM DInfo window") "IRM DInfo Graph") T (NOT FROM.BACKGROUND?))) IRM.DINFOGRAPH)
)

(IRM.DISPLAY.REF
(LAMBDA (REF GRAPH) (* drc%: "18-Jan-86 17:17") (* * visit the DInfo node of GRAPH containing REF) (LET ((NODE (FASSOC (fetch (IRMREFERENCE NODE) of REF) (fetch (DINFOGRAPH NODELST) of GRAPH)))) (if NODE then (DINFO.UPDATE GRAPH NODE (LIST (fetch (IRMREFERENCE ITEM) of REF) (fetch (IRMREFERENCE CH#) of REF))) else (PRINTOUT (GETPROMPTWINDOW WINDOW) T "Node not found!"))))
)
)
(CL:DEFUN IRM.LOAD-GRAPH NIL (LET ((FILE (INFILEP (PACKFILENAME (QUOTE NAME) (QUOTE IRM) (QUOTE EXTENSION) (QUOTE DINFOGRAPH) (QUOTE BODY) IRM.HOST&DIR)))) (CL:IF FILE (DINFO.READ.GRAPH FILE) (PROG1 NIL (CL:WARN "IRM.DINFOGRAPH not found on ~S~%%Perhaps IL:IRM.HOST&DIR is set incorrectly" IRM.HOST&DIR)))))

(ADDTOVAR DINFO.GRAPHS ("Interlisp-D Reference Manual" (IRM.GET.DINFOGRAPH T)))

(RPAQ? IRM.DINFOGRAPH )
(DECLARE%: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS IRM.DINFOGRAPH)
)
(DECLARE%: DONTEVAL@LOAD DOCOPY 
(COND (IRM.HOST&DIR (SETQ IRM.DINFOGRAPH (IRM.LOAD-GRAPH))))
)



(* ;;; "Cross reference imageobj")

(DEFINEQ

(IRM.DISPLAY.CREF
(LAMBDA (IMAGEOBJ STREAM) (* drc%: " 7-Jan-86 13:41") (if (EQ (IMAGESTREAMTYPE STREAM) (QUOTE DISPLAY)) then (DSPFONT IRM.CREF.FONT STREAM) (LET* ((STRING (IMAGEOBJPROP IMAGEOBJ (QUOTE ITEM))) (STRINGREGION (STRINGREGION STRING STREAM)) (LEFT (ADD1 (fetch (REGION LEFT) of STRINGREGION))) (BOTTOM (fetch (REGION BOTTOM) of STRINGREGION)) (REGION (create REGION LEFT _ LEFT BOTTOM _ BOTTOM HEIGHT _ (IPLUS (fetch (REGION HEIGHT) of STRINGREGION) 2) WIDTH _ (IPLUS (fetch (REGION WIDTH) of STRINGREGION) 6))) (TOP (fetch (REGION TOP) of REGION)) (RIGHT (fetch (REGION RIGHT) of REGION))) (IMAGEOBJPROP IMAGEOBJ (QUOTE REGION) REGION) (CENTERPRINTINREGION STRING REGION STREAM) (DRAWLINE LEFT BOTTOM LEFT (SUB1 TOP) 1 (QUOTE INVERT) STREAM) (DRAWLINE LEFT TOP (SUB1 RIGHT) TOP 1 (QUOTE INVERT) STREAM) (DRAWLINE RIGHT TOP RIGHT (ADD1 BOTTOM) 1 (QUOTE INVERT) STREAM) (DRAWLINE RIGHT BOTTOM (ADD1 LEFT) BOTTOM 1 (QUOTE INVERT) STREAM)) else (PRIN1 "page X.XX" STREAM)))
)

(IRM.CREF.BOX
(LAMBDA (IMAGEOBJ STREAM CURRENTX RIGHTMARGIN) (* drc%: " 7-Jan-86 13:42") (LET ((TYPE (IMAGESTREAMTYPE STREAM))) (create IMAGEBOX XSIZE _ (SELECTQ TYPE (DISPLAY (IPLUS (STRINGWIDTH (IMAGEOBJPROP IMAGEOBJ (QUOTE ITEM)) IRM.CREF.FONT) 8)) (STRINGWIDTH "page X.XX" STREAM)) YSIZE _ (SELECTQ TYPE (DISPLAY (IPLUS (FONTHEIGHT IRM.CREF.FONT) 4)) (FONTHEIGHT STREAM)) YDESC _ (SELECTQ TYPE (DISPLAY 4) 0) XKERN _ 0)))
)

(IRM.PUT.CREF
(LAMBDA (IMAGEOBJ STREAM) (* drc%: " 7-Jan-86 22:09") (PRIN2 (CONS (IMAGEOBJPROP IMAGEOBJ (QUOTE ITEM)) (IMAGEOBJPROP IMAGEOBJ (QUOTE TYPE))) STREAM))
)

(IRM.GET.CREF
(LAMBDA (FILE TEXTSTREAM) (* drc%: " 2-Jan-86 17:45") (DECLARE (GLOBALVARS \IRM.CREF.IMAGEFNS)) (LET ((DATA (READ FILE)) (IMAGEOBJ (IMAGEOBJCREATE NIL \IRM.CREF.IMAGEFNS))) (IMAGEOBJPROP IMAGEOBJ (QUOTE ITEM) (CAR DATA)) (IMAGEOBJPROP IMAGEOBJ (QUOTE TYPE) (CDR DATA)) IMAGEOBJ))
)

(IRM.CREF.BUTTONEVENTFN
(LAMBDA (IMAGEOBJ WSTREAM SELECTION RELX RELY WINDOW TEXTSTREAM BUTTON) (* drc%: " 8-Jan-86 15:34") (* (INSPECT IMAGEOBJ)) (LET* ((BOUNDBOX (IMAGEOBJPROP IMAGEOBJ (QUOTE BOUNDBOX))) (WIDTH (fetch (IMAGEBOX XSIZE) of BOUNDBOX)) (HEIGHT (fetch (IMAGEBOX YSIZE) of BOUNDBOX)) (REGION (create REGION HEIGHT _ HEIGHT WIDTH _ WIDTH LEFT _ 0 BOTTOM _ 0))) (RESETFORM (TTYDISPLAYSTREAM (GETPROMPTWINDOW WINDOW)) (BLTSHADE BLACKSHADE WSTREAM 0 0 WIDTH HEIGHT (QUOTE INVERT)) (bind (N _ 0) (ITEM _ (IMAGEOBJPROP IMAGEOBJ (QUOTE ITEM))) (TYPE _ (IMAGEOBJPROP IMAGEOBJ (QUOTE TYPE))) until (OR (NOT (MOUSESTATE (OR LEFT MIDDLE))) (NOT (INSIDEP REGION (CURSORPOSITION NIL WSTREAM)))) do (BLOCK 100) (if (EQ (SETQ N (ADD1 N)) 10) then (printout T T "Will lookup " (IMAGEOBJPROP IMAGEOBJ (QUOTE ITEM)) (if TYPE then (CONCAT " as a " TYPE ".") else "."))) (GETMOUSESTATE) finally (CLEARW T) (if (INSIDEP REGION (CURSORPOSITION NIL WSTREAM)) then (ADD.PROCESS (LIST (QUOTE IRM.LOOKUP) (KWOTE ITEM) (KWOTE TYPE) (WINDOWPROP WINDOW (QUOTE DINFOGRAPH))) (QUOTE NAME) "IRM Cross Reference")) (BLTSHADE BLACKSHADE WSTREAM 0 0 WIDTH HEIGHT (QUOTE INVERT)) NIL))))
)
)

(RPAQ? IRM.CREF.FONT (FONTCREATE (QUOTE MODERN) 8 (QUOTE MRR)))

(RPAQ? \IRM.CREF.IMAGEFNS (IMAGEFNSCREATE (FUNCTION IRM.DISPLAY.CREF) (FUNCTION IRM.CREF.BOX) (FUNCTION IRM.PUT.CREF) (FUNCTION IRM.GET.CREF) (FUNCTION NILL) (FUNCTION IRM.CREF.BUTTONEVENTFN))
)
(DECLARE%: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS IRM.CREF.FONT \IRM.CREF.IMAGEFNS)
)



(* ;;; "Internal functions and variables")

(DEFINEQ

(\IRM.GET.REF
(LAMBDA (KEYWORD TYPE WINDOW) (* drc%: "18-Jan-86 17:13") (* * Returns an IRMREFERENCE for KEYWORD of optionally specified TYPE.) (\IRM.GET.HASHFILE) (* keywords in hashfile are all uppercased -- make's lookup case insensitive) (SETQ KEYWORD (MKATOM (U-CASE KEYWORD))) (LET (SAMEFLG REFS) (SETQ REFS (if (EQ KEYWORD (WINDOWPROP WINDOW (QUOTE PREVIOUS.KEYWORD))) then (* same keyword as last time, so fetch cached refs) (SETQ SAMEFLG T) (WINDOWPROP WINDOW (QUOTE IRM.REFS)) else (CLEARW T) (PRINTOUT T "Fetching reference(s) for " KEYWORD "...") (* hashfile contains a list of IRMREFERENCES for each keyword) (GETHASHFILE KEYWORD \IRM.HASHFILE))) (WINDOWPROP WINDOW (QUOTE PREVIOUS.KEYWORD) KEYWORD) (WINDOWPROP WINDOW (QUOTE IRM.REFS) REFS) (COND ((NULL REFS) (PRINTOUT T "None found.") NIL) ((NULL TYPE) (PRINTOUT T "OK.") (\IRM.CHOOSE.REF REFS KEYWORD)) ((for REF in REFS thereis (if (AND (EQ (fetch (IRMREFERENCE TYPE) of REF) TYPE) (fetch (IRMREFERENCE PRIMARYFLG) of REF)) then (PRINTOUT T "OK.") REF))) ((SETQ REFS (for REF in REFS join (if (EQ (fetch (IRMREFERENCE TYPE) of REF) TYPE) then (LIST REF) else NIL))) (PRINTOUT T "OK.") (\IRM.CHOOSE.REF REFS KEYWORD)) (T (PRINTOUT T "none found of type " TYPE ".") NIL))))
)

(\IRM.SMART.REF
(LAMBDA (KEYWORD WINDOW) (* drc%: "18-Jan-86 17:40") (* * Returns IRMREFERENCE for KEYWORD. Allows wildcards in KEYWORD, and will try spelling correction.) (if (while (SETQ POS (STRPOS "*" KEYWORD (AND POS (ADD1 POS)))) bind POS when (NEQ (NTHCHAR KEYWORD (SUB1 POS)) (QUOTE %')) do (RETURN T) finally (* if not doing wildcarding then remove quotes when preceding asterisks) (SETQ KEYWORD (PACK (for TAIL on (UNPACK KEYWORD) when (NOT (AND (EQ (CAR TAIL) (QUOTE %')) (EQ (CADR TAIL) (QUOTE *)))) collect (CAR TAIL)))) (RETURN NIL)) then (* there's an unquoted asterisk -- it's wildcardin' time!) (\IRM.WILD.REF KEYWORD WINDOW) elseif \IRM.KEYWORDS then (* we've got possible matches loaded, so try spelling correction) (RESETFORM (TTY.PROCESS (THIS.PROCESS)) (LET ((CORRECTED (MISSPELLED? KEYWORD 50 \IRM.KEYWORDS T))) (if CORRECTED then (\IRM.GET.REF CORRECTED NIL WINDOW) else (PRINTOUT T T KEYWORD " Not in IRM") NIL))) else (* default to normal lookup) (\IRM.GET.REF KEYWORD NIL WINDOW)))
)

(\IRM.CHOOSE.REF
(LAMBDA (REFS KEYWORD) (* drc%: " 8-Jan-86 15:23") (if (NULL (CDR REFS)) then (CAR REFS) else (MENU (create MENU CENTERFLG _ T TITLE _ (MKSTRING KEYWORD) ITEMS _ (for REF in REFS collect (LIST (LET ((TYPE (fetch (IRMREFERENCE TYPE) of REF))) (if (fetch (IRMREFERENCE PRIMARYFLG) of REF) then (PACK* "* " TYPE " *") else TYPE)) (KWOTE REF) (CONCAT "Lookup " KEYWORD " as " (fetch (IRMREFERENCE TYPE) of REF))))))))
)

(\IRM.WILD.REF
(LAMBDA (KEYWORD WINDOW) (* drc%: "18-Jan-86 17:04") (* * Return IRMREFERENCE matching wildcarded KEYWORD.) (OPENW WINDOW) (LET* (SAMEFLG (MATCHES (if (EQ KEYWORD (WINDOWPROP WINDOW (QUOTE IRM.WILD.KEYWORD))) then (* same as last time we wildcarded -- used cached matches.) (SETQ SAMEFLG T) (WINDOWPROP WINDOW (QUOTE IRM.MATCHES)) else (PROG2 (PRINTOUT (GETPROMPTWINDOW WINDOW) "...Matching wildcard(s)...") (\IRM.WILDCARD KEYWORD (\IRM.GET.KEYWORDS WINDOW)) (PRINTOUT (GETPROMPTWINDOW WINDOW) "OK"))))) (WINDOWPROP WINDOW (QUOTE IRM.WILD.KEYWORD) KEYWORD) (WINDOWPROP WINDOW (QUOTE IRM.MATCHES) MATCHES) (if MATCHES then (if (NULL (CDR MATCHES)) then (\IRM.GET.REF (CAR MATCHES) NIL WINDOW) else (OR SAMEFLG (WINDOWPROP WINDOW (QUOTE WILD.MENU) (create MENU ITEMS _ (for MATCH in MATCHES collect (LIST MATCH (KWOTE MATCH) (CONCAT "Will lookup " MATCH " in IRM if selected."))) CENTERFLG _ T TITLE _ KEYWORD))) (LET ((CHOICE (MENU (WINDOWPROP WINDOW (QUOTE WILD.MENU))))) (AND CHOICE (\IRM.GET.REF CHOICE NIL WINDOW)))) else (PRINTOUT (GETPROMPTWINDOW WINDOW) T "No matches found for " KEYWORD) NIL)))
)

(\IRM.WILDCARD
(LAMBDA (WILDATOM LIST) (* drc%: "18-Jan-86 17:00") (* * Returns those atoms in LIST which match WILDATOM.) (LET ((SCRATCH (CONS)) (WILDLIST (UNPACK WILDATOM))) (for ATOM in LIST when (\IRM.WILD.MATCH WILDLIST (DUNPACK ATOM SCRATCH)) collect ATOM)))
)

(\IRM.WILD.MATCH
(LAMBDA (WILDLIST LIST) (* drc%: "18-Jan-86 16:59") (* * predicate for whether wildcard containing WILDLIST matches LIST.) (COND ((AND (NULL WILDLIST) (NULL LIST))) ((AND (EQ (CAR WILDLIST) (QUOTE %')) (EQ (CADR WILDLIST) (QUOTE *))) (* found a quoted asterisk) (if (EQ (QUOTE *) (CAR LIST)) then (* and it matches) (\IRM.WILD.MATCH (CDDR WILDLIST) (CDR LIST)))) ((EQ (CAR WILDLIST) (QUOTE *)) (* found a real wildcard) (OR (NULL (CDR WILDLIST)) (for TAIL on LIST thereis (\IRM.WILD.MATCH (CDR WILDLIST) TAIL)))) ((EQ (CAR WILDLIST) (CAR LIST)) (* first chars match -- keep checking) (\IRM.WILD.MATCH (CDR WILDLIST) (CDR LIST))) (T NIL)))
)

(\IRM.GET.HASHFILE
(LAMBDA NIL (* drc%: "16-Dec-85 12:09") (OR (ARRAYP \IRM.HASHFILE) (SETQ \IRM.HASHFILE (OPENHASHFILE (OR IRM.HASHFILE.NAME (PACKFILENAME (QUOTE NAME) (QUOTE IRM) (QUOTE EXTENSION) (QUOTE HASHFILE) (QUOTE BODY) IRM.HOST&DIR)) (QUOTE INPUT)))))
)

(\IRM.GET.KEYWORDS
(LAMBDA (WINDOW QUIETFLG) (* drc%: "18-Jan-86 17:14") (* * keyword list is hidden in hashfile as its key is in lower case) (OR \IRM.KEYWORDS (PROGN (PRINTOUT (GETPROMPTWINDOW WINDOW) "Loading keyword list...") (\IRM.GET.HASHFILE) (SETQ \IRM.KEYWORDS (GETHASHFILE (QUOTE irm.keywords) (\IRM.GET.HASHFILE))))))
)
)

(RPAQ? \IRM.HASHFILE )

(RPAQ? \IRM.KEYWORDS )
(DECLARE%: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS \IRM.HASHFILE \IRM.KEYWORDS)
)
(CL:DEFUN \IRM.AROUND-EXIT (EVENT) (CASE EVENT ((BEFORELOGOUT BEFOREMAKESYS BEFORESYSOUT) (AND \IRM.HASHFILE (CLOSEHASHFILE \IRM.HASHFILE)))))

(ADDTOVAR AROUNDEXITFNS \IRM.AROUND-EXIT)
(PUTPROPS HELPSYS COPYRIGHT ("Xerox Corporation" 1985 1986 1987))
(DECLARE%: DONTCOPY
  (FILEMAP (NIL (2803 4933 (HELPSYS 2813 . 3640) (IRM.LOOKUP 3642 . 4545) (IRM.SMART.LOOKUP 4547 . 4655)
 (IRM.RESET 4657 . 4931)) (5193 6238 (IRM.GET.DINFOGRAPH 5203 . 5837) (IRM.DISPLAY.REF 5839 . 6236)) (
6866 9945 (IRM.DISPLAY.CREF 6876 . 7865) (IRM.CREF.BOX 7867 . 8298) (IRM.PUT.CREF 8300 . 8470) (
IRM.GET.CREF 8472 . 8771) (IRM.CREF.BUTTONEVENTFN 8773 . 9943)) (10350 15724 (\IRM.GET.REF 10360 . 
11605) (\IRM.SMART.REF 11607 . 12621) (\IRM.CHOOSE.REF 12623 . 13059) (\IRM.WILD.REF 13061 . 14183) (
\IRM.WILDCARD 14185 . 14455) (\IRM.WILD.MATCH 14457 . 15118) (\IRM.GET.HASHFILE 15120 . 15387) (
\IRM.GET.KEYWORDS 15389 . 15722)))))
STOP
\ No newline at end of file
+(DEFINE-FILE-INFO READTABLE "INTERLISP" PACKAGE "INTERLISP")
(FILECREATED "27-Nov-2020 09:47:44" {DSK}<home>larry>ilisp>medley>lispusers>HELPSYS.;4 28861  

      changes to%:  (FNS IRM.LOOKUP)

      previous date%: "27-Nov-2020 08:54:23" {DSK}<home>larry>ilisp>medley>lispusers>HELPSYS.;2)


(* ; "
Copyright (c) 1985, 1986, 1987, 2020 by Xerox Corporation.  All rights reserved.
")

(PRETTYCOMPRINT HELPSYSCOMS)

(RPAQQ HELPSYSCOMS
       [(FILES DINFO HASH)
        (RECORDS IRMREFERENCE)
        (DECLARE%: EVAL@COMPILE DONTCOPY (FILES (LOADCOMP)
                                                DINFO HASH))
        [COMS (COMMANDS "man")
              (FNS HELPSYS IRM.LOOKUP IRM.SMART.LOOKUP IRM.RESET)
              (INITVARS (IRM.HOST&DIR)
                     (IRM.HASHFILE.NAME))
              (GLOBALVARS IRM.HOST&DIR IRM.HASHFILE.NAME)
              (DECLARE%: DONTEVAL@LOAD DOCOPY (P (MOVD 'HELPSYS 'XHELPSYS NIL T]
        (COMS 

(* ;;; "Interface to DInfo")

              (FNS IRM.GET.DINFOGRAPH IRM.DISPLAY.REF)
              (FUNCTIONS IRM.LOAD-GRAPH)
              [ADDVARS (DINFO.GRAPHS ("Interlisp-D Reference Manual" (IRM.GET.DINFOGRAPH T]
              (INITVARS (IRM.DINFOGRAPH))
              (GLOBALVARS IRM.DINFOGRAPH)
              [DECLARE%: DONTEVAL@LOAD DOCOPY (P (COND (IRM.HOST&DIR (SETQ IRM.DINFOGRAPH (
                                                                                       IRM.LOAD-GRAPH
                                                                                           ]
              

(* ;;; "Cross reference imageobj")

              (FNS IRM.DISPLAY.CREF IRM.CREF.BOX IRM.PUT.CREF IRM.GET.CREF IRM.CREF.BUTTONEVENTFN)
              [INITVARS (IRM.CREF.FONT (FONTCREATE 'MODERN 8 'MRR))
                     (\IRM.CREF.IMAGEFNS (IMAGEFNSCREATE (FUNCTION IRM.DISPLAY.CREF)
                                                (FUNCTION IRM.CREF.BOX)
                                                (FUNCTION IRM.PUT.CREF)
                                                (FUNCTION IRM.GET.CREF)
                                                (FUNCTION NILL)
                                                (FUNCTION IRM.CREF.BUTTONEVENTFN]
              (GLOBALVARS IRM.CREF.FONT \IRM.CREF.IMAGEFNS))
        (COMS 

(* ;;; "Internal functions and variables")

              (FNS \IRM.GET.REF \IRM.SMART.REF \IRM.CHOOSE.REF \IRM.WILD.REF \IRM.WILDCARD 
                   \IRM.WILD.MATCH \IRM.GET.HASHFILE \IRM.GET.KEYWORDS)
              (INITVARS (\IRM.HASHFILE)
                     (\IRM.KEYWORDS))
              (GLOBALVARS \IRM.HASHFILE \IRM.KEYWORDS)
              (FUNCTIONS \IRM.AROUND-EXIT)
              (ADDVARS (AROUNDEXITFNS \IRM.AROUND-EXIT])

(FILESLOAD DINFO HASH)
(DECLARE%: EVAL@COMPILE

(RECORD IRMREFERENCE 
                         (* ;; "A reference to something in the IRM.  There is a list of these for each entry in the index of the IRM.  Each element of the list corresponds to one of the page references.  These lists are stored under the ITEM in a hash file. ")

                         (TYPE                               (* ; "The type of index entry -- typically a capitalized symbol in IL, eg. il:|Functions|.  Yes, it's ugly.")
                               ITEM                          (* ; "The name indexed")
                               PRIMARYFLG                    (* ; 
                                        "True iff this is the primary reference for this name/type")
                               NODE                          (* ; 
                              "The ID of the node in the IRM DInfo graph containing this reference")
                               CH#                           (* ; "The character number of the beginning of the reference.  If unspecified we search for the first existence of NAME in the text of the node.")
                               )
                         (SYSTEM))
)
(DECLARE%: EVAL@COMPILE DONTCOPY 

(FILESLOAD (LOADCOMP)
       DINFO HASH)
)

(DEFCOMMAND "man" (ENTRY) "Lookup ENTRY in the IRM."
   (IRM.SMART.LOOKUP ENTRY))
(DEFINEQ

(HELPSYS
  [LAMBDA (FN PROPS)                                         (* drc%: "20-Jan-86 18:05")
    (if (NOT IRM.HOST&DIR)
        then (PROMPTPRINT "HELPSYS is unavailable.  Set IRM.HOST&DIR.")
              NIL
      else (SELECTQ PROPS
                   (ARGS 

         (* HELPSYS is called by SMARTARGLIST to get args, but this implementation does 
       not support that.)

                         NIL)
                   (FromDEdit                                (* from ? under EditCom)
                              (IRM.LOOKUP (if (LISTP FN)
                                                  then (CAR FN)
                                                else FN))
                              NIL)
                   (NIL                                      (* called by TTYIN <actually 
                                                           XHELPSYS is...> when FN...? <CR> is 
                                                           typed.)
                        (if (FGETD FN)
                            then (IRM.LOOKUP FN 'Function)
                          elseif (for MACRO.TYPE in MACROPROPS
                                        thereis (GETPROP FN MACRO.TYPE))
                            then (IRM.LOOKUP FN 'Macro IRMWINDOW)
                          elseif (SELECTQ (CAR (GETPROP FN 'CLISPWORD))
                                         (NIL)
                                         (FORWORD (IRM.LOOKUP FN 'I.S.Operator))
                                         (RECORDTRAN (IRM.LOOKUP FN 'RecordOperator))
                                         (PROGN (IRM.LOOKUP FN NIL)))
                          else (BEEP)))
                   NIL])

(IRM.LOOKUP
  [LAMBDA (KEYWORD TYPE GRAPH SMARTFLG)                (* ; "Edited 27-Nov-2020 08:45 by larry")
                                                             (* drc%: "17-Jan-86 14:09")

         (* * Does a lookup in the IRM index for KEYWORD
       (optionally of TYPE) and visits the DInfo node in GRAPH containing the 
       reference. If SMARTFLG is non-NIL, wildcards will be enabled.
       GRAPH defaults to IRM.DINFOGRAPH.)

    (LET* [(GRAPH (if (type? DINFOGRAPH GRAPH)
                      then GRAPH
                    else (IRM.GET.DINFOGRAPH)))
           (KEYWORD (MKATOM (U-CASE KEYWORD)))
           (TYPE (MKATOM TYPE))
           (WINDOW (fetch (DINFOGRAPH WINDOW) of GRAPH))
           (MONITORLOCK (DINFOGRAPHPROP GRAPH 'MONITORLOCK]
          (OPENW WINDOW)
          (if (OBTAIN.MONITORLOCK MONITORLOCK T)
              then (RESETLST
                           (RESETSAVE (TTYDISPLAYSTREAM (GETPROMPTWINDOW WINDOW)))
                           (RESETSAVE NIL (LIST 'RELEASE.MONITORLOCK MONITORLOCK))
                           (LET [(REF (if SMARTFLG
                                          then (\IRM.SMART.REF KEYWORD WINDOW)
                                        else (\IRM.GET.REF KEYWORD TYPE WINDOW]
                                (AND REF (IRM.DISPLAY.REF REF GRAPH))))
            else (FLASHWINDOW WINDOW])

(IRM.SMART.LOOKUP
  [LAMBDA (KEYWORD GRAPH)                                    (* drc%: " 6-Jan-86 14:50")
    (IRM.LOOKUP KEYWORD NIL GRAPH T])

(IRM.RESET
  [LAMBDA NIL                                                (* drc%: "27-Jan-86 11:19")
    (if (type? DINFOGRAPH IRM.DINFOGRAPH)
        then (LET ((W (fetch (DINFOGRAPH WINDOW) of IRM.DINFOGRAPH)))
                      (OPENW W)
                      (CLOSEW W)))
    (SETQ IRM.DINFOGRAPH)
    (CLOSEHASHFILE \IRM.HASHFILE)
    (SETQ \IRM.HASHFILE)
    (SETQ \IRM.KEYWORDS])
)

(RPAQ? IRM.HOST&DIR )

(RPAQ? IRM.HASHFILE.NAME )
(DECLARE%: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS IRM.HOST&DIR IRM.HASHFILE.NAME)
)
(DECLARE%: DONTEVAL@LOAD DOCOPY 

(MOVD 'HELPSYS 'XHELPSYS NIL T)
)



(* ;;; "Interface to DInfo")

(DEFINEQ

(IRM.GET.DINFOGRAPH
  [LAMBDA (FROM.BACKGROUND?)                                 (* ; "Edited 14-Aug-87 17:31 by drc:")

    (* ;; "returns the DInfo graph for the IRM, ensuring that it has been setup.")

    (CL:UNLESS (TYPEP IRM.DINFOGRAPH 'DINFOGRAPH)

        (* ;; "graph has not been loaded -- load it")

        (RESETFORM (TTYDISPLAYSTREAM PROMPTWINDOW)
               (SETQ IRM.DINFOGRAPH (IRM.LOAD-GRAPH))))
    (CL:UNLESS (WINDOWP (fetch (DINFOGRAPH WINDOW) of IRM.DINFOGRAPH))

        (* ;; "graph has not been set up -- set it up")

        (DINFO IRM.DINFOGRAPH (CREATEW (GETBOXREGION 540 400 NIL NIL NIL 
                                              "Specify region for IRM DInfo window")
                                     "IRM DInfo Graph")
               T
               (NOT FROM.BACKGROUND?)))
    IRM.DINFOGRAPH])

(IRM.DISPLAY.REF
  [LAMBDA (REF GRAPH)                                        (* drc%: "18-Jan-86 17:17")

         (* * visit the DInfo node of GRAPH containing REF)

    (LET [(NODE (FASSOC (fetch (IRMREFERENCE NODE) of REF)
                       (fetch (DINFOGRAPH NODELST) of GRAPH]
         (if NODE
             then (DINFO.UPDATE GRAPH NODE (LIST (fetch (IRMREFERENCE ITEM) of REF)
                                                     (fetch (IRMREFERENCE CH#) of REF)))
           else (PRINTOUT (GETPROMPTWINDOW WINDOW)
                           T "Node not found!"])
)

(CL:DEFUN IRM.LOAD-GRAPH ()
   [LET [(FILE (INFILEP (PACKFILENAME 'NAME 'IRM 'EXTENSION 'DINFOGRAPH 'BODY IRM.HOST&DIR]
        (CL:IF FILE
            (DINFO.READ.GRAPH FILE)
            (PROG1 NIL (CL:WARN 
                        "IRM.DINFOGRAPH not found on ~S~%%Perhaps IL:IRM.HOST&DIR is set incorrectly"
                              IRM.HOST&DIR)))])

(ADDTOVAR DINFO.GRAPHS ("Interlisp-D Reference Manual" (IRM.GET.DINFOGRAPH T)))

(RPAQ? IRM.DINFOGRAPH )
(DECLARE%: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS IRM.DINFOGRAPH)
)
(DECLARE%: DONTEVAL@LOAD DOCOPY 

[COND
   (IRM.HOST&DIR (SETQ IRM.DINFOGRAPH (IRM.LOAD-GRAPH]
)



(* ;;; "Cross reference imageobj")

(DEFINEQ

(IRM.DISPLAY.CREF
  [LAMBDA (IMAGEOBJ STREAM)                                  (* drc%: " 7-Jan-86 13:41")
    (if (EQ (IMAGESTREAMTYPE STREAM)
                'DISPLAY)
        then (DSPFONT IRM.CREF.FONT STREAM)
              (LET* ((STRING (IMAGEOBJPROP IMAGEOBJ 'ITEM))
                     (STRINGREGION (STRINGREGION STRING STREAM))
                     (LEFT (ADD1 (fetch (REGION LEFT) of STRINGREGION)))
                     (BOTTOM (fetch (REGION BOTTOM) of STRINGREGION))
                     (REGION (create REGION
                                    LEFT _ LEFT
                                    BOTTOM _ BOTTOM
                                    HEIGHT _ (IPLUS (fetch (REGION HEIGHT) of STRINGREGION)
                                                    2)
                                    WIDTH _ (IPLUS (fetch (REGION WIDTH) of STRINGREGION)
                                                   6)))
                     (TOP (fetch (REGION TOP) of REGION))
                     (RIGHT (fetch (REGION RIGHT) of REGION)))
                    (IMAGEOBJPROP IMAGEOBJ 'REGION REGION)
                    (CENTERPRINTINREGION STRING REGION STREAM)
                    (DRAWLINE LEFT BOTTOM LEFT (SUB1 TOP)
                           1
                           'INVERT STREAM)
                    (DRAWLINE LEFT TOP (SUB1 RIGHT)
                           TOP 1 'INVERT STREAM)
                    (DRAWLINE RIGHT TOP RIGHT (ADD1 BOTTOM)
                           1
                           'INVERT STREAM)
                    (DRAWLINE RIGHT BOTTOM (ADD1 LEFT)
                           BOTTOM 1 'INVERT STREAM))
      else (PRIN1 "page X.XX" STREAM])

(IRM.CREF.BOX
  [LAMBDA (IMAGEOBJ STREAM CURRENTX RIGHTMARGIN)             (* drc%: " 7-Jan-86 13:42")
    (LET ((TYPE (IMAGESTREAMTYPE STREAM)))
         (create IMAGEBOX
                XSIZE _ (SELECTQ TYPE
                            (DISPLAY (IPLUS (STRINGWIDTH (IMAGEOBJPROP IMAGEOBJ 'ITEM)
                                                   IRM.CREF.FONT)
                                            8))
                            (STRINGWIDTH "page X.XX" STREAM))
                YSIZE _ (SELECTQ TYPE
                            (DISPLAY (IPLUS (FONTHEIGHT IRM.CREF.FONT)
                                            4))
                            (FONTHEIGHT STREAM))
                YDESC _ (SELECTQ TYPE
                            (DISPLAY 4)
                            0)
                XKERN _ 0])

(IRM.PUT.CREF
  [LAMBDA (IMAGEOBJ STREAM)                                  (* drc%: " 7-Jan-86 22:09")
    (PRIN2 (CONS (IMAGEOBJPROP IMAGEOBJ 'ITEM)
                 (IMAGEOBJPROP IMAGEOBJ 'TYPE))
           STREAM])

(IRM.GET.CREF
  [LAMBDA (FILE TEXTSTREAM)                                  (* drc%: " 2-Jan-86 17:45")
    (DECLARE (GLOBALVARS \IRM.CREF.IMAGEFNS))
    (LET ((DATA (READ FILE))
          (IMAGEOBJ (IMAGEOBJCREATE NIL \IRM.CREF.IMAGEFNS)))
         (IMAGEOBJPROP IMAGEOBJ 'ITEM (CAR DATA))
         (IMAGEOBJPROP IMAGEOBJ 'TYPE (CDR DATA))
         IMAGEOBJ])

(IRM.CREF.BUTTONEVENTFN
  [LAMBDA (IMAGEOBJ WSTREAM SELECTION RELX RELY WINDOW TEXTSTREAM BUTTON)
                                                             (* drc%: " 8-Jan-86 15:34")
                                                             (* (INSPECT IMAGEOBJ))
    (LET* ((BOUNDBOX (IMAGEOBJPROP IMAGEOBJ 'BOUNDBOX))
           (WIDTH (fetch (IMAGEBOX XSIZE) of BOUNDBOX))
           (HEIGHT (fetch (IMAGEBOX YSIZE) of BOUNDBOX))
           (REGION (create REGION
                          HEIGHT _ HEIGHT
                          WIDTH _ WIDTH
                          LEFT _ 0
                          BOTTOM _ 0)))
          (RESETFORM (TTYDISPLAYSTREAM (GETPROMPTWINDOW WINDOW))
                 (BLTSHADE BLACKSHADE WSTREAM 0 0 WIDTH HEIGHT 'INVERT)
                 (bind (N _ 0)
                        (ITEM _ (IMAGEOBJPROP IMAGEOBJ 'ITEM))
                        (TYPE _ (IMAGEOBJPROP IMAGEOBJ 'TYPE))
                    until [OR (NOT (MOUSESTATE (OR LEFT MIDDLE)))
                                  (NOT (INSIDEP REGION (CURSORPOSITION NIL WSTREAM]
                    do (BLOCK 100)
                          (if (EQ (SETQ N (ADD1 N))
                                      10)
                              then (printout T T "Will lookup " (IMAGEOBJPROP IMAGEOBJ
                                                                           'ITEM)
                                              (if TYPE
                                                  then (CONCAT " as a " TYPE ".")
                                                else ".")))
                          (GETMOUSESTATE) finally (CLEARW T)
                                                (if (INSIDEP REGION (CURSORPOSITION NIL WSTREAM))
                                                    then (ADD.PROCESS (LIST 'IRM.LOOKUP
                                                                                (KWOTE ITEM)
                                                                                (KWOTE TYPE)
                                                                                (WINDOWPROP
                                                                                 WINDOW
                                                                                 'DINFOGRAPH))
                                                                    'NAME "IRM Cross Reference"))
                                                (BLTSHADE BLACKSHADE WSTREAM 0 0 WIDTH HEIGHT
                                                       'INVERT)
                                                NIL])
)

(RPAQ? IRM.CREF.FONT (FONTCREATE 'MODERN 8 'MRR))

(RPAQ? \IRM.CREF.IMAGEFNS (IMAGEFNSCREATE (FUNCTION IRM.DISPLAY.CREF)
                                     (FUNCTION IRM.CREF.BOX)
                                     (FUNCTION IRM.PUT.CREF)
                                     (FUNCTION IRM.GET.CREF)
                                     (FUNCTION NILL)
                                     (FUNCTION IRM.CREF.BUTTONEVENTFN)))
(DECLARE%: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS IRM.CREF.FONT \IRM.CREF.IMAGEFNS)
)



(* ;;; "Internal functions and variables")

(DEFINEQ

(\IRM.GET.REF
  [LAMBDA (KEYWORD TYPE WINDOW)                              (* drc%: "18-Jan-86 17:13")

         (* * Returns an IRMREFERENCE for KEYWORD of optionally specified TYPE.)

    (\IRM.GET.HASHFILE)                                  (* keywords in hashfile are all 
                                                           uppercased -- make's lookup case 
                                                           insensitive)
    (SETQ KEYWORD (MKATOM (U-CASE KEYWORD)))
    (LET (SAMEFLG REFS)
         (SETQ REFS (if (EQ KEYWORD (WINDOWPROP WINDOW 'PREVIOUS.KEYWORD))
                        then                             (* same keyword as last time, so 
                                                           fetch cached refs)
                              (SETQ SAMEFLG T)
                              (WINDOWPROP WINDOW 'IRM.REFS)
                      else (CLEARW T)
                            (PRINTOUT T "Fetching reference(s) for " KEYWORD "...") 
                                                             (* hashfile contains a list of 
                                                           IRMREFERENCES for each keyword)
                            (GETHASHFILE KEYWORD \IRM.HASHFILE)))
         (WINDOWPROP WINDOW 'PREVIOUS.KEYWORD KEYWORD)
         (WINDOWPROP WINDOW 'IRM.REFS REFS)
         (COND
            ((NULL REFS)
             (PRINTOUT T "None found.")
             NIL)
            ((NULL TYPE)
             (PRINTOUT T "OK.")
             (\IRM.CHOOSE.REF REFS KEYWORD))
            ((for REF in REFS thereis (if (AND (EQ (fetch (IRMREFERENCE TYPE)
                                                                      of REF)
                                                                   TYPE)
                                                               (fetch (IRMREFERENCE PRIMARYFLG)
                                                                  of REF))
                                                      then (PRINTOUT T "OK.")
                                                            REF)))
            ((SETQ REFS (for REF in REFS join (if (EQ (fetch (IRMREFERENCE TYPE)
                                                                         of REF)
                                                                      TYPE)
                                                              then (LIST REF)
                                                            else NIL)))
             (PRINTOUT T "OK.")
             (\IRM.CHOOSE.REF REFS KEYWORD))
            (T (PRINTOUT T "none found of type " TYPE ".")
               NIL])

(\IRM.SMART.REF
  [LAMBDA (KEYWORD WINDOW)                                   (* drc%: "18-Jan-86 17:40")

         (* * Returns IRMREFERENCE for KEYWORD. Allows wildcards in KEYWORD, and will 
       try spelling correction.)

    (if (while [SETQ POS (STRPOS "*" KEYWORD (AND POS (ADD1 POS] bind POS
               when (NEQ (NTHCHAR KEYWORD (SUB1 POS))
                             '%') do (RETURN T)
               finally                                   (* if not doing wildcarding then 
                                                           remove quotes when preceding 
                                                           asterisks)
                     [SETQ KEYWORD (PACK (for TAIL on (UNPACK KEYWORD)
                                            when [NOT (AND (EQ (CAR TAIL)
                                                                   '%')
                                                               (EQ (CADR TAIL)
                                                                   '*] collect (CAR TAIL]
                     (RETURN NIL))
        then                                             (* there's an unquoted asterisk --
                                                           it's wildcardin' time!)
              (\IRM.WILD.REF KEYWORD WINDOW)
      elseif \IRM.KEYWORDS
        then                                             (* we've got possible matches 
                                                           loaded, so try spelling correction)
              (RESETFORM (TTY.PROCESS (THIS.PROCESS))
                     (LET ((CORRECTED (MISSPELLED? KEYWORD 50 \IRM.KEYWORDS T)))
                          (if CORRECTED
                              then (\IRM.GET.REF CORRECTED NIL WINDOW)
                            else (PRINTOUT T T KEYWORD " Not in IRM")
                                  NIL)))
      else                                               (* default to normal lookup)
            (\IRM.GET.REF KEYWORD NIL WINDOW])

(\IRM.CHOOSE.REF
  [LAMBDA (REFS KEYWORD)                                     (* drc%: " 8-Jan-86 15:23")
    (if (NULL (CDR REFS))
        then (CAR REFS)
      else (MENU (create MENU
                            CENTERFLG _ T
                            TITLE _ (MKSTRING KEYWORD)
                            ITEMS _ (for REF in REFS
                                       collect (LIST (LET ((TYPE (fetch (IRMREFERENCE TYPE)
                                                                        of REF)))
                                                              (if (fetch (IRMREFERENCE 
                                                                                        PRIMARYFLG)
                                                                         of REF)
                                                                  then (PACK* "* " TYPE " *")
                                                                else TYPE))
                                                         (KWOTE REF)
                                                         (CONCAT "Lookup " KEYWORD " as "
                                                                (fetch (IRMREFERENCE TYPE)
                                                                   of REF])

(\IRM.WILD.REF
  [LAMBDA (KEYWORD WINDOW)                                   (* drc%: "18-Jan-86 17:04")

         (* * Return IRMREFERENCE matching wildcarded KEYWORD.)

    (OPENW WINDOW)
    (LET* [SAMEFLG (MATCHES (if (EQ KEYWORD (WINDOWPROP WINDOW 'IRM.WILD.KEYWORD))
                                then                     (* same as last time we wildcarded 
                                                           -- used cached matches.)
                                      (SETQ SAMEFLG T)
                                      (WINDOWPROP WINDOW 'IRM.MATCHES)
                              else (PROG2 (PRINTOUT (GETPROMPTWINDOW WINDOW)
                                                     "...Matching wildcard(s)...")
                                              (\IRM.WILDCARD KEYWORD (\IRM.GET.KEYWORDS
                                                                          WINDOW))
                                              (PRINTOUT (GETPROMPTWINDOW WINDOW)
                                                     "OK"]
          (WINDOWPROP WINDOW 'IRM.WILD.KEYWORD KEYWORD)
          (WINDOWPROP WINDOW 'IRM.MATCHES MATCHES)
          (if MATCHES
              then [if (NULL (CDR MATCHES))
                           then (\IRM.GET.REF (CAR MATCHES)
                                           NIL WINDOW)
                         else (OR SAMEFLG (WINDOWPROP WINDOW 'WILD.MENU
                                                     (create MENU
                                                            ITEMS _
                                                            (for MATCH in MATCHES
                                                               collect (LIST MATCH (KWOTE MATCH)
                                                                                 (CONCAT 
                                                                                       "Will lookup "
                                                                                        MATCH 
                                                                               " in IRM if selected."
                                                                                        )))
                                                            CENTERFLG _ T
                                                            TITLE _ KEYWORD)))
                               (LET [(CHOICE (MENU (WINDOWPROP WINDOW 'WILD.MENU]
                                    (AND CHOICE (\IRM.GET.REF CHOICE NIL WINDOW]
            else (PRINTOUT (GETPROMPTWINDOW WINDOW)
                            T "No matches found for " KEYWORD)
                  NIL])

(\IRM.WILDCARD
  [LAMBDA (WILDATOM LIST)                                    (* drc%: "18-Jan-86 17:00")

         (* * Returns those atoms in LIST which match WILDATOM.)

    (LET ((SCRATCH (CONS))
          (WILDLIST (UNPACK WILDATOM)))
         (for ATOM in LIST when (\IRM.WILD.MATCH WILDLIST (DUNPACK ATOM SCRATCH))
            collect ATOM])

(\IRM.WILD.MATCH
  [LAMBDA (WILDLIST LIST)                                    (* drc%: "18-Jan-86 16:59")

         (* * predicate for whether wildcard containing WILDLIST matches LIST.)

    (COND
       ((AND (NULL WILDLIST)
             (NULL LIST)))
       [(AND (EQ (CAR WILDLIST)
                 '%')
             (EQ (CADR WILDLIST)
                 '*))                                        (* found a quoted asterisk)
        (if (EQ '* (CAR LIST))
            then                                         (* and it matches)
                  (\IRM.WILD.MATCH (CDDR WILDLIST)
                         (CDR LIST]
       [(EQ (CAR WILDLIST)
            '*)                                              (* found a real wildcard)
        (OR (NULL (CDR WILDLIST))
            (for TAIL on LIST thereis (\IRM.WILD.MATCH (CDR WILDLIST)
                                                         TAIL]
       ((EQ (CAR WILDLIST)
            (CAR LIST))                                      (* first chars match --
                                                           keep checking)
        (\IRM.WILD.MATCH (CDR WILDLIST)
               (CDR LIST)))
       (T NIL])

(\IRM.GET.HASHFILE
  [LAMBDA NIL                                                (* drc%: "16-Dec-85 12:09")
    (OR (ARRAYP \IRM.HASHFILE)
        (SETQ \IRM.HASHFILE (OPENHASHFILE (OR IRM.HASHFILE.NAME (PACKFILENAME 'NAME 'IRM 'EXTENSION
                                                                       'HASHFILE
                                                                       'BODY IRM.HOST&DIR))
                                   'INPUT])

(\IRM.GET.KEYWORDS
  [LAMBDA (WINDOW QUIETFLG)                                  (* drc%: "18-Jan-86 17:14")

         (* * keyword list is hidden in hashfile as its key is in lower case)

    (OR \IRM.KEYWORDS (PROGN (PRINTOUT (GETPROMPTWINDOW WINDOW)
                                    "Loading keyword list...")
                             (\IRM.GET.HASHFILE)
                             (SETQ \IRM.KEYWORDS (GETHASHFILE 'irm.keywords (\IRM.GET.HASHFILE])
)

(RPAQ? \IRM.HASHFILE )

(RPAQ? \IRM.KEYWORDS )
(DECLARE%: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS \IRM.HASHFILE \IRM.KEYWORDS)
)

(CL:DEFUN \IRM.AROUND-EXIT (EVENT)
   (CASE EVENT
       ((BEFORELOGOUT BEFOREMAKESYS BEFORESYSOUT) (AND \IRM.HASHFILE (CLOSEHASHFILE \IRM.HASHFILE)))))

(ADDTOVAR AROUNDEXITFNS \IRM.AROUND-EXIT)
(PUTPROPS HELPSYS COPYRIGHT ("Xerox Corporation" 1985 1986 1987 2020))
(DECLARE%: DONTCOPY
  (FILEMAP (NIL (4149 8000 (HELPSYS 4159 . 5963) (IRM.LOOKUP 5965 . 7421) (IRM.SMART.LOOKUP 7423 . 7579)
 (IRM.RESET 7581 . 7998)) (8247 9766 (IRM.GET.DINFOGRAPH 8257 . 9128) (IRM.DISPLAY.REF 9130 . 9764)) (
9768 10130 (IRM.LOAD-GRAPH 9768 . 10130)) (10455 16304 (IRM.DISPLAY.CREF 10465 . 12208) (IRM.CREF.BOX 
12210 . 13037) (IRM.PUT.CREF 13039 . 13264) (IRM.GET.CREF 13266 . 13637) (IRM.CREF.BUTTONEVENTFN 13639
 . 16302)) (16879 28427 (\IRM.GET.REF 16889 . 19643) (\IRM.SMART.REF 19645 . 21766) (\IRM.CHOOSE.REF 
21768 . 23114) (\IRM.WILD.REF 23116 . 25858) (\IRM.WILDCARD 25860 . 26238) (\IRM.WILD.MATCH 26240 . 
27478) (\IRM.GET.HASHFILE 27480 . 27943) (\IRM.GET.KEYWORDS 27945 . 28425)) (28564 28720 (
\IRM.AROUND-EXIT 28564 . 28720)))))
STOP
\ No newline at end of file
diff --git a/run-medley b/run-medley
index cab615f9..9d2315b5 100755
--- a/run-medley
+++ b/run-medley
@@ -3,28 +3,24 @@
 # Run Medley
 #
 # Syntax: run-medley [options] [sysout name]
-# Options
+# Options:
+#  -nogreet
+#  -greet <greetfile>
 
-#  -nogreet                          ; just run sysout
-#  -greet    greetfile               ; which greetfile to use
+# current limit 65536*32 bits
+#  -g[eometry]   <width>x<height>
+#  -sc[reensize] <width>x<height>
 
-#  -geometry pixelgeometry
-#  -screensize pixelgeometry
+#  -d[isplay] <xdisplay-device>
+#  -vmem <savevmemfilename>
 
-#  -display xdisplay-device    e.g. :0
-
-#   -vmem savevmemfilename
-
-# current limits the size of the screen to
-# 65536*32 bits so 1600x1200 will do
 #
 # Environment variables set
 # Directory variables are accessible from Lisp via UNIX-GETENV
 
 # LDESRCESYSOUT         SYSOUT full-file name you want to run
-# LDESOURCESYSOUT       
 # LDEDESTSYSOUT         name for destination of SAVEVM/LOGOUT
-# MEDLEYDIR
+# MEDLEYDIR             used by init file to set other path variables
 
 
 if [ -z "$MEDLEYDIR" ] ; then export MEDLEYDIR=`pwd`; fi
@@ -33,6 +29,8 @@ if [ ! -d $MEDLEYDIR/loadups ] ; then
    exit 1
 fi
 
+## should allow for local install?
+
 if [ -z "$MAIKODIR" ] ; then
    export MAIKODIR="$MEDLEYDIR/../maiko"
    if [ ! -d "$MAIKODIR"/bin ] ; then
@@ -57,37 +55,54 @@ while [ "$#" -ne 0 ]; do
             export LDEINIT="$2"
             shift
             ;;
-        "-geometry")
+        "-g")
+	    geometry="-g $2"
+	    shift
+	    ;;
+	"-geometry")
             geometry="-g $2"
             shift
             ;;
+    	"-sc")
+	    screensize="-sc 2"
+	    shift
+	    ;;
 	"-screensize")
-            screensize="-sc $2"
+	    screensize="-sc $2"
             shift
             ;;
-        "-display")
+	"-display")
             export DISPLAY=$2
             shift
             ;;
+	"-d")
+	    export DISPLAY=$2
+	    ;;
 	"-vmem")
 	    LDEDESTSYSOUT=$2
 	    shift
 	    ;;
+	"-full")
+	    export LDESRCSYSOUT="$MEDLEYDIR/loadups/xfull35.sysout"
+	    ;;
+	"-lisp")
+	    export LDESRCSYSOUT="$MEDLEYDIR/loadups/xlisp.sysout"
+	    ;;
 	"-"*)
 	    echo unrecognized option "$1"
 	    exit 1
 	    ;;
         *)
 	    # not an option so must be a sysout name
-            export LDESRCESYSOUT=$1
+            export LDESRCSYSOUT=$1
 	    ;;
     esac
     shift
 done
 
-if [ -z "$LDESRCESYSOUT" ] ; then
+if [ -z "$LDESRCSYSOUT" ] ; then
     if [ -f "$LDEDESTSYSOUT" ] ; then
-	export LDESRCESYSOUT="$LDEDESTSYSOUT"
+	export LDESRCSYSOUT="$LDEDESTSYSOUT"
     fi
 else
     export LDESRCSYSOUT="$MEDLEYDIR/loadups/xfull35.sysout" ;
@@ -107,4 +122,4 @@ export PATH=$MAIKODIR/`osversion`.`machinetype`:"$oldpath"
 cd $old_wd
 
 
-$prog $geometry $screensize -t "Medley Interlisp @ https://Interlisp.org" 
+$prog $geometry $screensize -t "Medley Interlisp (https://Interlisp.org)" "$LDESRCSYSOUT"
