~ubuntu-branches/ubuntu/maverick/texinfo/maverick

« back to all changes in this revision

Viewing changes to makeinfo/float.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Preining
  • Date: 2005-10-28 15:10:30 UTC
  • mto: (2.1.1 dapper) (3.1.4 hardy)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20051028151030-9nsf2s2k2z3fktjt
Tags: upstream-4.8
ImportĀ upstreamĀ versionĀ 4.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* float.c -- float environment functions.
 
2
   $Id: float.c,v 1.8 2004/07/05 22:23:22 karl Exp $
 
3
 
 
4
   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
 
5
 
 
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)
 
9
   any later version.
 
10
 
 
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.
 
15
 
 
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.
 
19
 
 
20
   Originally written by Alper Ersoy <dirt@gtk.org>.  */
 
21
 
 
22
#include "system.h"
 
23
#include "makeinfo.h"
 
24
#include "cmds.h"
 
25
#include "files.h"
 
26
#include "float.h"
 
27
#include "html.h"
 
28
#include "sectioning.h"
 
29
#include "xml.h"
 
30
 
 
31
static FLOAT_ELT *float_stack = NULL;
 
32
 
 
33
void
 
34
add_new_float (char *id, char *title, char *shorttitle,
 
35
    char *type, char *position)
 
36
{
 
37
  FLOAT_ELT *new = xmalloc (sizeof (FLOAT_ELT));
 
38
  unsigned long num_len;
 
39
 
 
40
  new->id = id;
 
41
  new->type = type;
 
42
  new->title = title;
 
43
  new->shorttitle = shorttitle;
 
44
  new->position = position;
 
45
  new->title_used = 0;
 
46
  new->defining_line = line_number - 1;
 
47
 
 
48
  new->number = current_chapter_number ();
 
49
  /* Append dot if not @unnumbered.  */
 
50
  num_len = strlen (new->number);
 
51
  if (num_len > 0)
 
52
    {
 
53
      new->number = xrealloc (new->number, num_len + 1 + 1);
 
54
      new->number[num_len] = '.';
 
55
      new->number[num_len+1] = '\0';
 
56
    }
 
57
 
 
58
  { /* Append the current float number.  */
 
59
    unsigned len = strlen (new->number) + 21;  /* that's 64 bits */
 
60
    char *s = xmalloc (len + 1);
 
61
 
 
62
    sprintf (s, "%s%d", new->number,
 
63
                count_floats_of_type_in_chapter (text_expansion (type),
 
64
                                                 new->number) + 1); 
 
65
    free (new->number);
 
66
    new->number = xstrdup (s);
 
67
  }
 
68
 
 
69
  /* Plain text output needs sectioning number and its title,
 
70
     when listing floats.  */
 
71
  if (!html && !xml && no_headers)
 
72
    {
 
73
      new->section = current_sectioning_number ();
 
74
      if (strlen (new->section) == 0)
 
75
        new->section_name = current_sectioning_name ();
 
76
      else
 
77
        new->section_name = "";
 
78
    }
 
79
 
 
80
  new->next = float_stack;
 
81
  float_stack = new;
 
82
}
 
83
 
 
84
int
 
85
count_floats_of_type_in_chapter (char *type, char *chapter)
 
86
{
 
87
  int i = 0;
 
88
  int l = strlen (chapter);
 
89
  FLOAT_ELT *temp = float_stack;
 
90
 
 
91
  while (temp && strncmp (temp->number, chapter, l) == 0)
 
92
    {
 
93
      if (strlen (temp->id) > 0 && STREQ (text_expansion (temp->type), type))
 
94
        i++;
 
95
      temp = temp->next;
 
96
    }
 
97
 
 
98
  return i;
 
99
}
 
100
 
 
101
char *
 
102
current_float_title (void)
 
103
{
 
104
  return float_stack->title;
 
105
}
 
106
 
 
107
char *
 
108
current_float_shorttitle (void)
 
109
{
 
110
  return float_stack->shorttitle;
 
111
}
 
112
 
 
113
char *
 
114
current_float_type (void)
 
115
{
 
116
  return float_stack->type;
 
117
}
 
118
 
 
119
char *
 
120
current_float_position (void)
 
121
{
 
122
  return float_stack->position;
 
123
}
 
124
 
 
125
char *
 
126
current_float_number (void)
 
127
{
 
128
  return float_stack->number;
 
129
}
 
130
 
 
131
char *
 
132
current_float_id (void)
 
