123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431 |
- /* float.c -- float environment functions.
- $Id: float.c,v 1.12 2007-07-01 21:20:32 karl Exp $
- Copyright (C) 2003, 2004, 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
- Originally written by Alper Ersoy <dirt@gtk.org>. */
- #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 ("<ul class=\"listoffloats\">\n");
- else
- {
- if (!no_headers)
- insert_string ("* Menu:\n\n");
- }
- while (temp)
- {
- if (strlen (temp->id) > 0 && STREQ (float_type, temp->type))
- {
- char *caption;
- if (strlen (temp->shorttitle) > 0)
- caption = expansion (temp->shorttitle, 0);
- else if (strlen (temp->title) > 0)
- caption = expansion (temp->title, 0);
- else
- caption = "";
-
- if (html)
- {
- /* A bit of space for HTML reabality. */
- insert_string (" ");
- add_html_block_elt ("<li>");
- /* Simply relying on @ref command doesn't work here, because
- commas in the caption may confuse the argument parsing. */
- add_word ("<a href=\"");
- add_anchor_name (temp->id, 1);
- add_word ("\">");
- if (strlen (float_type) > 0)
- execute_string ("%s", float_type);
- if (strlen (temp->id) > 0)
- {
- if (strlen (float_type) > 0)
- add_char (' ');
- add_word (temp->number);
- }
- if (caption)
- {
- if (strlen (float_type) > 0 || strlen (temp->id) > 0)
- insert_string (": ");
- execute_string ("%s", caption);
- }
- add_word ("</a>");
- add_html_block_elt ("</li>\n");
- }
- else
- {
- char *entry;
- char *raw_entry;
- int len;
- int aux_chars_len; /* these are asterisk, colon, etc. */
- int column_width; /* width of the first column in menus. */
- int number_len; /* length of Figure X.Y: etc. */
- int i = 0;
- /* Chosen widths are to match what @printindex produces. */
- if (no_headers)
- {
- column_width = 43;
- /* We have only one auxiliary character, NULL. */
- aux_chars_len = sizeof ("");
- }
- else
- {
- column_width = 37;
- /* We'll be adding an asterisk, followed by a space
- and then a colon after the title, to construct a
- proper menu item. */
- aux_chars_len = sizeof ("* :");
- }
- /* Allocate enough space for possible expansion later. */
- raw_entry = (char *) xmalloc (strlen (float_type)
- + strlen (temp->number) + strlen (caption)
- + sizeof (": "));
- sprintf (raw_entry, "%s %s", float_type, temp->number);
- if (strlen (caption) > 0)
- strcat (raw_entry, ": ");
- number_len = strlen (raw_entry);
- len = strlen (caption) + strlen (raw_entry);
- strcat (raw_entry, caption);
- len = strlen (raw_entry);
- if (len + aux_chars_len > column_width)
- { /* Shorten long titles by looking for a space before
- column_width - strlen (" ..."). */
- /* -1 is for NULL, which is already in aux_chars_len. */
- aux_chars_len += sizeof ("...") - 1;
- len = column_width - aux_chars_len;
- while (raw_entry[len] != ' ' && len >= 0)
- len--;
- /* Advance to the whitespace. */
- len++;
- /* If we are at the end of, say, Figure X.Y:, but
- we have a title, then this means title does not
- contain any whitespaces. Or it may be that we
- went as far as the beginning. Just print as much
- as possible of the title. */
- if (len == 0
- || (len == number_len && strlen (caption) > 0))
- len = column_width - sizeof ("...");
- /* Break here. */
- raw_entry[len] = 0;
- entry = xmalloc (len + aux_chars_len);
- if (!no_headers)
- strcpy (entry, "* ");
- else
- entry[0] = 0;
- strcat (entry, raw_entry);
- strcat (entry, "...");
- if (!no_headers)
- strcat (entry, ":");
- }
- else
- {
- entry = xmalloc (len + aux_chars_len);
- if (!no_headers)
- strcpy (entry, "* ");
- else
- entry[0] = 0;
- strcat (entry, raw_entry);
- if (!no_headers)
- strcat (entry, ":");
- }
- insert_string (entry);
- i = strlen (entry);
- /* We insert space chars until ``column_width + four spaces''
- is reached, to make the layout the same with what we produce
- for @printindex. This is of course not obligatory, though
- easier on the eye. -1 is for NULL. */
- while (i < column_width + sizeof (" ") - 1)
- {
- insert (' ');
- i++;
- }
- if (no_headers)
- {
- if (strlen (temp->section) > 0)
- { /* We got your number. */
- insert_string ((char *) _("See "));
- insert_string (temp->section);
- }
- else
- { /* Sigh, @float in an @unnumbered. :-\ */
- insert_string ("\n ");
- insert_string ((char *) _("See "));
- insert_string ("``");
- insert_string (expansion (temp->section_name, 0));
- insert_string ("''");
- }
- }
- else
- insert_string (temp->id);
- insert_string (".\n");
- free (entry);
- }
-
- if (strlen (caption) > 0)
- free (caption);
- }
- temp = temp->next;
- }
- if (html)
- {
- inhibit_paragraph_indentation = 1;
- insert_string ("</ul>\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;
- }
|