1
1
/* node.c -- nodes for Texinfo.
2
$Id: node.c,v 1.31 2002/02/23 19:12:15 karl Exp $
2
$Id: node.c,v 1.27 2004/12/20 23:56:07 karl Exp $
4
Copyright (C) 1998, 99, 2000, 01, 02 Free Software Foundation, Inc.
4
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
6
7
This program is free software; you can redistribute it and/or modify
7
8
it under the terms of the GNU General Public License as published by
115
write_tag_table (char *filename)
117
output_stream = fopen (filename, "a");
116
124
write_tag_table_internal (0); /* Not indirect. */
126
if (fclose (output_stream) != 0)
120
write_tag_table_indirect ()
131
write_tag_table_indirect (void)
122
133
write_tag_table_internal (1);
125
136
/* Convert "top" and friends into "Top". */
127
normalize_node_name (string)
138
normalize_node_name (char *string)
130
140
if (strcasecmp (string, "Top") == 0)
131
141
strcpy (string, "Top");
135
get_node_token (expand)
145
get_node_token (int expand)
264
269
/* Remember NODE and associates. */
266
remember_node (node, prev, next, up, position, line_no, fname, flags)
267
char *node, *prev, *next, *up, *fname;
268
int position, line_no, flags;
271
remember_node (char *node, char *prev, char *next, char *up,
272
int position, int line_no, char *fname, int flags)
270
274
/* Check for existence of this tag already. */
468
476
/* Set the name of the current output file. */
470
set_current_output_filename (fname)
478
set_current_output_filename (const char *fname)
473
480
if (current_output_filename)
474
481
free (current_output_filename);
475
482
current_output_filename = xstrdup (fname);
486
/* Output the <a name="..."></a> constructs for NODE. We output both
487
the new-style conversion and the old-style, if they are different.
488
See comments at `add_escaped_anchor_name' in html.c. */
491
add_html_names (char *node)
493
char *tem = expand_node_name (node);
494
char *otem = xstrdup (tem);
496
/* Determine if the old and new schemes come up with different names;
497
only output the old scheme if that is so. We don't want to output
498
the same name twice. */
504
for (; *optr; optr++)
506
if (!cr_or_whitespace (*optr) && !URL_SAFE_CHAR (*optr))
515
add_word ("<a name=\"");
516
add_anchor_name (otem, -1); /* old anchor name conversion */
517
add_word ("\"></a>\n");
522
/* Always output the new scheme. */
524
add_word ("<a name=\"");
525
add_anchor_name (tem, 0);
526
add_word ("\"></a>\n");
478
532
/* The order is: nodename, nextnode, prevnode, upnode.
479
533
If all of the NEXT, PREV, and UP fields are empty, they are defaulted.
480
534
You must follow a node command which has those fields defaulted
481
with a sectioning command (e.g. @chapter) giving the "level" of that node.
535
with a sectioning command (e.g., @chapter) giving the "level" of that node.
482
536
It is an error not to do so.
483
537
The defaults come from the menu in this node's parent. */
487
541
static long epilogue_len = 0L;
488
542
char *node, *prev, *next, *up;
589
643
filling_enabled = indented_fill = 0;
590
644
if (!html || (html && splitting))
591
645
current_footnote_number = 1;
593
647
if (verbose_mode)
594
648
printf (_("Formatting node %s...\n"), node);
596
650
if (macro_expansion_output_stream && !executing_string)
597
651
remember_itext (input_text, input_text_offset);
653
/* Reset the line number in each node for Info output, so that
654
index entries will save the line numbers of parent node. */
655
node_line_number = 0;
602
xml_begin_document ();
660
xml_begin_document (current_output_filename);
603
661
xml_begin_node ();
606
xml_insert_element (NODENAME, START);
664
xml_insert_element (NODENAME, START);
607
665
if (macro_expansion_output_stream && !executing_string)
608
666
me_execute_string (node);
907
971
if (!splitting && no_headers)
908
{ /* cross refs need a name="#anchor" even if we're not writing headers*/
909
add_word ("<a name=\"");
910
tem = expand_node_name (node);
911
add_anchor_name (tem, 0);
912
add_word ("\"></a>");
972
{ /* cross refs need a name="#anchor" even if not writing headers */
973
add_html_names (node);
916
976
if (splitting || !no_headers)
917
{ /* Navigation bar. The <p> avoids the links area running
918
on with old Lynxen. */
977
{ /* Navigation bar. */
978
add_html_block_elt ("<div class=\"node\">\n");
979
/* The <p> avoids the links area running on with old Lynxen. */
919
980
add_word_args ("<p>%s\n", splitting ? "" : "<hr>");
920
add_word_args ("%s<a name=\"", _("Node:"));
921
tem = expand_node_name (node);
922
add_anchor_name (tem, 0);
923
add_word_args ("\">%s</a>", tem);
982
/* In the split HTML case, the filename is wrong for the
983
old-style converted names, but we'll add them anyway, for
984
consistency. (And we need them in the normal (not
985
no_headers) nonsplit case.) */
986
add_html_names (node);
928
990
tem = expansion (next, 0);
930
add_word (_("Next:"));
931
add_word ("<a rel=next href=\"");
991
add_word ((char *) _("Next:"));
994
add_word ("<a rel=\"next\" accesskey=\"n\" href=\"");
932
995
add_anchor_name (tem, 1);
996
tem = escape_string (tem);
933
997
add_word_args ("\">%s</a>", tem);
938
1006
tem = expansion (prev, 0);
940
add_word (_("Previous:"));
941
add_word ("<a rel=previous href=\"");
1007
add_word ((char *) _("Previous:"));
1008
add_word (" ");
1009
add_word ("<a rel=\"previous\" accesskey=\"p\" href=\"");
942
1010
add_anchor_name (tem, 1);
1011
tem = escape_string (tem);
943
1012
add_word_args ("\">%s</a>", tem);
948
1020
tem = expansion (up, 0);
951
add_word ("<a rel=up href=\"");
1021
add_word ((char *) _("Up:"));
1022
add_word (" ");
1023
add_word ("<a rel=\"up\" accesskey=\"u\" href=\"");
952
1024
add_anchor_name (tem, 1);
1025
tem = escape_string (tem);
953
1026
add_word_args ("\">%s</a>", tem);
956
1029
/* html fixxme: we want a `top' or `contents' link here. */
958
add_word_args ("\n%s<br>\n", splitting ? "<hr>" : "");
1031
add_word_args ("\n%s\n", splitting ? "<hr>" : "");
1032
add_word ("</div>\n");
961
1035
else if (docbook)
1149
1225
xml_insert_element (ANCHOR, END);
1151
1227
/* Save it in the tag table. */
1152
remember_node (anchor, NULL, NULL, NULL, output_position + output_column,
1228
remember_node (anchor, NULL, NULL, NULL,
1229
output_position + output_paragraph_offset,
1153
1230
line_number, fname_for_anchor, TAG_FLAG_ANCHOR);
1156
1233
/* Find NODE in REF_LIST. */
1157
1234
static NODE_REF *
1158
find_node_reference (node, ref_list)
1235
find_node_reference (char *node, NODE_REF *ref_list)
1162
1237
NODE_REF *orig_ref_list = ref_list;
1163
1238
char *expanded_node;
1369
1437
tem1 = expand_node_name (prev);
1370
1438
tem2 = expand_node_name (tags->node);
1372
if (STREQ (tem1, tem2))
1440
if (tem1 && tem2 && STREQ (tem1, tem2))
1379
line_error (_("Next field of node `%s' not pointed to"),
1447
line_error (_("Next field of node `%s' not pointed to (perhaps incorrect sectioning?)"),
1381
1449
file_line_error (temp_tag->filename, temp_tag->line_no,
1382
1450
_("This node (%s) has the bad Prev"),
1665
enumerate_filename (char *pathname, char *basename, int number)
1667
/* Do we need to generate names of subfiles which don't exceed 8+3 limits? */
1668
const int dos_file_names = !HAVE_LONG_FILENAMES (pathname ? pathname : ".");
1669
unsigned name_len = strlen (basename);
1670
char *filename = xmalloc (10 + strlen (pathname) + name_len);
1671
char *base_filename = xmalloc (10 + name_len);
1673
sprintf (base_filename, "%s-%d", basename, number);
1677
char *dot = strchr (base_filename, '.');
1678
unsigned base_len = strlen (base_filename);
1681
{ /* Make foobar.i1, .., foobar.i99, foobar.100, ... */
1683
memmove (number <= 99 ? dot + 2 : dot + 1,
1684
base_filename + name_len + 1,
1685
strlen (base_filename + name_len + 1) + 1);
1687
else if (base_len > 8)
1689
/* Make foobar-1, .., fooba-10, .., foob-100, ... */
1690
unsigned numlen = base_len - name_len;
1692
memmove (base_filename + 8 - numlen, base_filename + name_len, numlen + 1);
1696
sprintf (filename, "%s%s", pathname, base_filename);
1701
/* Remove previously split files, to avoid
1702
lingering parts of shrinked documents. */
1704
clean_old_split_files (char *filename)
1706
char *root_filename = filename_part (filename);
1707
char *root_pathname = pathname_part (filename);
1710
/* We break as soon as we hit an inexistent file,
1711
so looping until large numbers is harmless. */
1712
for (i = 1; i < 1000; i++)
1715
char *check_file = enumerate_filename (root_pathname, root_filename, i);
1717
if (stat (check_file, &st) != 0)
1719
else if (!S_ISDIR (st.st_mode))
1721
/* Give feedback if requested, removing a file is important. */
1723
printf (_("Removing %s\n"), check_file);
1725
/* Warn user that we cannot remove the file. */
1726
if (unlink (check_file) != 0)
1727
warning (_("Can't remove file `%s': %s"), check_file, strerror (errno));
1597
1735
/* Split large output files into a series of smaller files. Each file
1598
1736
is pointed to in the tag table, which then gets written out as the
1599
1737
original file. The new files have the same name as the original file
1600
1738
with a "-num" attached. SIZE is the largest number of bytes to allow
1601
1739
in any single split file. */
1603
split_file (filename, size)
1741
split_file (char *filename, int size)
1607
1743
char *root_filename, *root_pathname;
1608
char *the_file, *filename_part ();
1609
1745
struct stat fileinfo;
1610
1746
long file_size;
1611
1747
char *the_header;
1612
1748
int header_size;
1613
int dos_file_names = 0; /* if nonzero, don't exceed 8+3 limits */
1615
1750
/* Can only do this to files with tag tables. */
1616
1751
if (!tag_table)
1620
1755
size = DEFAULT_SPLIT_SIZE;
1622
if ((stat (filename, &fileinfo) != 0) ||
1623
(((long) fileinfo.st_size) < SPLIT_SIZE_THRESHOLD))
1757
if ((stat (filename, &fileinfo) != 0)
1758
|| (((long) fileinfo.st_size) < size))
1625
1760
file_size = (long) fileinfo.st_size;
1627
the_file = find_and_load (filename);
1762
the_file = find_and_load (filename, 0);
1631
1766
root_filename = filename_part (filename);
1632
1767
root_pathname = pathname_part (filename);
1634
/* Do we need to generate names of subfiles which don't exceed 8+3 limits? */
1635
dos_file_names = !HAVE_LONG_FILENAMES (root_pathname ? root_pathname : ".");
1637
1769
if (!root_pathname)
1638
1770
root_pathname = xstrdup ("");
1735
char *split_filename, *split_basename;
1736
unsigned root_len = strlen (root_filename);
1738
split_filename = xmalloc (10 + strlen (root_pathname)
1740
split_basename = xmalloc (10 + root_len);
1741
sprintf (split_basename, "%s-%d", root_filename, which_file);
1744
char *dot = strchr (split_basename, '.');
1745
unsigned base_len = strlen (split_basename);
1748
{ /* Make foobar.i1, .., foobar.i99, foobar.100, ... */
1750
memmove (which_file <= 99 ? dot + 2 : dot + 1,
1751
split_basename + root_len + 1,
1752
strlen (split_basename + root_len + 1) + 1);
1754
else if (base_len > 8)
1756
/* Make foobar-1, .., fooba-10, .., foob-100, ... */
1757
unsigned numlen = base_len - root_len;
1759
memmove (split_basename + 8 - numlen,
1760
split_basename + root_len, numlen + 1);
1763
sprintf (split_filename, "%s%s", root_pathname,
1871
char *split_filename = enumerate_filename (root_pathname,
1872
root_filename, which_file);
1873
char *split_basename = filename_part (split_filename);
1766
1875
fd = open (split_filename, O_WRONLY|O_TRUNC|O_CREAT, 0666);
1768
1877
|| write (fd, the_header, header_size) != header_size
1769
1878
|| write (fd, the_file + file_top, file_bot - file_top)
1770
1879
!= (file_bot - file_top)
1771
|| (close (fd)) < 0)
1881
&& write (fd, trailer, trailer_len) != trailer_len)
1773
1884
perror (split_filename);