3 /* index.c -- indexing for Texinfo.
4 Id: index.c,v 1.17 2004/11/30 02:03:23 karl Exp
6 Copyright (C) 1998, 1999, 2002, 2003, 2004 Free Software Foundation,
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software Foundation,
21 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
30 #include "sectioning.h"
34 INDEX_ALIST
**name_index_alist
= NULL
;
36 /* An array of pointers. Each one is for a different index. The
37 "synindex" command changes which array slot is pointed to by a
39 INDEX_ELT
**the_indices
= NULL
;
41 /* The number of defined indices. */
42 int defined_indices
= 0;
44 /* This is the order of the index. */
45 int index_counter
= 0;
47 /* Stuff for defining commands on the fly. */
48 COMMAND
**user_command_array
= NULL
;
49 int user_command_array_len
= 0;
51 /* How to compare index entries for sorting. May be set to strcoll. */
52 int (*index_compare_fn
) (const char *a
, const char *b
) = strcasecmp
;
54 /* Function to compare index entries for sorting. (Calls
55 `index_compare_fn' above.) */
56 int index_element_compare (const void *element1
, const void *element2
);
58 /* Find which element in the known list of indices has this name.
59 Returns -1 if NAME isn't found. */
61 find_index_offset (char *name
)
64 for (i
= 0; i
< defined_indices
; i
++)
65 if (name_index_alist
[i
] && STREQ (name
, name_index_alist
[i
]->name
))
70 /* Return a pointer to the entry of (name . index) for this name.
71 Return NULL if the index doesn't exist. */
73 find_index (char *name
)
75 int offset
= find_index_offset (name
);
77 return name_index_alist
[offset
];
82 /* User-defined commands, which happens only from user-defined indexes.
83 Used to initialize the builtin indices, too. */
85 define_user_command (char *name
, COMMAND_FUNCTION (*proc
), int needs_braces_p
)
87 int slot
= user_command_array_len
;
88 user_command_array_len
++;
90 if (!user_command_array
)
91 user_command_array
= xmalloc (1 * sizeof (COMMAND
*));
93 user_command_array
= xrealloc (user_command_array
,
94 (1 + user_command_array_len
) * sizeof (COMMAND
*));
96 user_command_array
[slot
] = xmalloc (sizeof (COMMAND
));
97 user_command_array
[slot
]->name
= xstrdup (name
);
98 user_command_array
[slot
]->proc
= proc
;
99 user_command_array
[slot
]->argument_in_braces
= needs_braces_p
;
102 /* Please release me, let me go... */
104 free_index (INDEX_ELT
*index
)
108 while ((temp
= index
))
111 free (temp
->entry_text
);
112 /* Do not free the node, because we already freed the tag table,
113 which freed all the node names. */
114 /* free (temp->node); */
120 /* Flush an index by name. This will delete the list of entries that
121 would be written by a @printindex command for this index. */
123 undefindex (char *name
)
126 int which
= find_index_offset (name
);
128 /* The index might have already been freed if this was the target of
130 if (which
< 0 || !name_index_alist
[which
])
133 i
= name_index_alist
[which
]->read_index
;
135 free_index (the_indices
[i
]);
136 the_indices
[i
] = NULL
;
138 free (name_index_alist
[which
]->name
);
139 free (name_index_alist
[which
]);
140 name_index_alist
[which
] = NULL
;
143 /* Add the arguments to the current index command to the index NAME. */
145 index_add_arg (char *name
)
151 tem
= find_index (name
);
153 which
= tem
? tem
->write_index
: -1;
155 if (macro_expansion_output_stream
&& !executing_string
)
156 append_to_expansion_output (input_text_offset
+ 1);
158 get_rest_of_line (0, &index_entry
);
159 ignore_blank_line ();
161 if (macro_expansion_output_stream
&& !executing_string
)
163 char *index_line
= xmalloc (strlen (index_entry
) + 2);
164 sprintf (index_line
, "%s\n", index_entry
);
165 me_execute_string_keep_state (index_line
, NULL
);
171 line_error (_("Unknown index `%s'"), name
);
176 INDEX_ELT
*new = xmalloc (sizeof (INDEX_ELT
));
180 /* Get output line number updated before doing anything. */
184 new->next
= the_indices
[which
];
186 new->entry_text
= index_entry
;
187 /* Since footnotes are handled at the very end of the document,
188 node name in the non-split HTML outputs always show the last
189 node. We artificially make it ``Footnotes''. */
190 if (html
&& !splitting
&& already_outputting_pending_notes
)
191 new->node
= xstrdup (_("Footnotes"));
193 new->node
= current_node
? current_node
: xstrdup ("");
194 if (!html
&& !xml
&& no_headers
)
196 new->section
= current_sectioning_number ();
197 if (strlen (new->section
) == 0)
198 new->section_name
= current_sectioning_name ();
200 new->section_name
= "";
205 new->section_name
= NULL
;
207 new->code
= tem
->code
;
208 new->defining_line
= line_number
- 1;
209 new->output_line
= no_headers
? output_line_number
: node_line_number
;
210 /* We need to make a copy since input_filename may point to
211 something that goes away, for example, inside a macro.
212 (see the findexerr test). */
213 new->defining_file
= xstrdup (input_filename
);
215 if (html
&& splitting
)
217 if (current_output_filename
&& *current_output_filename
)
218 new->output_file
= filename_part (current_output_filename
);
220 new->output_file
= xstrdup ("");
223 new->output_file
= NULL
;
225 new->entry_number
= index_counter
;
226 the_indices
[which
] = new;
229 /* The index breaks if there are colons in the entry.
230 -- This is true, but it's too painful to force changing index
231 entries to use `colon', and too confusing for users. The real
232 fix is to change Info support to support arbitrary characters
233 in node names, and we're not ready to do that. --karl,
235 if (strchr (new->entry_text
, ':'))
236 warning (_("Info cannot handle `:' in index entry `%s'"),
243 int removed_empty_elt
= 0;
245 /* We must put the anchor outside the <dl> and <ul> blocks. */
246 if (rollback_empty_tag ("dl"))
247 removed_empty_elt
= 1;
248 else if (rollback_empty_tag ("ul"))
249 removed_empty_elt
= 2;
251 add_word ("<a name=\"index-");
252 add_escaped_anchor_name (index_entry
, 0);
253 add_word_args ("-%d\"></a>", index_counter
);
255 if (removed_empty_elt
== 1)
256 add_html_block_elt_args ("\n<dl>");
257 else if (removed_empty_elt
== 2)
258 add_html_block_elt_args ("\n<ul>");
263 xml_insert_indexterm (index_entry
, name
);
266 /* The function which user defined index commands call. */
270 char *name
= xstrdup (command
);
271 if (strlen (name
) >= strlen ("index"))
272 name
[strlen (name
) - strlen ("index")] = 0;
273 index_add_arg (name
);
277 /* Define an index known as NAME. We assign the slot number.
278 If CODE is nonzero, make this a code index. */
280 defindex (char *name
, int code
)
284 /* If it already exists, flush it. */
287 /* Try to find an empty slot. */
289 for (i
= 0; i
< defined_indices
; i
++)
290 if (!name_index_alist
[i
])
297 { /* No such luck. Make space for another index. */
298 slot
= defined_indices
;
301 name_index_alist
= (INDEX_ALIST
**)
302 xrealloc (name_index_alist
, (1 + defined_indices
)
303 * sizeof (INDEX_ALIST
*));
304 the_indices
= (INDEX_ELT
**)
305 xrealloc (the_indices
, (1 + defined_indices
) * sizeof (INDEX_ELT
*));
308 /* We have a slot. Start assigning. */
309 name_index_alist
[slot
] = xmalloc (sizeof (INDEX_ALIST
));
310 name_index_alist
[slot
]->name
= xstrdup (name
);
311 name_index_alist
[slot
]->read_index
= slot
;
312 name_index_alist
[slot
]->write_index
= slot
;
313 name_index_alist
[slot
]->code
= code
;
315 the_indices
[slot
] = NULL
;
318 /* Define an index NAME, implicitly @code if CODE is nonzero. */
320 top_defindex (char *name
, int code
)
324 temp
= xmalloc (1 + strlen (name
) + strlen ("index"));
325 sprintf (temp
, "%sindex", name
);
326 define_user_command (temp
, gen_index
, 0);
327 defindex (name
, code
);
331 /* Set up predefined indices. */
337 /* Create the default data structures. */
339 /* Initialize data space. */
342 the_indices
= xmalloc ((1 + defined_indices
) * sizeof (INDEX_ELT
*));
343 the_indices
[defined_indices
] = NULL
;
345 name_index_alist
= xmalloc ((1 + defined_indices
)
346 * sizeof (INDEX_ALIST
*));
347 name_index_alist
[defined_indices
] = NULL
;
350 /* If there were existing indices, get rid of them now. */
351 for (i
= 0; i
< defined_indices
; i
++)
353 if (name_index_alist
[i
])
354 { /* Suppose we're called with two input files, and the first
355 does a @synindex pg cp. Then, when we get here to start
356 the second file, the "pg" element won't get freed by
357 undefindex (because it's pointing to "cp"). So free it
358 here; otherwise, when we try to define the pg index again
359 just below, it will still point to cp. */
360 undefindex (name_index_alist
[i
]->name
);
362 /* undefindex sets all this to null in some cases. */
363 if (name_index_alist
[i
])
365 free (name_index_alist
[i
]->name
);
366 free (name_index_alist
[i
]);
367 name_index_alist
[i
] = NULL
;
372 /* Add the default indices. */
373 top_defindex ("cp", 0); /* cp is the only non-code index. */
374 top_defindex ("fn", 1);
375 top_defindex ("ky", 1);
376 top_defindex ("pg", 1);
377 top_defindex ("tp", 1);
378 top_defindex ("vr", 1);
381 /* Given an index name, return the offset in the_indices of this index,
382 or -1 if there is no such index. */
384 translate_index (char *name
)
386 INDEX_ALIST
*which
= find_index (name
);
389 return which
->read_index
;
394 /* Return the index list which belongs to NAME. */
396 index_list (char *name
)
398 int which
= translate_index (name
);
400 return (INDEX_ELT
*) -1;
402 return the_indices
[which
];
405 /* Define a new index command. Arg is name of index. */
407 gen_defindex (int code
)
410 get_rest_of_line (0, &name
);
412 if (find_index (name
))
414 line_error (_("Index `%s' already exists"), name
);
418 char *temp
= xmalloc (strlen (name
) + sizeof ("index"));
419 sprintf (temp
, "%sindex", name
);
420 define_user_command (temp
, gen_index
, 0);
421 defindex (name
, code
);
435 cm_defcodeindex (void)
440 /* Expects 2 args, on the same line. Both are index abbreviations.
441 Make the first one be a synonym for the second one, i.e. make the
442 first one have the same index as the second one. */
447 char *abbrev1
, *abbrev2
;
450 get_until_in_line (0, " ", &abbrev1
);
451 target
= find_index_offset (abbrev1
);
453 get_until_in_line (0, " ", &abbrev2
);
454 source
= find_index_offset (abbrev2
);
455 if (source
< 0 || target
< 0)
457 line_error (_("Unknown index `%s' and/or `%s' in @synindex"),
463 xml_synindex (abbrev1
, abbrev2
);
465 name_index_alist
[target
]->write_index
466 = name_index_alist
[source
]->write_index
;
474 cm_pindex (void) /* Pinhead index. */
476 index_add_arg ("pg");
480 cm_vindex (void) /* Variable index. */
482 index_add_arg ("vr");
486 cm_kindex (void) /* Key index. */
488 index_add_arg ("ky");
492 cm_cindex (void) /* Concept index. */
494 index_add_arg ("cp");
498 cm_findex (void) /* Function index. */
500 index_add_arg ("fn");
504 cm_tindex (void) /* Data Type index. */
506 index_add_arg ("tp");
510 index_element_compare (const void *element1
, const void *element2
)
512 INDEX_ELT
**elt1
= (INDEX_ELT
**) element1
;
513 INDEX_ELT
**elt2
= (INDEX_ELT
**) element2
;
515 return index_compare_fn ((*elt1
)->entry
, (*elt2
)->entry
);
518 /* Force all index entries to be unique. */
520 make_index_entries_unique (INDEX_ELT
**array
, int count
)
526 copy
= xmalloc ((1 + count
) * sizeof (INDEX_ELT
*));
528 for (i
= 0, j
= 0; i
< count
; i
++)
531 || array
[i
]->node
!= array
[i
+ 1]->node
532 || !STREQ (array
[i
]->entry
, array
[i
+ 1]->entry
))
533 copy
[j
++] = array
[i
];
536 free (array
[i
]->entry
);
537 free (array
[i
]->entry_text
);
543 /* Now COPY contains only unique entries. Duplicated entries in the
544 original array have been freed. Replace the current array with
545 the copy, fixing the NEXT pointers. */
546 for (i
= 0; copy
[i
]; i
++)
548 copy
[i
]->next
= copy
[i
+ 1];
550 /* Fix entry names which are the same. They point to different nodes,
551 so we make the entry name unique. */
553 && STREQ (copy
[i
]->entry
, copy
[i
+ 1]->entry
)
556 char *new_entry_name
;
558 new_entry_name
= xmalloc (10 + strlen (copy
[i
]->entry
));
559 sprintf (new_entry_name
, "%s <%d>", copy
[i
]->entry
, counter
);
560 free (copy
[i
]->entry
);
561 copy
[i
]->entry
= new_entry_name
;
571 /* Free the storage used only by COPY. */
576 /* Sort the index passed in INDEX, returning an array of pointers to
577 elements. The array is terminated with a NULL pointer. */
580 sort_index (INDEX_ELT
*index
)
585 int save_line_number
= line_number
;
586 char *save_input_filename
= input_filename
;
587 int save_html
= html
;
589 /* Pretend we are in non-HTML mode, for the purpose of getting the
590 expanded index entry that lacks any markup and other HTML escape
591 characters which could produce a wrong sort order. */
592 /* fixme: html: this still causes some markup, such as non-ASCII
593 characters @AE{} etc., to sort incorrectly. */
596 for (temp
= index
, count
= 0; temp
; temp
= temp
->next
, count
++)
598 /* We have the length, now we can allocate an array. */
599 array
= xmalloc ((count
+ 1) * sizeof (INDEX_ELT
*));
601 for (temp
= index
, count
= 0; temp
; temp
= temp
->next
, count
++)
603 /* Allocate new memory for the return array, since parts of the
604 original INDEX get freed. Otherwise, if the document calls
605 @printindex twice on the same index, with duplicate entries,
606 we'll have garbage the second time. There are cleaner ways to
607 deal, but this will suffice for now. */
608 array
[count
] = xmalloc (sizeof (INDEX_ELT
));
609 *(array
[count
]) = *(temp
); /* struct assignment, hope it's ok */
611 /* Adjust next pointers to use the new memory. */
613 array
[count
-1]->next
= array
[count
];
615 /* Set line number and input filename to the source line for this
616 index entry, as this expansion finds any errors. */
617 line_number
= array
[count
]->defining_line
;
618 input_filename
= array
[count
]->defining_file
;
620 /* If this particular entry should be printed as a "code" index,
621 then expand it as @code{entry}, i.e., as in fixed-width font. */
622 array
[count
]->entry
= expansion (temp
->entry_text
, array
[count
]->code
);
624 array
[count
] = NULL
; /* terminate the array. */
626 line_number
= save_line_number
;
627 input_filename
= save_input_filename
;
631 /* This is not perfect. We should set (then restore) the locale to the
632 documentlanguage, so strcoll operates according to the document's
633 locale, not the user's. For now, I'm just going to assume that
634 those few new documents which use @documentlanguage will be
635 processed in the appropriate locale. In any case, don't use
636 strcoll in the C (aka POSIX) locale, that is the ASCII ordering. */
637 if (language_code
!= en
)
639 char *lang_env
= getenv ("LANG");
640 if (lang_env
&& !STREQ (lang_env
, "C") && !STREQ (lang_env
, "POSIX"))
641 index_compare_fn
= strcoll
;
643 #endif /* HAVE_STRCOLL */
645 /* Sort the array. */
646 qsort (array
, count
, sizeof (INDEX_ELT
*), index_element_compare
);
648 /* Remove duplicate entries. */
649 make_index_entries_unique (array
, count
);
651 /* Replace the original index with the sorted one, in case the
652 document wants to print it again. If the index wasn't empty. */
660 insert_index_output_line_no (int line_number
, int output_line_number_len
)
663 int str_size
= output_line_number_len
+ strlen (_("(line )"))
665 char *out_line_no_str
= (char *) xmalloc (str_size
+ 1);
667 /* Do not translate ``(line NNN)'' below for !no_headers case (Info output),
668 because it's something like the ``* Menu'' strings. For plaintext output
669 it should be translated though. */
670 sprintf (out_line_no_str
,
671 no_headers
? _("(line %*d)") : "(line %*d)",
672 output_line_number_len
, line_number
);
675 int i
= output_paragraph_offset
;
676 while (0 < i
&& output_paragraph
[i
-1] != '\n')
678 last_column
= output_paragraph_offset
- i
;
681 if (last_column
+ strlen (out_line_no_str
) > fill_column
)
687 while (last_column
+ strlen (out_line_no_str
) < fill_column
)
693 insert_string (out_line_no_str
);
696 free (out_line_no_str
);
699 /* Nonzero means that we are in the middle of printing an index. */
700 int printing_index
= 0;
702 /* Takes one arg, a short name of an index to print.
703 Outputs a menu of the sorted elements of the index. */
708 get_rest_of_line (0, &index_name
);
710 /* get_rest_of_line increments the line number by one,
711 so to make warnings/errors point to the correct line,
712 we decrement the line_number again. */
713 if (!handling_delayed_writes
)
718 xml_insert_element (PRINTINDEX
, START
);
719 insert_string (index_name
);
720 xml_insert_element (PRINTINDEX
, END
);
722 else if (!handling_delayed_writes
)
724 int command_len
= sizeof ("@ ") + strlen (command
) + strlen (index_name
);
725 char *index_command
= xmalloc (command_len
+ 1);
731 sprintf (index_command
, "@%s %s", command
, index_name
);
732 register_delayed_write (index_command
);
733 free (index_command
);
739 INDEX_ELT
*last_index
= 0;
741 unsigned line_length
;
743 int saved_inhibit_paragraph_indentation
= inhibit_paragraph_indentation
;
744 int saved_filling_enabled
= filling_enabled
;
745 int saved_line_number
= line_number
;
746 char *saved_input_filename
= input_filename
;
747 unsigned output_line_number_len
;
749 index
= index_list (index_name
);
750 if (index
== (INDEX_ELT
*)-1)
752 line_error (_("Unknown index `%s' in @printindex"), index_name
);
757 /* Do this before sorting, so execute_string is in the good environment */
761 /* Do this before sorting, so execute_string in index_element_compare
762 will give the same results as when we actually print. */
765 inhibit_paragraph_indentation
= 1;
767 array
= sort_index (index
);
771 add_html_block_elt_args ("<ul class=\"index-%s\" compact>",
773 else if (!no_headers
&& !docbook
)
774 { /* Info. Add magic cookie for info readers (to treat this
775 menu differently), and the usual start-of-menu. */
777 add_word ("\010[index");
779 add_word ("\010]\n");
780 add_word ("* Menu:\n\n");
783 me_inhibit_expansion
++;
785 /* This will probably be enough. */
787 line
= xmalloc (line_length
);
790 char *max_output_line_number
= (char *) xmalloc (25 * sizeof (char));
793 sprintf (max_output_line_number
, "%d", output_line_number
);
796 INDEX_ELT
*tmp_entry
= index
;
798 for (tmp_entry
= index
; tmp_entry
; tmp_entry
= tmp_entry
->next
)
799 tmp
= tmp_entry
->output_line
> tmp
? tmp_entry
->output_line
: tmp
;
800 sprintf (max_output_line_number
, "%d", tmp
);
803 output_line_number_len
= strlen (max_output_line_number
);
804 free (max_output_line_number
);
807 for (item
= 0; (index
= array
[item
]); item
++)
809 /* A pathological document might have an index entry outside of any
810 node. Don't crash; try using the section name instead. */
811 char *index_node
= index
->node
;
813 line_number
= index
->defining_line
;
814 input_filename
= index
->defining_file
;
816 if ((!index_node
|| !*index_node
) && html
)
817 index_node
= toc_find_section_of_node (index_node
);
819 if (!index_node
|| !*index_node
)
821 line_error (_("Entry for index `%s' outside of any node"),
823 if (html
|| !no_headers
)
824 index_node
= (char *) _("(outside of any node)");
829 /* For HTML, we need to expand and HTML-escape the
830 original entry text, at the same time. Consider
831 @cindex J@"urgen. We want Jüurgen. We can't
832 expand and then escape since we'll end up with
833 J&uuml;rgen. We can't escape and then expand
834 because then `expansion' will see J@"urgen, and
835 @"urgen is not a command. */
837 maybe_escaped_expansion (index
->entry_text
, index
->code
, 1);
839 add_html_block_elt_args ("\n<li><a href=\"%s#index-",
840 (splitting
&& index
->output_file
) ? index
->output_file
: "");
841 add_escaped_anchor_name (index
->entry_text
, 0);
842 add_word_args ("-%d\">%s</a>: ", index
->entry_number
,
846 add_word ("<a href=\"");
847 if (index
->node
&& *index
->node
)
849 /* Ensure any non-macros in the node name are expanded. */
850 char *expanded_index
;
852 in_fixed_width_font
++;
853 expanded_index
= expansion (index_node
, 0);
854 in_fixed_width_font
--;
855 add_anchor_name (expanded_index
, 1);
856 expanded_index
= escape_string (expanded_index
);
857 add_word_args ("\">%s</a>", expanded_index
);
858 free (expanded_index
);
860 else if (STREQ (index_node
, _("(outside of any node)")))
862 add_anchor_name (index_node
, 1);
863 add_word_args ("\">%s</a>", index_node
);
866 /* If we use the section instead of the (missing) node, then
867 index_node already includes all we need except the #. */
868 add_word_args ("#%s</a>", index_node
);
870 add_html_block_elt ("</li>");
872 else if (xml
&& docbook
)
874 /* In the DocBook case, the expanded index entry is not
875 good for us, since it was expanded for non-DocBook mode
876 inside sort_index. So we send the original entry text
877 to be used with execute_string. */
878 xml_insert_indexentry (index
->entry_text
, index_node
);
882 unsigned new_length
= strlen (index
->entry
);
884 if (new_length
< 50) /* minimum length used below */
886 new_length
+= strlen (index_node
) + 7; /* * : .\n\0 */
888 if (new_length
> line_length
)
890 line_length
= new_length
;
891 line
= xrealloc (line
, line_length
);
893 /* Print the entry, nicely formatted. We've already
894 expanded any commands in index->entry, including any
895 implicit @code. Thus, can't call execute_string, since
896 @@ has turned into @. */
899 sprintf (line
, "* %-37s ", index
->entry
);
900 line
[2 + strlen (index
->entry
)] = ':';
901 insert_string (line
);
902 /* Make sure any non-macros in the node name are expanded. */
903 in_fixed_width_font
++;
904 execute_string ("%s. ", index_node
);
905 insert_index_output_line_no (index
->output_line
,
906 output_line_number_len
);
907 in_fixed_width_font
--;
911 /* With --no-headers, the @node lines are gone, so
912 there's little sense in referring to them in the
913 index. Instead, output the number or name of the
914 section that corresponds to that node. */
915 sprintf (line
, "%-*s ", number_sections
? 46 : 1, index
->entry
);
916 line
[strlen (index
->entry
)] = ':';
917 insert_string (line
);
919 if (strlen (index
->section
) > 0)
920 { /* We got your number. */
921 insert_string ((char *) _("See "));
922 insert_string (index
->section
);
925 { /* Sigh, index in an @unnumbered. :-\ */
926 insert_string ("\n ");
927 insert_string ((char *) _("See "));
928 insert_string ("``");
929 insert_string (expansion (index
->section_name
, 0));
930 insert_string ("''");
933 insert_string (". ");
934 insert_index_output_line_no (index
->output_line
,
935 output_line_number_len
);
939 /* Prevent `output_paragraph' from growing to the size of the
947 me_inhibit_expansion
--;
950 close_single_paragraph ();
951 filling_enabled
= saved_filling_enabled
;
952 inhibit_paragraph_indentation
= saved_inhibit_paragraph_indentation
;
953 input_filename
= saved_input_filename
;
954 line_number
= saved_line_number
;
957 add_html_block_elt ("</ul>");
958 else if (xml
&& docbook
)
963 /* Re-increment the line number, because get_rest_of_line
964 left us looking at the next line after the command. */