30
30
#include "makeinfo.h"
31
31
#include "sectioning.h"
36
35
/* array of toc entries */
37
36
static TOC_ENTRY_ELT **toc_entry_alist = NULL;
39
38
/* toc_counter start from 0 ... n for every @chapter, @section ... */
40
39
static int toc_counter = 0;
42
/* the file where we found the @contents directive */
43
char *contents_filename;
45
/* the file where we found the @shortcontents directive */
46
char *shortcontents_filename;
48
static const char contents_placebo[] = "\n...Table of Contents...\n";
49
static const char shortcontents_placebo[] = "\n...Short Contents...\n";
50
static const char lots_of_stars[] =
51
"***************************************************************************";
54
41
/* Routine to add an entry to the table of contents */
56
toc_add_entry (tocname, level, node_name, anchor)
43
toc_add_entry (char *tocname, int level, char *node_name, char *anchor)
62
char *tocname_and_node, *expanded_node, *s, *d;
45
char *tocname_and_node, *expanded_node, *d;
63
47
char *filename = NULL;
77
/* We need to insert the expanded node name into the TOC, so
78
that when we eventually output the TOC, its <A REF= link will
79
point to the <A NAME= tag created by cm_node in the navigation
61
/* We need to insert the expanded node name into the toc, so
62
that when we eventually output the toc, its <a ref= link will
63
point to the <a name= tag created by cm_node in the navigation
80
64
bar. We cannot expand the containing_node member, for the
81
65
reasons explained in the WARNING below. We also cannot wait
82
with the node name expansion until the TOC is actually output,
66
with the node name expansion until the toc is actually output,
83
67
since by that time the macro definitions may have been changed.
84
68
So instead we store in the tocname member the expanded node
85
name and the TOC name concatenated together (with the necessary
86
HTML markup), since that's how they are output. */
69
name and the toc name concatenated together (with the necessary
70
html markup), since that's how they are output. */
88
72
s = expanded_node = expand_node_name (node_name);
293
268
if (!toc_counter)
296
flush_output (); /* in case we are writing stdout */
298
fprintf (fp, "%s\n%.*s\n\n", _("Table of Contents"),
299
(int) strlen (_("Table of Contents")), lots_of_stars);
271
insert_string ((char *) _("Table of Contents"));
273
for (i = 0; i < strlen (_("Table of Contents")); i++)
275
insert_string ("\n\n");
301
277
for (i = 0; i < toc_counter; i++)
303
279
if (toc_entry_alist[i]->level == 0)
306
282
/* indention with two spaces per level, should this
308
284
for (k = 0; k < toc_entry_alist[i]->level; k++)
311
fprintf (fp, "%s\n", toc_entry_alist[i]->name);
287
insert_string (toc_entry_alist[i]->name);
290
insert_string ("\n\n");
316
293
/* shortcontents in HTML; Should this produce a standalone file? */
318
shortcontents_update_html (fp)
295
shortcontents_update_html (char *contents_filename)
298
char *toc_file = NULL;
324
300
/* does exist any toc? */
325
301
if (!toc_counter)
328
flush_output (); /* in case we are writing stdout */
330
fprintf (fp, "\n<h2>%s</h2>\n<ul>\n", _("Short Contents"));
304
add_html_block_elt_args ("\n<div class=\"shortcontents\">\n<h2>%s</h2>\n<ul>\n", _("Short Contents"));
332
306
if (contents_filename)
333
307
toc_file = filename_part (contents_filename);
339
313
if (toc_entry_alist[i]->level == 0)
341
315
if (contents_filename)
342
fprintf (fp, "<li><a href=\"%s#toc_%s</a>\n",
316
add_word_args ("<li><a href=\"%s#toc_%s</a></li>\n",
343
317
splitting ? toc_file : "", name);
345
fprintf (fp, "<a href=\"%s#%s</a>\n",
319
add_word_args ("<a href=\"%s#%s</a>\n",
346
320
splitting ? toc_entry_alist[i]->html_file : "", name);
349
fputs ("</ul>\n\n", fp);
323
add_word ("</ul>\n</div>\n\n");
350
324
if (contents_filename)
354
328
/* short contents in ASCII (--no-headers). */
356
shortcontents_update_info (fp)
330
shortcontents_update_info (void)
361
334
if (!toc_counter)
364
flush_output (); /* in case we are writing stdout */
366
fprintf (fp, "%s\n%.*s\n\n", _("Short Contents"),
367
(int) strlen (_("Short Contents")), lots_of_stars);
337
insert_string ((char *) _("Short Contents"));
339
for (i = 0; i < strlen (_("Short Contents")); i++)
341
insert_string ("\n\n");
369
343
for (i = 0; i < toc_counter; i++)
371
345
if (toc_entry_alist[i]->level == 0)
372
fprintf (fp, "%s\n", toc_entry_alist[i]->name);
379
static char *toc_buf;
382
rewrite_top (fname, placebo)
383
const char *fname, *placebo;
387
/* Can't rewrite standard output or the null device. No point in
389
if (STREQ (fname, "-")
390
|| FILENAME_CMP (fname, NULL_DEVICE) == 0
391
|| FILENAME_CMP (fname, ALSO_NULL_DEVICE) == 0)
394
toc_buf = find_and_load (fname);
402
idx = search_forward (placebo, 0);
406
error (_("%s: TOC should be here, but it was not found"), fname);
410
toc_fp = fopen (fname, "w");
417
if (fwrite (toc_buf, 1, idx, toc_fp) != idx)
423
return idx + strlen (placebo);
429
int cont_idx = rewrite_top (contents_filename, contents_placebo);
435
contents_update_html (toc_fp);
437
contents_update_info (toc_fp);
439
if (fwrite (toc_buf + cont_idx, 1, input_text_length - cont_idx, toc_fp)
440
!= input_text_length - cont_idx
441
|| fclose (toc_fp) != 0)
442
fs_error (contents_filename);
446
shortcontents_update ()
448
int cont_idx = rewrite_top (shortcontents_filename, shortcontents_placebo);
454
shortcontents_update_html (toc_fp);
456
shortcontents_update_info (toc_fp);
458
if (fwrite (toc_buf + cont_idx, 1, input_text_length - cont_idx - 1, toc_fp)
459
!= input_text_length - cont_idx - 1
460
|| fclose (toc_fp) != 0)
461
fs_error (shortcontents_filename);
467
if (!html && !no_headers)
470
if (contents_filename)
472
if (shortcontents_filename)
473
shortcontents_update ();
480
if ((html || no_headers) && arg == START)
482
if (contents_filename)
484
free (contents_filename);
485
contents_filename = NULL;
488
if (contents_filename && STREQ (contents_filename, "-"))
491
contents_update_html (stdout);
493
contents_update_info (stdout);
497
if (!executing_string && html)
347
insert_string (toc_entry_alist[i]->name);
351
insert_string ("\n\n");
355
cm_contents (int arg)
357
/* the file where we found the @contents directive */
358
static char *contents_filename;
360
/* No need to mess with delayed stuff for XML and Docbook. */
365
int elt = STREQ (command, "contents") ? CONTENTS : SHORTCONTENTS;
366
xml_insert_element (elt, START);
367
xml_insert_element (elt, END);
370
else if (!handling_delayed_writes)
372
register_delayed_write (STREQ (command, "contents")
373
? "@contents" : "@shortcontents");
375
if (html && STREQ (command, "contents"))
377
if (contents_filename)
378
free (contents_filename);
499
379
contents_filename = xstrdup (current_output_filename);
500
insert_string (contents_placebo); /* just mark it, for now */
506
cm_shortcontents (arg)
509
if ((html || no_headers) && arg == START)
511
if (shortcontents_filename)
513
free (shortcontents_filename);
514
shortcontents_filename = NULL;
517
if (shortcontents_filename && STREQ (shortcontents_filename, "-"))
520
shortcontents_update_html (stdout);
522
shortcontents_update_info (stdout);
526
if (!executing_string && html)
528
shortcontents_filename = xstrdup (current_output_filename);
529
insert_string (shortcontents_placebo); /* just mark it, for now */
383
STREQ (command, "contents")
384
? contents_update_html () : shortcontents_update_html (contents_filename);
386
STREQ (command, "contents")
387
? contents_update_info () : shortcontents_update_info ();