133
{
 
134
  return float_stack->id;
 
135
}
 
136
 
 
137
char *
 
138
get_float_ref (char *id)
 
139
{
 
140
  FLOAT_ELT *temp = float_stack;
 
141
 
 
142
  while (temp)
 
143
    {
 
144
      if (STREQ (id, temp->id))
 
145
        {
 
146
          char *s = xmalloc (strlen (temp->type) + strlen (temp->number) + 2);
 
147
          sprintf (s, "%s %s", temp->type, temp->number);
 
148
          return s;
 
149
        }
 
150
      temp = temp->next;
 
151
    }
 
152
 
 
153
  return NULL;
 
154
}
 
155
 
 
156
static int
 
157
float_type_exists (char *check_type)
 
158
{
 
159
  /* Check if the requested float_type exists in the floats stack.  */
 
160
  FLOAT_ELT *temp;
 
161
 
 
162
  for (temp = float_stack; temp; temp = temp->next)
 
163
    if (STREQ (temp->type, check_type) && temp->id && *temp->id)
 
164
      return 1;
 
165
 
 
166
  return 0;
 
167
}
 
168
 
 
169
void
 
170
cm_listoffloats (void)
 
171
{
 
172
  char *float_type;
 
173
  get_rest_of_line (1, &float_type);
 
174
 
 
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)
 
179
    line_number--;
 
180
 
 
181
  if (handling_delayed_writes && !float_type_exists (float_type))
 
182
    warning (_("Requested float type `%s' not previously used"), float_type);
 
183
 
 
184
  if (xml)
 
185
    {
 
186
      xml_insert_element_with_attribute (LISTOFFLOATS, START,
 
187
          "type=\"%s\"", text_expansion (float_type));
 
188
      xml_insert_element (LISTOFFLOATS, END);
 
189
    }
 
190
  else if (!handling_delayed_writes)
 
191
    {
 
192
      int command_len = sizeof ("@ ") + strlen (command) + strlen (float_type);
 
193
      char *list_command = xmalloc (command_len + 1);
 
194
 
 
195
      /* These are for the text following @listoffloats command.
 
196
         Handling them with delayed writes is too late.  */
 
197
      close_paragraph ();
 
198
      cm_noindent ();
 
199
 
 
200
      sprintf (list_command, "@%s %s", command, float_type);
 
201
      register_delayed_write (list_command);
 
202
      free (list_command);
 
203
    }
 
204
  else if (float_type_exists (float_type))
 
