/* float.c -- float environment functions. $Id: float.c,v 1.8 2004/07/05 22:23:22 karl Exp $ Copyright (C) 2003, 2004 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Originally written by Alper Ersoy . */ #include "system.h" #include "makeinfo.h" #include "cmds.h" #include "files.h" #include "float.h" #include "html.h" #include "sectioning.h" #include "xml.h" static FLOAT_ELT *float_stack = NULL; void add_new_float (char *id, char *title, char *shorttitle, char *type, char *position) { FLOAT_ELT *new = xmalloc (sizeof (FLOAT_ELT)); unsigned long num_len; new->id = id; new->type = type; new->title = title; new->shorttitle = shorttitle; new->position = position; new->title_used = 0; new->defining_line = line_number - 1; new->number = current_chapter_number (); /* Append dot if not @unnumbered. */ num_len = strlen (new->number); if (num_len > 0) { new->number = xrealloc (new->number, num_len + 1 + 1); new->number[num_len] = '.'; new->number[num_len+1] = '\0'; } { /* Append the current float number. */ unsigned len = strlen (new->number) + 21; /* that's 64 bits */ char *s = xmalloc (len + 1); sprintf (s, "%s%d", new->number, count_floats_of_type_in_chapter (text_expansion (type), new->number) + 1); free (new->number); new->number = xstrdup (s); } /* Plain text output needs sectioning number and its title, when listing floats. */ if (!html && !xml && no_headers) { new->section = current_sectioning_number (); if (strlen (new->section) == 0) new->section_name = current_sectioning_name (); else new->section_name = ""; } new->next = float_stack; float_stack = new; } int count_floats_of_type_in_chapter (char *type, char *chapter) { int i = 0; int l = strlen (chapter); FLOAT_ELT *temp = float_stack; while (temp && strncmp (temp->number, chapter, l) == 0) { if (strlen (temp->id) > 0 && STREQ (text_expansion (temp->type), type)) i++; temp = temp->next; } return i; } char * current_float_title (void) { return float_stack->title; } char * current_float_shorttitle (void) { return float_stack->shorttitle; } char * current_float_type (void) { return float_stack->type; } char * current_float_position (void) { return float_stack->position; } char * current_float_number (void) { return float_stack->number; } char * current_float_id (void) { return float_stack->id; } char * get_float_ref (char *id) { FLOAT_ELT *temp = float_stack; while (temp) { if (STREQ (id, temp->id)) { char *s = xmalloc (strlen (temp->type) + strlen (temp->number) + 2); sprintf (s, "%s %s", temp->type, temp->number); return s; } temp = temp->next; } return NULL; } static int float_type_exists (char *check_type) { /* Check if the requested float_type exists in the floats stack. */ FLOAT_ELT *temp; for (temp = float_stack; temp; temp = temp->next) if (STREQ (temp->type, check_type) && temp->id && *temp->id) return 1; return 0; } void cm_listoffloats (void) { char *float_type; get_rest_of_line (1, &float_type); /* get_rest_of_line increments the line number by one, so to make warnings/errors point to the correct line, we decrement the line_number again. */ if (!handling_delayed_writes) line_number--; if (handling_delayed_writes && !float_type_exists (float_type)) warning (_("Requested float type `%s' not previously used"), float_type); if (xml) { xml_insert_element_with_attribute (LISTOFFLOATS, START, "type=\"%s\"", text_expansion (float_type)); xml_insert_element (LISTOFFLOATS, END); } else if (!handling_delayed_writes) { int command_len = sizeof ("@ ") + strlen (command) + strlen (float_type); char *list_command = xmalloc (command_len + 1); /* These are for the text following @listoffloats command. Handling them with delayed writes is too late. */ close_paragraph (); cm_noindent (); sprintf (list_command, "@%s %s", command, float_type); register_delayed_write (list_command); free (list_command); } else if (float_type_exists (float_type)) { FLOAT_ELT *temp = (FLOAT_ELT *) reverse_list ((GENERIC_LIST *) float_stack); FLOAT_ELT *new_start = temp; if (html) insert_string ("\n\n"); } else insert ('\n'); /* Retain the original order of float stack. */ temp = new_start; float_stack = (FLOAT_ELT *) reverse_list ((GENERIC_LIST *) temp); } free (float_type); /* Re-increment the line number, because get_rest_of_line left us looking at the next line after the command. */ line_number++; } int current_float_used_title (void) { return float_stack->title_used; } void current_float_set_title_used (void) { float_stack->title_used = 1; }