(FILECREATED "24-Jan-86 00:05:26" {ERIS}<CUTTING>LISP>KOTO>XQPM.;5 18913 changes to: (FNS XQPM.GET.GRAPH) previous date: "23-Jan-86 17:10:36" {ERIS}<CUTTING>LISP>KOTO>XQPM.;4) (* Copyright (c) 1985, 1986 by Xerox Corporation. All rights reserved.) (PRETTYCOMPRINT XQPMCOMS) (RPAQQ XQPMCOMS ((FILES (* * NOTE: XQPINFO is a Koto-ized version of LispCore DINFO. To get this package to run in Lute just replace all occurences of "XQPINFO" with "DINFO" and "XQPInfo" with "DInfo" , load it, MAKEFILE and BCOMPL.) XQPINFO) (RECORDS XQPMREF) [COMS (* Runtime code) (FNS (* called from prolog) XQPM.HELP XQPM.MANUAL) (FNS (* called from lisp) XQPM.GET.GRAPH XQPM.CREF XQPM.UPDATE.FROM.CREF XQPM.CREF.TO.ID XQPM.LOOKUP XQPM.BSEARCH XQPM.CHOOSE.REF XQPM.GATHER.REFS \XQPM.RESET) (MACROS XQPM.SUBSTRINGP) (INITVARS (PROLOGHELPDIRECTORY) (XQPM.FONT (FONTCREATE (QUOTE TERMINAL) 10))) (GLOBALVARS PROLOGHELPDIRECTORY XQPM.FONT) (ADDVARS (XQPINFO.GRAPHS ("Xerox Quintus Prolog Manual" (XQPM.GET.GRAPH T] (COMS (* MAKESYS time code) (FNS XQPM.SETUP XQPM.MAKEINDEX XQPM.MAKEGRAPH XQPM.MAKE.NODE XQPM.GET.PARENT.ID) (INITVARS (\XQPM.INDEX.ARRAY) (\XQPM.XQPINFO.GRAPH)) (GLOBALVARS \XQPM.INDEX.ARRAY \XQPM.XQPINFO.GRAPH)))) (FILESLOAD XQPINFO) [DECLARE: EVAL@COMPILE (DATATYPE XQPMREF (ITEM TYPE NODEID)) ] (/DECLAREDATATYPE (QUOTE XQPMREF) (QUOTE (POINTER POINTER POINTER)) (QUOTE ((XQPMREF 0 POINTER) (XQPMREF 2 POINTER) (XQPMREF 4 POINTER))) (QUOTE 6)) (* Runtime code) (DEFINEQ (XQPM.HELP [LAMBDA (ATOM) (* drc: "23-Jan-86 14:06") (* * Lookup ATOM in the index of the online manual. Called by prolog predicate "help(Topic)") (LET ((GRAPH (XQPM.GET.GRAPH))) (RESETFORM (TTYDISPLAYSTREAM (GETPROMPTWINDOW (fetch (XQPINFOGRAPH WINDOW) of GRAPH))) (XQPM.LOOKUP (MKSTRING ATOM) GRAPH)) NIL]) (XQPM.MANUAL [LAMBDA (SECTION) (* drc: "23-Jan-86 14:06") (* * Visit SECTION of the online manual. Called by prolog predicate "manual(Section)") (LET ((GRAPH (XQPM.GET.GRAPH))) (RESETFORM (TTYDISPLAYSTREAM (GETPROMPTWINDOW (fetch (XQPINFOGRAPH WINDOW) of GRAPH))) (XQPM.UPDATE.FROM.CREF (MKSTRING SECTION) GRAPH)) NIL]) ) (DEFINEQ (XQPM.GET.GRAPH [LAMBDA (FROMBACKGROUND?) (* drc: "24-Jan-86 00:03") (* * Returns the XQPInfo graph for the XQPM, initializing if necesary.) (DECLARE (GLOBALVARS PROLOGHELPDIRECTORY \XQPM.XQPINFO.GRAPH)) (* drc: "19-Dec-85 17:47") (if (AND (type? XQPINFOGRAPH \XQPM.XQPINFO.GRAPH) (WINDOWP (fetch (XQPINFOGRAPH WINDOW) of \XQPM.XQPINFO.GRAPH))) then (OPENW (fetch (XQPINFOGRAPH WINDOW) of \XQPM.XQPINFO.GRAPH)) (AND FROMBACKGROUND? (XQPINFO.UPDATE \XQPM.XQPINFO.GRAPH)) \XQPM.XQPINFO.GRAPH elseif (INFILEP (PACKFILENAME (QUOTE NAME) (QUOTE R0101) (QUOTE BODY) PROLOGHELPDIRECTORY)) then (OR (type? XQPINFOGRAPH \XQPM.XQPINFO.GRAPH) (ERROR "XQPM XQPInfo graph not installed!" "Try (XQPM.SETUP >>HOST&DIR<<).")) (replace (XQPINFOGRAPH DEFAULTHOST) of \XQPM.XQPINFO.GRAPH with (FILENAMEFIELD PROLOGHELPDIRECTORY (QUOTE HOST))) (replace (XQPINFOGRAPH DEFAULTDEVICE) of \XQPM.XQPINFO.GRAPH with (FILENAMEFIELD PROLOGHELPDIRECTORY (QUOTE DEVICE))) (replace (XQPINFOGRAPH DEFAULTDIR) of \XQPM.XQPINFO.GRAPH with (FILENAMEFIELD PROLOGHELPDIRECTORY (QUOTE DIRECTORY))) (replace (XQPINFOGRAPH TEXTPROPS) of \XQPM.XQPINFO.GRAPH with (LIST (QUOTE FONT) XQPM.FONT)) (replace (XQPINFOGRAPH MENUFONT) of \XQPM.XQPINFO.GRAPH with XQPM.FONT) (replace (XQPINFOGRAPH WINDOW) of \XQPM.XQPINFO.GRAPH with (CREATEW (GETBOXREGION 500 300 NIL NIL NIL "Specify region for XQPInfo window") "XQPInfo")) (XQPINFO \XQPM.XQPINFO.GRAPH NIL (if FROMBACKGROUND? then NIL else T)) \XQPM.XQPINFO.GRAPH else (ERROR "Set PROLOGHELPDIRECTORY to the location of the manual files.") NIL]) (XQPM.CREF [LAMBDA (ITEM FM.WINDOW BUTTONS) (* drc: "23-Jan-86 14:16") (LET* ((GRAPH (XQPINFOGRAPH FM.WINDOW)) (W (fetch (XQPINFOGRAPH WINDOW) of GRAPH)) (TEXTSTREAM (WINDOWPROP W (QUOTE TEXTSTREAM))) (TEXTOBJ (TEXTOBJ TEXTSTREAM)) CREF SEL) (RESETFORM (TTYDISPLAYSTREAM (GETPROMPTWINDOW W)) (CLEARW T) (SELECTQ (FM.ITEMPROP ITEM (QUOTE ID)) (GOTOREF (SETQ SEL (TEDIT.SEL.AS.STRING TEXTSTREAM (TEDIT.GETSEL TEXTSTREAM))) (if (AND (STRING-EQUAL (SUBSTRING SEL 1 8) "{manual(") (STRING-EQUAL (SUBSTRING SEL -2) ")}")) then (XQPM.UPDATE.FROM.CREF (SUBSTRING SEL 9 -3) GRAPH) else (PRINTOUT T T "No cross reference selected. Try NextRef!"))) [NEXTREF (PRINTOUT T "Searching...") (SETQ CREF (TEDIT.FIND TEXTOBJ "{manual(*)}" NIL NIL T) ) (if CREF then (TEDIT.NORMALIZECARET TEXTOBJ (SETQ SEL (TEDIT.SETSEL TEXTSTREAM (CAR CREF) (ADD1 (IDIFFERENCE (CADR CREF) (CAR CREF))) (QUOTE RIGHT) T))) (PRINTOUT T T "OK. Select GoToRef! to go to " (SUBSTRING (TEDIT.SEL.AS.STRING TEXTSTREAM SEL) 2 -2) ".") else (PRINTOUT T T "No more cross references in this node") (TEDIT.NORMALIZECARET TEXTOBJ (TEDIT.SETSEL TEXTSTREAM 0 0] (SHOULDNT]) (XQPM.UPDATE.FROM.CREF [LAMBDA (STRING GRAPH) (* drc: "23-Jan-86 14:24") (* Go to node in GRAPH denoted by STRING. STRING should be a string encoding the nodeid of the cross referenced node, where "ref-1-11" encodes nodeid R0111.) (LET* [(ID (XQPM.CREF.TO.ID STRING)) (NODE (FASSOC ID (fetch (XQPINFOGRAPH NODELST) of GRAPH] (if NODE then (XQPINFO.UPDATE GRAPH NODE) else (printout T T "Section " STRING " not found."]) (XQPM.CREF.TO.ID [LAMBDA (CREF) (* drc: "23-Jan-86 14:24") (* * converts a ref-1-2 style cross reference (CREF) to a R0102 style ID.) (LET ((L (UNPACK CREF))) (PACK (CONS (U-CASE (CAR L)) (for TAIL on L bind FLG join (if (SMALLP (CAR TAIL)) then (if FLG then (SETQ FLG) (LIST (CAR TAIL)) elseif (SMALLP (CADR TAIL)) then (SETQ FLG T) (LIST (CAR TAIL)) else (LIST 0 (CAR TAIL))) else NIL]) (XQPM.LOOKUP [LAMBDA (STRING GRAPH) (* drc: "15-Jan-86 23:11") (* LOOKUPFN for XQPM XQPInfo graph. All index entries for which STRING is an initial substring of are gathered and put in the manual for the user to select which one to lookup.) (LET* [(W (fetch (XQPINFOGRAPH WINDOW) of GRAPH)) [SAME? (STRING-EQUAL STRING (WINDOWPROP W (QUOTE XQPM.LAST.LOOKUP] (REFS (if SAME? then (WINDOWPROP W (QUOTE XQPM.LAST.REFS)) else (XQPM.BSEARCH (L-CASE STRING] (WINDOWPROP W (QUOTE XQPM.LAST.LOOKUP) STRING) (WINDOWPROP W (QUOTE XQPM.LAST.REFS) REFS) (if REFS then [LET ((REF (XQPM.CHOOSE.REF REFS W SAME?))) (AND REF (XQPINFO.UPDATE GRAPH (FASSOC (fetch (XQPMREF NODEID) of REF) (fetch (XQPINFOGRAPH NODELST) of GRAPH)) (MKSTRING (fetch (XQPMREF ITEM) of REF] else (PRINTOUT T T STRING " not found in index"]) (XQPM.BSEARCH [LAMBDA (ITEM) (* drc: "15-Jan-86 23:15") (* * returns the list of XQPMREF's in \XQPM.INDEX.ARRAY whose ITEM fields' initial substrings match ITEM. Binary searches until it finds a match, then gathers all the matches neighboring it. Algorithm courtesy of Knuth, Volume 3, Sorting and Searching, page 407) (RESETFORM (CURSOR WAITINGCURSOR) (PROG ((ARRAY (GETTOPVAL (QUOTE \XQPM.INDEX.ARRAY))) (ITEMLEN (NCHARS ITEM)) (L 1) U I REF FLG) (SETQ U (ARRAYSIZE ARRAY)) LOOP(if (LESSP U L) then (RETURN NIL)) (SETQ I (IQUOTIENT (IPLUS L U) 2)) (SETQ REF (ELT ARRAY I)) (SETQ FLG (ALPHORDER ITEM (fetch (XQPMREF ITEM) of REF))) (if (NULL FLG) then (SETQ L (ADD1 I)) (GO LOOP) elseif (OR (EQ FLG (QUOTE EQUAL)) (XQPM.SUBSTRINGP ITEM ITEMLEN (fetch (XQPMREF ITEM) of REF))) then (RETURN (XQPM.GATHER.REFS ITEM ITEMLEN REF I ARRAY)) else (SETQ U (SUB1 I)) (GO LOOP]) (XQPM.CHOOSE.REF [LAMBDA (REFS W SAME?) (* drc: "15-Jan-86 23:11") (if (NULL (CDR REFS)) then (CAR REFS) else (LET [(MENU (if SAME? then (WINDOWPROP W (QUOTE XQPM.LOOKUP.MENU)) else (create MENU CENTERFLG ← T TITLE ← STRING ITEMS ←(for REF in REFS collect (LIST (fetch (XQPMREF TYPE) of REF) REF] (WINDOWPROP W (QUOTE XQPM.LOOKUP.MENU) MENU) (MENU MENU]) (XQPM.GATHER.REFS [LAMBDA (ITEM ITEMLEN REF POINT ARRAY) (* drc: "18-Dec-85 18:57") (* Assumes that REF (which is at POINT in ARRAY) matches ITEM, and collects the references on either side of REF which also match ITEM. As we are matching ITEM with initial substring's of the ITEM fields of the XQPMREF's in ARRAY, and we know that ARRAY is sorted alphabetically by this field, we can be sure that all matches will be adjacent.) (LET ((BEFORE (for I from (SUB1 POINT) to 1 by -1 bind REF eachtime (AND (GEQ I 1) (SETQ REF (ELT ARRAY I))) while (XQPM.SUBSTRINGP ITEM ITEMLEN (fetch (XQPMREF ITEM) of REF)) collect REF)) (AFTER (for I from (ADD1 POINT) to (ARRAYSIZE ARRAY) bind REF eachtime (AND (LEQ I (ARRAYSIZE ARRAY)) (SETQ REF (ELT ARRAY I))) while (XQPM.SUBSTRINGP ITEM ITEMLEN (fetch (XQPMREF ITEM) of REF)) collect REF))) (NCONC (DREVERSE BEFORE) (LIST REF) AFTER]) (\XQPM.RESET [LAMBDA NIL (* drc: "16-Jan-86 15:25") (if (type? XQPINFOGRAPH \XQPM.XQPINFO.GRAPH) then (LET ((W (fetch (XQPINFOGRAPH WINDOW) of \XQPM.XQPINFO.GRAPH))) (OPENW W) (CLOSEW W))) (SETQ PROLOGHELPDIRECTORY) (SETQ \XQPM.XQPINFO.GRAPH) (SETQ \XQPM.INDEX.ARRAY]) ) (DECLARE: EVAL@COMPILE [PUTPROPS XQPM.SUBSTRINGP MACRO ((X XLEN Y) (STREQUAL X (SUBSTRING Y 1 XLEN] ) (RPAQ? PROLOGHELPDIRECTORY ) (RPAQ? XQPM.FONT (FONTCREATE (QUOTE TERMINAL) 10)) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS PROLOGHELPDIRECTORY XQPM.FONT) ) (ADDTOVAR XQPINFO.GRAPHS ("Xerox Quintus Prolog Manual" (XQPM.GET.GRAPH T))) (* MAKESYS time code) (DEFINEQ (XQPM.SETUP [LAMBDA (HOST&DIR) (* drc: "16-Jan-86 15:23") (* * Sets up the XQPM. To be called when assembling a prolog sysout. HOST&DIR should be the prolog sources directory and should contain files XQPM.FILETITLES and XQPM.INDEX.) (XQPM.MAKEGRAPH HOST&DIR) (XQPM.MAKEINDEX HOST&DIR]) (XQPM.MAKEINDEX [LAMBDA (HOST&DIR) (* drc: "16-Jan-86 21:20") (* * Reads the file named XQPM.INDEX on HOST&DIR sorts its contents, and makes \XQPM.INDEX.ARRAY out of it. File should contain a sequence of (ItemAtom TypeString NodeID) where NodeID is the name of the file (and the nodeid of the node) containing the reference to ItemAtom as a TypeString.) (DECLARE (GLOBALVARS \XQPM.INDEX.ARRAY)) (PRINTOUT T "Making index array...") (PRINTOUT T "reading...") (LET* ((ENTRIES (READFILE (PACKFILENAME (QUOTE NAME) (QUOTE XQPM.INDEX) (QUOTE BODY) HOST&DIR))) (#ENTRIES (FLENGTH ENTRIES))) [MAP ENTRIES (FUNCTION (LAMBDA (TAIL) (RPLACA TAIL (L-CASE (CAR TAIL] (* L-CASE the ITEM fields before sorting) (PRINTOUT T "sorting...") [SORT ENTRIES (FUNCTION (LAMBDA (A B) (ALPHORDER (CAR A) (CAR B] (SETQ \XQPM.INDEX.ARRAY (ARRAY #ENTRIES)) (printout T "inserting...") [for ENTRY in ENTRIES as I from 1 to #ENTRIES do (SETA \XQPM.INDEX.ARRAY I (create XQPMREF ITEM ←(CAR ENTRY) TYPE ←(CADR ENTRY) NODEID ←(U-CASE (CADDR ENTRY] (printout T "OK." T]) (XQPM.MAKEGRAPH [LAMBDA (HOST&DIR) (* drc: "21-Jan-86 19:57") (* Expects HOST&DIR to contain a file called XQPM.FILETITLES which contains a sequence of (filename/nodeid nodename fileexists?) lists, where filename/nodeid is both (possibly) the name of a documentation file, and an encoded graph position. Encoding of reference manual section 4-12-2 would be R041202. The file is expected to be ordered in the order the corresponding sections of the manual occur in.) (DECLARE (GLOBALVARS \XQPM.XQPINFO.GRAPH)) (PRINTOUT T "Making XQPInfo graph...") (PRINTOUT T "reading...") (LET* ((FILETITLES (READFILE (PACKFILENAME (QUOTE NAME) (QUOTE XQPM.FILETITLES) (QUOTE BODY) HOST&DIR))) (TOPNODE (create XQPINFONODE ID ←(CAAR FILETITLES) LABEL ←(CADAR FILETITLES))) (NODELST (LIST TOPNODE))) [SETQ \XQPM.XQPINFO.GRAPH (create XQPINFOGRAPH NAME ← "XQPM" TOPNODEID ←(fetch (XQPINFONODE ID) of TOPNODE) LOOKUPFN ←(FUNCTION XQPM.LOOKUP) FREEMENUITEMS ←(QUOTE ((ID NEXTREF LABEL "NextRef!" SELECTEDFN XQPM.CREF FONT (HELVETICA 10 BOLD) MESSAGE "Find next cross reference in this node") (ID GOTOREF LABEL "GoToRef!" SELECTEDFN XQPM.CREF FONT (HELVETICA 10 BOLD) MESSAGE "Go to currently selected cross reference"] (PRINTOUT T "creating NODELST...") (* chug through the nodes...) (for X in (CDR FILETITLES) do (XQPM.MAKE.NODE (CAR X) (CADR X) (CADDR X) NODELST HOST&DIR)) (replace (XQPINFOGRAPH NODELST) of \XQPM.XQPINFO.GRAPH with NODELST) (PRINTOUT T "OK." T]) (XQPM.MAKE.NODE [LAMBDA (ID LABEL FILE? NODELST HOST&DIR) (* drc: "21-Jan-86 20:00") (* * Takes filename/nodeid ID, and node label LABEL, creates a XQPINFONODE for them, and inserts it into NODELST appropriatly. FILE? is T if there really is a file (named ID) for the node.) (if (AND (EQ (MKATOM (SUBSTRING ID -2)) 0) (STRING-EQUAL LABEL "Overview")) then (* zeroth sections named "Overview" don't get turned into nodes -- their text is just slid up into their textless parent.) (replace (XQPINFONODE FILE) of (FASSOC (XQPM.GET.PARENT.ID ID NODELST) NODELST) with ID) else (LET ((PREVIOUS (CAR NODELST)) NODE) (replace (XQPINFONODE NEXTNODE) of PREVIOUS with ID) [LET* ((PARENTID (XQPM.GET.PARENT.ID ID NODELST)) (PARENT (FASSOC PARENTID NODELST))) (replace (XQPINFONODE CHILDREN) of PARENT with (ATTACH ID (fetch (XQPINFONODE CHILDREN) of PARENT))) (SETQ NODE (create XQPINFONODE LABEL ← LABEL FILE ←(AND FILE? ID) ID ← ID PARENT ← PARENTID PREVIOUSNODE ←(fetch (XQPINFONODE ID) of PREVIOUS] (ATTACH NODE NODELST]) (XQPM.GET.PARENT.ID [LAMBDA (ID NODELST) (* drc: "18-Dec-85 19:11") (* * Decodes the ID of the node whose ID is ID and returns the ID of its Parent node.) (if (EQ (NCHARS ID) 1) then (* Parent is top node, which should be last in nodelst.) (fetch (XQPINFONODE ID) of (CAR (FLAST NODELST))) else (MKATOM (SUBSTRING (MKSTRING ID) 1 -3]) ) (RPAQ? \XQPM.INDEX.ARRAY ) (RPAQ? \XQPM.XQPINFO.GRAPH ) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS \XQPM.INDEX.ARRAY \XQPM.XQPINFO.GRAPH) ) (PUTPROPS XQPM COPYRIGHT ("Xerox Corporation" 1985 1986)) (DECLARE: DONTCOPY (FILEMAP (NIL (1678 2621 (XQPM.HELP 1688 . 2148) (XQPM.MANUAL 2150 . 2619)) (2622 12496 ( XQPM.GET.GRAPH 2632 . 4774) (XQPM.CREF 4776 . 6566) (XQPM.UPDATE.FROM.CREF 6568 . 7124) ( XQPM.CREF.TO.ID 7126 . 7874) (XQPM.LOOKUP 7876 . 9036) (XQPM.BSEARCH 9038 . 10319) (XQPM.CHOOSE.REF 10321 . 10929) (XQPM.GATHER.REFS 10931 . 12094) (\XQPM.RESET 12096 . 12494)) (12896 18679 (XQPM.SETUP 12906 . 13282) (XQPM.MAKEINDEX 13284 . 14694) (XQPM.MAKEGRAPH 14696 . 16681) (XQPM.MAKE.NODE 16683 . 18132) (XQPM.GET.PARENT.ID 18134 . 18677))))) STOP