summaryrefslogtreecommitdiff
path: root/makeinfo/float.c
diff options
context:
space:
mode:
Diffstat (limited to 'makeinfo/float.c')
-rw-r--r--makeinfo/float.c430
1 files changed, 430 insertions, 0 deletions
diff --git a/makeinfo/float.c b/makeinfo/float.c
new file mode 100644
index 0000000..8866ffb
--- /dev/null
+++ b/makeinfo/float.c
@@ -0,0 +1,430 @@
+/* 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;
+}