205
    {
 
206
      FLOAT_ELT *temp = (FLOAT_ELT *) reverse_list
 
207
        ((GENERIC_LIST *) float_stack);
 
208
      FLOAT_ELT *new_start = temp;
 
209
 
 
210
      if (html)
 
211
        insert_string ("<ul class=\"listoffloats\">\n");
 
212
      else
 
213
        {
 
214
          if (!no_headers)
 
215
            insert_string ("* Menu:\n\n");
 
216
        }
 
217
 
 
218
      while (temp)
 
219
        {
 
220
          if (strlen (temp->id) > 0 && STREQ (float_type, temp->type))
 
221
            {
 
222
              if (html)
 
223
                {
 
224
                  /* A bit of space for HTML reabality.  */
 
225
                  insert_string ("  ");
 
226
                  add_html_block_elt ("<li>");
 
227
 
 
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);
 
232
                  add_word ("\">");
 
233
 
 
234
                  if (strlen (float_type) > 0)
 
235
                    execute_string ("%s", float_type);
 
236
 
 
237
                  if (strlen (temp->id) > 0)
 
238
                    {
 
239
                      if (strlen (float_type) > 0)
 
240
                        add_char (' ');
 
241
 
 
242
                      add_word (temp->number);
 
243
                    }
 
244
 
 
245
                  if (strlen (temp->title) > 0)
 
246
                    {
 
247
                      if (strlen (float_type) > 0
 
248
                          || strlen (temp->id) > 0)
 
249
                        insert_string (": ");
 
250
 
 
251
                      execute_string ("%s", temp->title);
 
252
                    }
 
253
 
 
254
                  add_word ("</a>");
 
255
 
 
256
                  add_html_block_elt ("</li>\n");
 
257
                }
 
258
              else
 
259
                {
 
260
                  char *entry;
 
261
                  char *raw_entry;
 
262
                  char *title = expansion (temp->title, 0);
 
263
 
 
264
                  int len;
 
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.   */
 
268
                  int i = 0;
 
269
 
 
270
                  /* Chosen widths are to match what @printindex produces.  */
 
271
                  if (no_headers)
 
272
                    {
 
273
                      column_width = 43;
 
274
                      /* We have only one auxiliary character, NULL.  */
 
275
                      aux_chars_len = sizeof ("");
 
276
                    }
 
277
                  else
 
278
                    {
 
279
                      column_width = 37;
 
280
                      /* We'll be adding an asterisk, followed by a space
 
281
                         and then a colon after the title, to construct a
 
282
                         proper menu item.  */
 
283
                      aux_chars_len = sizeof ("* :");
 
284
                    }
 
285
 
 
286
                  /* Allocate enough space for possible expansion later.  */
 
287
                  raw_entry = (char *) xmalloc (strlen (float_type)
 
288
                      + strlen (temp->number) + strlen (title)
 
289
                      + sizeof (":  "));
 
290
 
 
291
                  sprintf (raw_entry, "%s %s", float_type, temp->number);
 
292
 
 
293
                  if (strlen (title) > 0)
 
294
                    strcat (raw_entry, ": ");
 
295
 
 
296
                  number_len = strlen (raw_entry);
 
297
 
 
298
                  len = strlen (title) + strlen (raw_entry);
 
299
 
 
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);
 
305
 
 
306
                  strcat (raw_entry, title);
 
307
                  len = strlen (raw_entry);
 
308
 
 
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)
 
316
                        len--;
 
317
 
 
318
                      /* Advance to the whitespace.  */
 
319
                      len++;
 
320
 
 
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.  */
 
326
                      if (len == 0
 
327
                          || (len == number_len && strlen (title) > 0))
 
328
                        len = column_width - sizeof ("...");
 
329
 
 
330
                      /* Break here.  */
 
331
                      raw_entry[len] = 0;
 
332
 
 
333
                      entry = xmalloc (len + aux_chars_len);
 
334
 
 
335
                      if (!no_headers)
 
336
                        strcpy (entry, "* ");
 
337
                      else
 
338
                        entry[0] = 0;
 
339
 
 
340
                      strcat (entry, raw_entry);
 
341
                      strcat (entry, "...");
 
342
 
 
343
                      if (!no_headers)
 
344
                        strcat (entry, ":");
 
345
                    }
 
346
                  else
 
347
                    {
 
348
                      entry = xmalloc (len + aux_chars_len);
 
349
 
 
350
                      if (!no_headers)
 
351
                        strcpy (entry, "* ");
 
352
                      else
 
353
                        entry[0] = 0;
 
354
 
 
355
                      strcat (entry, raw_entry);
 
356
 
 
357
                      if (!no_headers)
 
358
                        strcat (entry, ":");
 
359
                    }
 
360
 
 
361
                  insert_string (entry);
 
362
 
 
363
                  i = strlen (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)
 
369
                    {
 
370
                      insert (' ');
 
371
                      i++;
 
372
                    }
 
373
 
 
374
                  if (no_headers)
 
375
                    {
 
376
                      if (strlen (temp->section) > 0)
 
377
                        { /* We got your number.  */
 
378
                          insert_string ((char *) _("See "));
 
379
                          insert_string (temp->section);
 
380
                        }
 
381
                      else
 
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 ("''");
 
388
                        }
 
389
                    }
 
390
                  else
 
391
                    insert_string (temp->id);
 
392
 
 
393
                  insert_string (".\n");
 
394
 
 
395
                  free (entry);
 
396
                  free (title);
 
397
                }
 
398
            }
 
399
          temp = temp->next;
 
400
        }
 
401
 
 
402
      if (html)
 
403
        {
 
404
          inhibit_paragraph_indentation = 1;
 
405
          insert_string ("</ul>\n\n");
 
406
        }
 
407
      else
 
408
        insert ('\n');
 
409
 
 
410
      /* Retain the original order of float stack.  */
 
411
      temp = new_start;
 
412
      float_stack = (FLOAT_ELT *) reverse_list ((GENERIC_LIST *) temp);
 
413
    }
 
414
 
 
415
  free (float_type);
 
416
  /* Re-increment the line number, because get_rest_of_line
 
417
     left us looking at the next line after the command.  */
 
418
  line_number++;
 
419
}
 
420
 
 
421
int
 
422
current_float_used_title (void)
 
423
{
 
424
        return float_stack->title_used;
 
425
}
 
426
 
 
427
void current_float_set_title_used (void)
 
428
{
 
429
        float_stack->title_used = 1;
 
430
}