1 /* float.c -- float environment functions.
2 $Id: float.c,v 1.8 2004/07/05 22:23:22 karl Exp $
4 Copyright (C) 2003, 2004 Free Software Foundation, Inc.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 Originally written by Alper Ersoy <dirt@gtk.org>. */
28 #include "sectioning.h"
31 static FLOAT_ELT *float_stack = NULL;
34 add_new_float (char *id, char *title, char *shorttitle,
35 char *type, char *position)
37 FLOAT_ELT *new = xmalloc (sizeof (FLOAT_ELT));
38 unsigned long num_len;
43 new->shorttitle = shorttitle;
44 new->position = position;
46 new->defining_line = line_number - 1;
48 new->number = current_chapter_number ();
49 /* Append dot if not @unnumbered. */
50 num_len = strlen (new->number);
53 new->number = xrealloc (new->number, num_len + 1 + 1);
54 new->number[num_len] = '.';
55 new->number[num_len+1] = '\0';
58 { /* Append the current float number. */
59 unsigned len = strlen (new->number) + 21; /* that's 64 bits */
60 char *s = xmalloc (len + 1);
62 sprintf (s, "%s%d", new->number,
63 count_floats_of_type_in_chapter (text_expansion (type),
66 new->number = xstrdup (s);
69 /* Plain text output needs sectioning number and its title,
70 when listing floats. */
71 if (!html && !xml && no_headers)
73 new->section = current_sectioning_number ();
74 if (strlen (new->section) == 0)
75 new->section_name = current_sectioning_name ();
77 new->section_name = "";
80 new->next = float_stack;
85 count_floats_of_type_in_chapter (char *type, char *chapter)
88 int l = strlen (chapter);
89 FLOAT_ELT *temp = float_stack;
91 while (temp && strncmp (temp->number, chapter, l) == 0)
93 if (strlen (temp->id) > 0 && STREQ (text_expansion (temp->type), type))
102 current_float_title (void)
104 return float_stack->title;
108 current_float_shorttitle (void)
110 return float_stack->shorttitle;
114 current_float_type (void)
116 return float_stack->type;
120 current_float_position (void)
122 return float_stack->position;
126 current_float_number (void)
128 return float_stack->number;
132 current_float_id (void)
134 return float_stack->id;
138 get_float_ref (char *id)
140 FLOAT_ELT *temp = float_stack;
144 if (STREQ (id, temp->id))
146 char *s = xmalloc (strlen (temp->type) + strlen (temp->number) + 2);
147 sprintf (s, "%s %s", temp->type, temp->number);
157 float_type_exists (char *check_type)
159 /* Check if the requested float_type exists in the floats stack. */
162 for (temp = float_stack; temp; temp = temp->next)
163 if (STREQ (temp->type, check_type) && temp->id && *temp->id)
170 cm_listoffloats (void)
173 get_rest_of_line (1, &float_type);
175 /* get_rest_of_line increments the line number by one,
176 so to make warnings/errors point to the correct line,
177 we decrement the line_number again. */
178 if (!handling_delayed_writes)
181 if (handling_delayed_writes && !float_type_exists (float_type))
182 warning (_("Requested float type `%s' not previously used"), float_type);
186 xml_insert_element_with_attribute (LISTOFFLOATS, START,
187 "type=\"%s\"", text_expansion (float_type));
188 xml_insert_element (LISTOFFLOATS, END);
190 else if (!handling_delayed_writes)
192 int command_len = sizeof ("@ ") + strlen (command) + strlen (float_type);
193 char *list_command = xmalloc (command_len + 1);
195 /* These are for the text following @listoffloats command.
196 Handling them with delayed writes is too late. */
200 sprintf (list_command, "@%s %s", command, float_type);
201 register_delayed_write (list_command);
204 else if (float_type_exists (float_type))
206 FLOAT_ELT *temp = (FLOAT_ELT *) reverse_list
207 ((GENERIC_LIST *) float_stack);
208 FLOAT_ELT *new_start = temp;
211 insert_string ("<ul class=\"listoffloats\">\n");
215 insert_string ("* Menu:\n\n");
220 if (strlen (temp->id) > 0 && STREQ (float_type, temp->type))
224 /* A bit of space for HTML reabality. */
226 add_html_block_elt ("<li>");
228 /* Simply relying on @ref command doesn't work here, because
229 commas in the caption may confuse the argument parsing. */
230 add_word ("<a href=\"");
231 add_anchor_name (temp->id, 1);
234 if (strlen (float_type) > 0)
235 execute_string ("%s", float_type);
237 if (strlen (temp->id) > 0)
239 if (strlen (float_type) > 0)
242 add_word (temp->number);
245 if (strlen (temp->title) > 0)
247 if (strlen (float_type) > 0
248 || strlen (temp->id) > 0)
249 insert_string (": ");
251 execute_string ("%s", temp->title);
256 add_html_block_elt ("</li>\n");
262 char *title = expansion (temp->title, 0);
265 int aux_chars_len; /* these are asterisk, colon, etc. */
266 int column_width; /* width of the first column in menus. */
267 int number_len; /* length of Figure X.Y: etc. */
270 /* Chosen widths are to match what @printindex produces. */
274 /* We have only one auxiliary character, NULL. */
275 aux_chars_len = sizeof ("");
280 /* We'll be adding an asterisk, followed by a space
281 and then a colon after the title, to construct a
283 aux_chars_len = sizeof ("* :");
286 /* Allocate enough space for possible expansion later. */
287 raw_entry = (char *) xmalloc (strlen (float_type)
288 + strlen (temp->number) + strlen (title)
291 sprintf (raw_entry, "%s %s", float_type, temp->number);
293 if (strlen (title) > 0)
294 strcat (raw_entry, ": ");
296 number_len = strlen (raw_entry);
298 len = strlen (title) + strlen (raw_entry);
300 /* If we have a @shortcaption, try it if @caption is
301 too long to fit on a line. */
302 if (len + aux_chars_len > column_width
303 && strlen (temp->shorttitle) > 0)
304 title = expansion (temp->shorttitle, 0);
306 strcat (raw_entry, title);
307 len = strlen (raw_entry);
309 if (len + aux_chars_len > column_width)
310 { /* Shorten long titles by looking for a space before
311 column_width - strlen (" ..."). */
312 /* -1 is for NULL, which is already in aux_chars_len. */
313 aux_chars_len += sizeof ("...") - 1;
314 len = column_width - aux_chars_len;
315 while (raw_entry[len] != ' ' && len >= 0)
318 /* Advance to the whitespace. */
321 /* If we are at the end of, say, Figure X.Y:, but
322 we have a title, then this means title does not
323 contain any whitespaces. Or it may be that we
324 went as far as the beginning. Just print as much
325 as possible of the title. */
327 || (len == number_len && strlen (title) > 0))
328 len = column_width - sizeof ("...");
333 entry = xmalloc (len + aux_chars_len);
336 strcpy (entry, "* ");
340 strcat (entry, raw_entry);
341 strcat (entry, "...");
348 entry = xmalloc (len + aux_chars_len);
351 strcpy (entry, "* ");
355 strcat (entry, raw_entry);
361 insert_string (entry);
364 /* We insert space chars until ``column_width + four spaces''
365 is reached, to make the layout the same with what we produce
366 for @printindex. This is of course not obligatory, though
367 easier on the eye. -1 is for NULL. */
368 while (i < column_width + sizeof (" ") - 1)
376 if (strlen (temp->section) > 0)
377 { /* We got your number. */
378 insert_string ((char *) _("See "));
379 insert_string (temp->section);
382 { /* Sigh, @float in an @unnumbered. :-\ */
383 insert_string ("\n ");
384 insert_string ((char *) _("See "));
385 insert_string ("``");
386 insert_string (expansion (temp->section_name, 0));
387 insert_string ("''");
391 insert_string (temp->id);
393 insert_string (".\n");
404 inhibit_paragraph_indentation = 1;
405 insert_string ("</ul>\n\n");
410 /* Retain the original order of float stack. */
412 float_stack = (FLOAT_ELT *) reverse_list ((GENERIC_LIST *) temp);
416 /* Re-increment the line number, because get_rest_of_line
417 left us looking at the next line after the command. */
422 current_float_used_title (void)
424 return float_stack->title_used;
427 void current_float_set_title_used (void)
429 float_stack->title_used = 1;