Initial Commit
[packages] / xemacs-packages / hyperbole / hmous-info.el
1 ;;; hmous-info.el --- Walks through Info networks using one key.
2
3 ;; Copyright (C) 1989, 1990, 1991, 2006 Free Software Foundation, Inc.
4 ;; Developed with support from Motorola Inc.
5
6 ;; Author: Bob Weiner, Brown U.
7 ;; Maintainer: Mats Lidell <matsl@contactor.se>
8 ;; Keywords: docs, help, hypermedia, mouse
9
10 ;; This file is part of GNU Hyperbole.
11
12 ;; GNU Hyperbole is free software; you can redistribute it and/or
13 ;; modify it under the terms of the GNU General Public License as
14 ;; published by the Free Software Foundation; either version 3, or (at
15 ;; your option) any later version.
16
17 ;; GNU Hyperbole is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20 ;; General Public License for more details.
21
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
24 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25 ;; Boston, MA 02110-1301, USA.
26
27 ;;; Commentary:
28 ;;
29 ;;  This code is machine independent.
30 ;;
31 ;;  To install:  See hui-mouse.el
32 ;;
33
34 ;;; Code:
35
36 ;;;###autoload
37 (defun smart-info ()
38   "Walks through Info documentation networks using one key or mouse key.
39
40 If key is pressed within:
41  (1) the first line of an Info Menu Entry or Cross Reference, the desired node
42        is found;
43  (2) the Up, Next, or Previous entries of a Node Header (first line),
44        the desired node is found;
45  (3) the File entry of a Node Header (first line),       
46        the 'Top' node within that file is found;
47  (4) at the end of the current node, the Next node is found (this will
48        descend subtrees if the function 'Info-global-next' is bound);
49  (5) anywhere else (e.g. at the end of a line), the current node entry is
50        scrolled up one windowful.
51
52 Returns t if key is pressed within an Info Node Header, Cross Reference,
53 or a Menu; otherwise returns nil."
54
55   (interactive)
56   (cond 
57     ;;
58     ;; If at end of node, go to next node
59     ;;
60     ((last-line-p)
61      (if (fboundp 'Info-global-next) (Info-global-next)
62        (Info-next)))
63     ((Info-handle-in-node-hdr))
64     ((Info-handle-in-note))
65     ((Info-handle-in-menu))
66     ((pos-visible-in-window-p (point-max))
67      (if (fboundp 'Info-global-next) (Info-global-next)
68        (Info-next)))
69     ;;
70     ;; If nothing else scroll forward a windowful.
71     ;;
72     ((smart-scroll-up))))
73
74 ;;;###autoload
75 (defun smart-info-assist ()
76   "Walks through Info documentation networks using one assist-key or mouse assist-key.
77
78 If assist-key is pressed within:
79  (1) the first line of an Info Menu Entry or Cross Reference, the desired node
80        is found;
81  (2) the Up, Next, or Previous entries of a Node Header (first line),
82        the last node in the history list is found;
83  (3) the File entry of a Node Header (first line),       
84        the 'DIR' root-level node is found;
85  (4) at the end of the current node, the Previous node is found (this will
86        return from subtrees if the function 'Info-global-prev is bound);
87  (5) anywhere else (e.g. at the end of a line), the current node entry is
88        scrolled down one windowful.
89
90 Returns t if assist-key is pressed within an Info Node Header, Cross Reference,
91 or a Menu; otherwise returns nil."
92
93   (interactive)
94   (cond
95     ;;
96     ;; If at end or beginning of node, go to previous node
97     ;;
98     ((last-line-p)
99      (if (fboundp 'Info-global-prev) (Info-global-prev)
100        (Info-prev)))
101     ((Info-handle-in-node-hdr-assist))
102     ((Info-handle-in-note))
103     ((Info-handle-in-menu))
104     ((pos-visible-in-window-p (point-min))
105      (if (fboundp 'Info-global-prev) (Info-global-prev)
106        (Info-prev)))
107     ;;
108     ;; If anywhere else, scroll backward a windowful.
109     ;;
110     ((smart-scroll-down))))
111
112 (defun Info-handle-in-node-hdr ()
113   "If within an Info node header, move to <FILE>Top, <Up>, <Previous>, or
114 <Next> node, depending on which label point is on, and return t.
115 Otherwise, return nil."
116   ;;
117   ;; Test if on 1st line of node, i.e. node header
118   ;;
119   (if (not (first-line-p))
120       nil
121     (let ((nodename "Top") (filep nil))
122       (save-excursion
123         (if (and
124               (re-search-forward "[:, \t\n]" nil t)
125               (re-search-backward
126                 "\\(File\\|Node\\|Up\\|Prev\\|Previous\\|Next\\):[ \t]" nil t))
127             (progn (setq filep (string-equal
128                                  "file"
129                                  (downcase (buffer-substring
130                                              (match-beginning 1)
131                                              (match-end 1)))))
132                    (if (re-search-forward (concat ":[ \n]\\([^,\t\n"
133                                                   (if filep " ")
134                                                   "]*\\)") nil t)
135                        (setq nodename (buffer-substring
136                                         (match-beginning 1)
137                                         (match-end 1)))))
138           (error "Node header not found.")))
139       (setq nodename
140             (cond ((= (aref nodename 0) ?\() nodename)
141                   (filep (concat "(" nodename ")" "Top"))
142                   (buffer-file-name (concat "(" buffer-file-name ")" nodename))
143                   (t nodename)))
144       (if hyperb:xemacs-p
145           (Info-goto-node nodename nil t)
146         (Info-goto-node nodename))
147       t)))
148
149 (defun Info-handle-in-node-hdr-assist ()
150   "If within an Info node header when the 'smart-info-assist' command is
151 executed, when within the <FILE> header go to the DIR top-level node.  When
152 within any other header (<Up>, <Previous>, or <Next>) go to last node from
153 history list.  Return t if in Info node header.  Otherwise return nil."
154   ;;
155   ;; Test if on 1st line of node, i.e. node header
156   ;;
157   (if (not (first-line-p))
158       nil
159     (save-excursion
160       (if (and 
161             (re-search-forward "[:, \t\n]" nil t)
162             (re-search-backward
163               "\\(File\\|Node\\|Up\\|Prev\\|Previous\\|Next\\):[ \t]" nil t) )
164           ;; If in <FILE> hdr
165           (progn (if (string-equal
166                        "file"
167                        (downcase (buffer-substring
168                                    (match-beginning 1)
169                                    (match-end 1))))
170                      (Info-directory)
171                    (Info-last))
172                  t)
173         (error "Node header not found.")
174         nil))))
175
176 ;;;###autoload
177 (defun Info-handle-in-note ()
178   "Follows an Info cross-reference.
179 If point is within the first line of an Info note (cross-reference), follows
180 cross-reference and returns t; otherwise returns nil."
181   (let ((note-name) (opoint (point)))
182     (save-excursion
183       (skip-chars-forward "^:")
184       (if (and (re-search-backward
185                 "\*\\(Ref\\|Note\\|See\\)\\([ \t\n]+\\|$\\)" nil t)
186                (looking-at "\*\\(Ref\\|Note\\|See\\)[ \t\n]+\\([^:]*\\):")
187                (<= (match-beginning 0) opoint)
188                (> (match-end 0) opoint))
189           ;; Remove newline and extra spaces from 'note-name'
190           (setq note-name (hypb:replace-match-string
191                            "[ \n\t]+"
192                            (buffer-substring
193                             (match-beginning 2) (match-end 2))
194                            " " t))))
195     (if note-name
196         (progn (Info-follow-reference note-name) t))))
197
198 (defun Info-handle-in-menu ()
199   "Displays node referred to by an Info Menu Entry.
200 If point is within an Info menu entry, goes to node referenced by
201 entry and returns t; otherwise returns nil."
202   ;;
203   ;; Test if there is a menu in this node
204   ;;
205   (let ((in-menu nil) (curr-point (point)))
206     (save-excursion
207       (goto-char (point-min))
208       (setq in-menu 
209             (and (search-forward "\n* menu:" nil t)
210                  (< (point) curr-point))))
211     (if (not in-menu)
212         nil
213       (let ((node))
214         (save-excursion
215           (forward-char) ; Pass '*' char if point is in front of
216           (if (search-backward "\n*" nil t)
217               (progn (forward-char 2)
218                      (setq node (Info-extract-menu-node-name)))))
219         (if (null node)
220             nil
221           (if hyperb:xemacs-p
222               (Info-goto-node node nil t)
223             (Info-goto-node node))
224           t)))))
225
226 (provide 'hmous-info)
227
228 ;;; hmous-info.el ends here