Mercurial > octave
comparison info/footnotes.c @ 171:d6fae6ef3e60
[project @ 1993-10-21 22:39:46 by jwe]
Initial revision
author | jwe |
---|---|
date | Thu, 21 Oct 1993 22:39:46 +0000 |
parents | |
children | 5fb4ee02da70 |
comparison
equal
deleted
inserted
replaced
170:a76cfc0fc794 | 171:d6fae6ef3e60 |
---|---|
1 /* footnotes.c -- Some functions for manipulating footnotes. */ | |
2 | |
3 /* This file is part of GNU Info, a program for reading online documentation | |
4 stored in Info format. | |
5 | |
6 Copyright (C) 1993 Free Software Foundation, Inc. | |
7 | |
8 This program is free software; you can redistribute it and/or modify | |
9 it under the terms of the GNU General Public License as published by | |
10 the Free Software Foundation; either version 2, or (at your option) | |
11 any later version. | |
12 | |
13 This program is distributed in the hope that it will be useful, | |
14 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 GNU General Public License for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with this program; if not, write to the Free Software | |
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
21 | |
22 Written by Brian Fox (bfox@ai.mit.edu). */ | |
23 | |
24 #include "info.h" | |
25 | |
26 /* Non-zero means attempt to show footnotes when displaying a new window. */ | |
27 int auto_footnotes_p = 1; | |
28 | |
29 static char *footnote_nodename = "*Footnotes*"; | |
30 | |
31 #define FOOTNOTE_HEADER_FORMAT \ | |
32 "*** Footnotes appearing in the node \"%s\" ***\n" | |
33 | |
34 /* Find the window currently showing footnotes. */ | |
35 static WINDOW * | |
36 find_footnotes_window () | |
37 { | |
38 WINDOW *win; | |
39 | |
40 /* Try to find an existing window first. */ | |
41 for (win = windows; win; win = win->next) | |
42 if (internal_info_node_p (win->node) && | |
43 (strcmp (win->node->nodename, footnote_nodename) == 0)) | |
44 break; | |
45 | |
46 return (win); | |
47 } | |
48 | |
49 /* Manufacture a node containing the footnotes of this node, and | |
50 return the manufactured node. If NODE has no footnotes, return a | |
51 NULL pointer. */ | |
52 NODE * | |
53 make_footnotes_node (node) | |
54 NODE *node; | |
55 { | |
56 NODE *fn_node, *result = (NODE *)NULL; | |
57 long fn_start; | |
58 | |
59 /* Make the initial assumption that the footnotes appear as simple | |
60 text within this windows node. */ | |
61 fn_node = node; | |
62 | |
63 /* See if this node contains the magic footnote label. */ | |
64 fn_start = | |
65 info_search_in_node (FOOTNOTE_LABEL, node, 0, (WINDOW *)NULL, 1); | |
66 | |
67 /* If it doesn't, check to see if it has an associated footnotes node. */ | |
68 if (fn_start == -1) | |
69 { | |
70 REFERENCE **refs; | |
71 | |
72 refs = info_xrefs_of_node (node); | |
73 | |
74 if (refs) | |
75 { | |
76 register int i; | |
77 char *refname; | |
78 | |
79 refname = (char *)xmalloc | |
80 (1 + strlen ("-Footnotes") + strlen (node->nodename)); | |
81 | |
82 strcpy (refname, node->nodename); | |
83 strcat (refname, "-Footnotes"); | |
84 | |
85 for (i = 0; refs[i]; i++) | |
86 if (strcmp (refs[i]->nodename, refname) == 0) | |
87 { | |
88 char *filename; | |
89 | |
90 filename = node->parent; | |
91 if (!filename) | |
92 filename = node->filename; | |
93 | |
94 fn_node = info_get_node (filename, refname); | |
95 | |
96 if (fn_node) | |
97 fn_start = 0; | |
98 | |
99 break; | |
100 } | |
101 | |
102 free (refname); | |
103 info_free_references (refs); | |
104 } | |
105 } | |
106 | |
107 /* If we never found the start of a footnotes area, quit now. */ | |
108 if (fn_start == -1) | |
109 return ((NODE *)NULL); | |
110 | |
111 /* Make the new node. */ | |
112 result = (NODE *)xmalloc (sizeof (NODE)); | |
113 result->flags = 0; | |
114 | |
115 /* Get the size of the footnotes appearing within this node. */ | |
116 { | |
117 char *header; | |
118 long text_start = fn_start; | |
119 | |
120 header = (char *)xmalloc | |
121 (1 + strlen (node->nodename) + strlen (FOOTNOTE_HEADER_FORMAT)); | |
122 sprintf (header, FOOTNOTE_HEADER_FORMAT, node->nodename); | |
123 | |
124 /* Move the start of the displayed text to right after the first line. | |
125 This effectively skips either "---- footno...", or "File: foo...". */ | |
126 while (text_start < fn_node->nodelen) | |
127 if (fn_node->contents[text_start++] == '\n') | |
128 break; | |
129 | |
130 result->nodelen = strlen (header) + fn_node->nodelen - text_start; | |
131 | |
132 /* Set the contents of this node. */ | |
133 result->contents = (char *)xmalloc (1 + result->nodelen); | |
134 sprintf (result->contents, "%s", header); | |
135 memcpy (result->contents + strlen (header), | |
136 fn_node->contents + text_start, fn_node->nodelen - text_start); | |
137 | |
138 name_internal_node (result, footnote_nodename); | |
139 free (header); | |
140 } | |
141 | |
142 #if defined (NOTDEF) | |
143 /* If the footnotes were gleaned from the node that we were called with, | |
144 shorten the calling node's display length. */ | |
145 if (fn_node == node) | |
146 narrow_node (node, 0, fn_start); | |
147 #endif /* NOTDEF */ | |
148 | |
149 return (result); | |
150 } | |
151 | |
152 /* Create or delete the footnotes window depending on whether footnotes | |
153 exist in WINDOW's node or not. Returns FN_FOUND if footnotes were found | |
154 and displayed. Returns FN_UNFOUND if there were no footnotes found | |
155 in WINDOW's node. Returns FN_UNABLE if there were footnotes, but the | |
156 window to show them couldn't be made. */ | |
157 int | |
158 info_get_or_remove_footnotes (window) | |
159 WINDOW *window; | |
160 { | |
161 WINDOW *fn_win; | |
162 NODE *new_footnotes; | |
163 | |
164 fn_win = find_footnotes_window (); | |
165 | |
166 /* If we are in the footnotes window, change nothing. */ | |
167 if (fn_win == window) | |
168 return (FN_FOUND); | |
169 | |
170 /* Try to find footnotes for this window's node. */ | |
171 new_footnotes = make_footnotes_node (window->node); | |
172 | |
173 /* If there was a window showing footnotes, and there are no footnotes | |
174 for the current window, delete the old footnote window. */ | |
175 if (fn_win && !new_footnotes) | |
176 { | |
177 if (windows->next) | |
178 info_delete_window_internal (fn_win); | |
179 } | |
180 | |
181 /* If there are footnotes for this window's node, but no window around | |
182 showing footnotes, try to make a new window. */ | |
183 if (new_footnotes && !fn_win) | |
184 { | |
185 WINDOW *old_active; | |
186 WINDOW *last, *win; | |
187 | |
188 /* Always make this window be the last one appearing in the list. Find | |
189 the last window in the chain. */ | |
190 for (win = windows, last = windows; win; last = win, win = win->next); | |
191 | |
192 /* Try to split this window, and make the split window the one to | |
193 contain the footnotes. */ | |
194 old_active = active_window; | |
195 active_window = last; | |
196 fn_win = window_make_window (new_footnotes); | |
197 active_window = old_active; | |
198 | |
199 if (!fn_win) | |
200 { | |
201 free (new_footnotes->contents); | |
202 free (new_footnotes); | |
203 | |
204 /* If we are hacking automatic footnotes, and there are footnotes | |
205 but we couldn't display them, print a message to that effect. */ | |
206 if (auto_footnotes_p) | |
207 inform_in_echo_area ("Footnotes could not be displayed"); | |
208 return (FN_UNABLE); | |
209 } | |
210 } | |
211 | |
212 /* If there are footnotes, and there is a window to display them, | |
213 make that window be the number of lines appearing in the footnotes. */ | |
214 if (new_footnotes && fn_win) | |
215 { | |
216 window_set_node_of_window (fn_win, new_footnotes); | |
217 | |
218 window_change_window_height | |
219 (fn_win, fn_win->line_count - fn_win->height); | |
220 | |
221 remember_window_and_node (fn_win, new_footnotes); | |
222 add_gcable_pointer (new_footnotes->contents); | |
223 } | |
224 | |
225 if (!new_footnotes) | |
226 return (FN_UNFOUND); | |
227 else | |
228 return (FN_FOUND); | |
229 } | |
230 | |
231 /* Show the footnotes associated with this node in another window. */ | |
232 DECLARE_INFO_COMMAND (info_show_footnotes, | |
233 "Show the footnotes associated with this node in another window") | |
234 { | |
235 int result; | |
236 | |
237 /* A negative argument means just make the window go away. */ | |
238 if (count < 0) | |
239 { | |
240 WINDOW *fn_win = find_footnotes_window (); | |
241 | |
242 /* If there is an old footnotes window, and it isn't the only window | |
243 on the screen, delete it. */ | |
244 if (fn_win && windows->next) | |
245 info_delete_window_internal (fn_win); | |
246 } | |
247 else | |
248 { | |
249 int result; | |
250 | |
251 result = info_get_or_remove_footnotes (window); | |
252 | |
253 switch (result) | |
254 { | |
255 case FN_UNFOUND: | |
256 info_error (NO_FOOT_NODE); | |
257 break; | |
258 | |
259 case FN_UNABLE: | |
260 info_error (WIN_TOO_SMALL); | |
261 break; | |
262 } | |
263 } | |
264 } |