1 /* float.c -- float environment functions.
2 $Id: float.c,v 1.12 2007/07/01 21:20:32 karl Exp $
4 Copyright (C) 2003, 2004, 2007 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 3 of the License, or
9 (at your option) any later version.
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, see <http://www.gnu.org/licenses/>.
19 Originally written by Alper Ersoy <dirt@gtk.org>. */
27 #include "sectioning.h"
30 static FLOAT_ELT *float_stack = NULL;
33 add_new_float (char *id, char *title, char *shorttitle,
34 char *type, char *position)
36 FLOAT_ELT *new = xmalloc (sizeof (FLOAT_ELT));
37 unsigned long num_len;
42 new->shorttitle = shorttitle;
43 new->position = position;
45 new->defining_line = line_number - 1;
47 new->number = current_chapter_number ();
48 /* Append dot if not @unnumbered. */
49 num_len = strlen (new->number);
52 new->number = xrealloc (new->number, num_len + 1 + 1);
53 new->number[num_len] = '.';
54 new->number[num_len+1] = '\0';
57 { /* Append the current float number. */
58 unsigned len = strlen (new->number) + 21; /* that's 64 bits */
59 char *s = xmalloc (len + 1);
61 sprintf (s, "%s%d", new->number,
62 count_floats_of_type_in_chapter (text_expansion (type),
65 new->number = xstrdup (s);
68 /* Plain text output needs sectioning number and its title,
69 when listing floats. */
70 if (!html && !xml && no_headers)
72 new->section = current_sectioning_number ();
73 if (strlen (new->section) == 0)
74 new->section_name = current_sectioning_name ();
76 new->section_name = "";
79 new->next = float_stack;
84 count_floats_of_type_in_chapter (char *type, char *chapter)
87 int l = strlen (chapter);
88 FLOAT_ELT *temp = float_stack;
90 while (temp && strncmp (temp->number, chapter, l) == 0)
92 if (strlen (temp->id) > 0 && STREQ (text_expansion (temp->type), type))
101 current_float_title (void)
103 return float_stack->title;
107 current_float_shorttitle (void)
109 return float_stack->shorttitle;
113 current_float_type (void)
115 return float_stack->type;
119 current_float_position (void)
121 return float_stack->position;
125 current_float_number (void)
127 return float_stack->number;
131 current_float_id (void)
133 return float_stack->id;
137 get_float_ref (char *id)
139 FLOAT_ELT *temp = float_stack;
143 if (STREQ (id, temp->id))
145 char *s = xmalloc (strlen (temp->type) + strlen (temp->number) + 2);
146 sprintf (s, "%s %s", temp->type, temp->number);
156 float_type_exists (char *check_type)
158 /* Check if the requested float_type exists in the floats stack. */
161 for (temp = float_stack; temp; temp = temp->next)
162 if (STREQ (temp->type, check_type) && temp->id && *temp->id)
169 cm_listoffloats (void)
172 get_rest_of_line (1, &float_type);
174 /* get_rest_of_line increments the line number by one,
175 so to make warnings/errors point to the correct line,
176 we decrement the line_number again. */
177 if (!handling_delayed_writes)
180 if (handling_delayed_writes && !float_type_exists (float_type))
181 warning (_("Requested float type `%s' not previously used"), float_type);
185 xml_insert_element_with_attribute (LISTOFFLOATS, START,
186 "type=\"%s\"", text_expansion (float_type));
187 xml_insert_element (LISTOFFLOATS, END);
189 else if (!handling_delayed_writes)
191 int command_len = sizeof ("@ ") + strlen (command) + strlen (float_type);
192 char *list_command = xmalloc (command_len + 1);
194 /* These are for the text following @listoffloats command.
195 Handling them with delayed writes is too late. */
199 sprintf (list_command, "@%s %s", command, float_type);
200 register_delayed_write (list_command);
203 else if (float_type_exists (float_type))
205 FLOAT_ELT *temp = (FLOAT_ELT *) reverse_list
206 ((GENERIC_LIST *) float_stack);
207 FLOAT_ELT *new_start = temp;
210 insert_string ("<ul class=\"listoffloats\">\n");
214 insert_string ("* Menu:\n\n");
219 if (strlen (temp->id) > 0 && STREQ (float_type, temp->type))
222 if (strlen (temp->shorttitle) > 0)
223 caption = expansion (temp->shorttitle, 0);
224 else if (strlen (temp->title) > 0)
225 caption = expansion (temp->title, 0);
231 /* A bit of space for HTML reabality. */
233 add_html_block_elt ("<li>");
235 /* Simply relying on @ref command doesn't work here, because
236 commas in the caption may confuse the argument parsing. */
237 add_word ("<a href=\"");
238 add_anchor_name (temp->id, 1);
241 if (strlen (float_type) > 0)
242 execute_string ("%s", float_type);
244 if (strlen (temp->id) > 0)
246 if (strlen (float_type) > 0)
249 add_word (temp->number);
254 if (strlen (float_type) > 0 || strlen (temp->id) > 0)
255 insert_string (": ");
256 execute_string ("%s", caption);
261 add_html_block_elt ("</li>\n");
269 int aux_chars_len; /* these are asterisk, colon, etc. */
270 int column_width; /* width of the first column in menus. */
271 int number_len; /* length of Figure X.Y: etc. */
274 /* Chosen widths are to match what @printindex produces. */
278 /* We have only one auxiliary character, NULL. */
279 aux_chars_len = sizeof ("");
284 /* We'll be adding an asterisk, followed by a space
285 and then a colon after the title, to construct a
287 aux_chars_len = sizeof ("* :");
290 /* Allocate enough space for possible expansion later. */
291 raw_entry = (char *) xmalloc (strlen (float_type)
292 + strlen (temp->number) + strlen (caption)
295 sprintf (raw_entry, "%s %s", float_type, temp->number);
297 if (strlen (caption) > 0)
298 strcat (raw_entry, ": ");
300 number_len = strlen (raw_entry);
302 len = strlen (caption) + strlen (raw_entry);
304 strcat (raw_entry, caption);
305 len = strlen (raw_entry);
307 if (len + aux_chars_len > column_width)
308 { /* Shorten long titles by looking for a space before
309 column_width - strlen (" ..."). */
310 /* -1 is for NULL, which is already in aux_chars_len. */
311 aux_chars_len += sizeof ("...") - 1;
312 len = column_width - aux_chars_len;
313 while (raw_entry[len] != ' ' && len >= 0)
316 /* Advance to the whitespace. */
319 /* If we are at the end of, say, Figure X.Y:, but
320 we have a title, then this means title does not
321 contain any whitespaces. Or it may be that we
322 went as far as the beginning. Just print as much
323 as possible of the title. */
325 || (len == number_len && strlen (caption) > 0))
326 len = column_width - sizeof ("...");
331 entry = xmalloc (len + aux_chars_len);
334 strcpy (entry, "* ");
338 strcat (entry, raw_entry);
339 strcat (entry, "...");
346 entry = xmalloc (len + aux_chars_len);
349 strcpy (entry, "* ");
353 strcat (entry, raw_entry);
359 insert_string (entry);
362 /* We insert space chars until ``column_width + four spaces''
363 is reached, to make the layout the same with what we produce
364 for @printindex. This is of course not obligatory, though
365 easier on the eye. -1 is for NULL. */
366 while (i < column_width + sizeof (" ") - 1)
374 if (strlen (temp->section) > 0)
375 { /* We got your number. */
376 insert_string ((char *) _("See "));
377 insert_string (temp->section);
380 { /* Sigh, @float in an @unnumbered. :-\ */
381 insert_string ("\n ");
382 insert_string ((char *) _("See "));
383 insert_string ("``");
384 insert_string (expansion (temp->section_name, 0));
385 insert_string ("''");
389 insert_string (temp->id);
391 insert_string (".\n");
396 if (strlen (caption) > 0)
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;