xref: /openbsd-src/gnu/usr.bin/texinfo/makeinfo/insertion.c (revision 1076333c323c9f213f0d653fc52002328f47dbe9)
11cc83814Sespie /* insertion.c -- insertions for Texinfo.
2*1076333cSespie    $Id: insertion.c,v 1.3 2006/07/17 16:12:36 espie Exp $
31cc83814Sespie 
4*1076333cSespie    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
5*1076333cSespie    Foundation, Inc.
61cc83814Sespie 
71cc83814Sespie    This program is free software; you can redistribute it and/or modify
81cc83814Sespie    it under the terms of the GNU General Public License as published by
91cc83814Sespie    the Free Software Foundation; either version 2, or (at your option)
101cc83814Sespie    any later version.
111cc83814Sespie 
121cc83814Sespie    This program is distributed in the hope that it will be useful,
131cc83814Sespie    but WITHOUT ANY WARRANTY; without even the implied warranty of
141cc83814Sespie    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
151cc83814Sespie    GNU General Public License for more details.
161cc83814Sespie 
171cc83814Sespie    You should have received a copy of the GNU General Public License
181cc83814Sespie    along with this program; if not, write to the Free Software Foundation,
191cc83814Sespie    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
201cc83814Sespie 
211cc83814Sespie #include "system.h"
221cc83814Sespie #include "cmds.h"
231cc83814Sespie #include "defun.h"
24*1076333cSespie #include "float.h"
25*1076333cSespie #include "html.h"
261cc83814Sespie #include "insertion.h"
271cc83814Sespie #include "macro.h"
281cc83814Sespie #include "makeinfo.h"
29*1076333cSespie #include "multi.h"
303fb98d4aSespie #include "xml.h"
311cc83814Sespie 
321cc83814Sespie /* Must match list in insertion.h.  */
331cc83814Sespie static char *insertion_type_names[] =
341cc83814Sespie {
353fb98d4aSespie   "cartouche", "copying", "defcv", "deffn", "defivar", "defmac",
36*1076333cSespie   "defmethod", "defop", "defopt", "defspec", "deftp", "deftypecv",
37*1076333cSespie   "deftypefn", "deftypefun", "deftypeivar", "deftypemethod",
38*1076333cSespie   "deftypeop", "deftypevar", "deftypevr", "defun", "defvar", "defvr",
39*1076333cSespie   "detailmenu", "direntry", "display", "documentdescription",
40*1076333cSespie   "enumerate", "example", "float", "flushleft", "flushright", "format",
41*1076333cSespie   "ftable", "group", "ifclear", "ifdocbook", "ifhtml", "ifinfo",
42*1076333cSespie   "ifnotdocbook", "ifnothtml", "ifnotinfo", "ifnotplaintext", "ifnottex",
43*1076333cSespie   "ifnotxml", "ifplaintext", "ifset", "iftex", "ifxml", "itemize", "lisp",
44*1076333cSespie   "menu", "multitable", "quotation", "rawdocbook", "rawhtml", "rawtex",
45*1076333cSespie   "rawxml", "smalldisplay", "smallexample", "smallformat", "smalllisp",
46*1076333cSespie   "verbatim", "table", "tex", "vtable", "titlepage", "bad_type"
471cc83814Sespie };
481cc83814Sespie 
491cc83814Sespie /* All nested environments.  */
501cc83814Sespie INSERTION_ELT *insertion_stack = NULL;
511cc83814Sespie 
521cc83814Sespie /* How deeply we're nested.  */
531cc83814Sespie int insertion_level = 0;
541cc83814Sespie 
553fb98d4aSespie /* Set to 1 if we've processed (commentary) text in a @menu that
563fb98d4aSespie    wasn't part of a menu item.  */
573fb98d4aSespie int had_menu_commentary;
581cc83814Sespie 
591cc83814Sespie /* How to examine menu lines.  */
601cc83814Sespie int in_detailmenu = 0;
611cc83814Sespie 
623fb98d4aSespie /* Whether to examine menu lines.  */
633fb98d4aSespie int in_menu = 0;
641cc83814Sespie 
651cc83814Sespie /* Set to 1 if <p> is written in normal context.
661cc83814Sespie    Used for menu and itemize. */
671cc83814Sespie int in_paragraph = 0;
681cc83814Sespie 
69*1076333cSespie /* Since an insertion is already in the stack before we reach the switch
70*1076333cSespie    statement, we cannot use is_in_insertion_of_type (always returns true.) Also
71*1076333cSespie    making it return the level found, and comparing it with the current level is
72*1076333cSespie    no use, due to the order of stack.  */
73*1076333cSespie static int float_active = 0;
743fb98d4aSespie 
75*1076333cSespie /* Unsetting escape_html blindly causes text inside @html/etc. to be escaped if
76*1076333cSespie    used within a rmacro.  */
77*1076333cSespie static int raw_output_block = 0;
78*1076333cSespie 
79*1076333cSespie /* Non-zero if a <dl> element has a <dt> element in it.  We use this when
80*1076333cSespie    deciding whether to insert a <br> or not.  */
81*1076333cSespie static int html_deflist_has_term = 0;
821cc83814Sespie 
831cc83814Sespie void
init_insertion_stack(void)84*1076333cSespie init_insertion_stack (void)
851cc83814Sespie {
861cc83814Sespie   insertion_stack = NULL;
871cc83814Sespie }
881cc83814Sespie 
891cc83814Sespie /* Return the type of the current insertion. */
901cc83814Sespie static enum insertion_type
current_insertion_type(void)91*1076333cSespie current_insertion_type (void)
921cc83814Sespie {
931cc83814Sespie   return insertion_level ? insertion_stack->insertion : bad_type;
941cc83814Sespie }
951cc83814Sespie 
961cc83814Sespie /* Return the string which is the function to wrap around items, or NULL
971cc83814Sespie    if we're not in an environment where @item is ok.  */
981cc83814Sespie static char *
current_item_function(void)99*1076333cSespie current_item_function (void)
1001cc83814Sespie {
1011cc83814Sespie   int done = 0;
1021cc83814Sespie   INSERTION_ELT *elt = insertion_stack;
1031cc83814Sespie 
1041cc83814Sespie   /* Skip down through the stack until we find an insertion with an
1051cc83814Sespie      itemize function defined, i.e., skip conditionals, @cartouche, etc.  */
1061cc83814Sespie   while (!done && elt)
1071cc83814Sespie     {
1081cc83814Sespie       switch (elt->insertion)
1091cc83814Sespie         {
1101cc83814Sespie         /* This list should match the one in cm_item.  */
1111cc83814Sespie         case ifclear:
1121cc83814Sespie         case ifhtml:
1131cc83814Sespie         case ifinfo:
1141cc83814Sespie         case ifnothtml:
1151cc83814Sespie         case ifnotinfo:
1163fb98d4aSespie         case ifnotplaintext:
1171cc83814Sespie         case ifnottex:
118*1076333cSespie 	case ifnotxml:
1193fb98d4aSespie         case ifplaintext:
1201cc83814Sespie         case ifset:
1211cc83814Sespie         case iftex:
122*1076333cSespie 	case ifxml:
123*1076333cSespie         case rawdocbook:
1241cc83814Sespie         case rawhtml:
125*1076333cSespie         case rawxml:
1261cc83814Sespie         case rawtex:
1271cc83814Sespie         case tex:
1281cc83814Sespie         case cartouche:
1291cc83814Sespie           elt = elt->next;
1301cc83814Sespie           break;
1311cc83814Sespie 
1321cc83814Sespie         default:
1331cc83814Sespie           done = 1;
1341cc83814Sespie         }
1351cc83814Sespie     }
1361cc83814Sespie 
1371cc83814Sespie   /* item_function usually gets assigned the empty string.  */
1381cc83814Sespie   return done && (*elt->item_function) ? elt->item_function : NULL;
1391cc83814Sespie }
1401cc83814Sespie 
1411cc83814Sespie /* Parse the item marker function off the input.  If result is just "@",
1421cc83814Sespie    change it to "@ ", since "@" by itself is not a command.  This makes
1431cc83814Sespie    "@ ", "@\t", and "@\n" all the same, but their default meanings are
1441cc83814Sespie    the same anyway, and let's not worry about supporting redefining them.  */
145*1076333cSespie static char *
get_item_function(void)146*1076333cSespie get_item_function (void)
1471cc83814Sespie {
1481cc83814Sespie   char *item_function;
149*1076333cSespie   char *item_loc;
150*1076333cSespie 
1511cc83814Sespie   get_rest_of_line (0, &item_function);
1521cc83814Sespie 
153*1076333cSespie   /* If the document erroneously says
154*1076333cSespie        @itemize @bullet @item foobar
155*1076333cSespie      it's nicer to give an error up front than repeat `@bullet expected
156*1076333cSespie      braces' until we get a segmentation fault.  */
157*1076333cSespie   item_loc = strstr (item_function, "@item");
158*1076333cSespie   if (item_loc)
159*1076333cSespie     {
160*1076333cSespie       line_error (_("@item not allowed in argument to @itemize"));
161*1076333cSespie       *item_loc = 0;
162*1076333cSespie     }
163*1076333cSespie 
1641cc83814Sespie   /* If we hit the end of text in get_rest_of_line, backing up
1651cc83814Sespie      input pointer will cause the last character of the last line
1661cc83814Sespie      be pushed back onto the input, which is wrong.  */
1671cc83814Sespie   if (input_text_offset < input_text_length)
1681cc83814Sespie     backup_input_pointer ();
1691cc83814Sespie 
1701cc83814Sespie   if (STREQ (item_function, "@"))
1711cc83814Sespie     {
1721cc83814Sespie       free (item_function);
1731cc83814Sespie       item_function = xstrdup ("@ ");
1741cc83814Sespie     }
1751cc83814Sespie 
1761cc83814Sespie   return item_function;
1771cc83814Sespie }
1781cc83814Sespie 
1791cc83814Sespie  /* Push the state of the current insertion on the stack. */
180*1076333cSespie static void
push_insertion(enum insertion_type type,char * item_function)181*1076333cSespie push_insertion (enum insertion_type type, char *item_function)
1821cc83814Sespie {
1831cc83814Sespie   INSERTION_ELT *new = xmalloc (sizeof (INSERTION_ELT));
1841cc83814Sespie 
1851cc83814Sespie   new->item_function = item_function;
1861cc83814Sespie   new->filling_enabled = filling_enabled;
1871cc83814Sespie   new->indented_fill = indented_fill;
1881cc83814Sespie   new->insertion = type;
1891cc83814Sespie   new->line_number = line_number;
1901cc83814Sespie   new->filename = xstrdup (input_filename);
1911cc83814Sespie   new->inhibited = inhibit_paragraph_indentation;
1921cc83814Sespie   new->in_fixed_width_font = in_fixed_width_font;
1931cc83814Sespie   new->next = insertion_stack;
1941cc83814Sespie   insertion_stack = new;
1951cc83814Sespie   insertion_level++;
1961cc83814Sespie }
1971cc83814Sespie 
1981cc83814Sespie  /* Pop the value on top of the insertion stack into the
1991cc83814Sespie     global variables. */
2001cc83814Sespie void
pop_insertion(void)201*1076333cSespie pop_insertion (void)
2021cc83814Sespie {
2031cc83814Sespie   INSERTION_ELT *temp = insertion_stack;
2041cc83814Sespie 
2051cc83814Sespie   if (temp == NULL)
2061cc83814Sespie     return;
2071cc83814Sespie 
2081cc83814Sespie   in_fixed_width_font = temp->in_fixed_width_font;
2091cc83814Sespie   inhibit_paragraph_indentation = temp->inhibited;
2101cc83814Sespie   filling_enabled = temp->filling_enabled;
2111cc83814Sespie   indented_fill = temp->indented_fill;
2121cc83814Sespie   free_and_clear (&(temp->item_function));
2131cc83814Sespie   free_and_clear (&(temp->filename));
2141cc83814Sespie   insertion_stack = insertion_stack->next;
2151cc83814Sespie   free (temp);
2161cc83814Sespie   insertion_level--;
2171cc83814Sespie }
2181cc83814Sespie 
2191cc83814Sespie  /* Return a pointer to the print name of this
2201cc83814Sespie     enumerated type. */
221*1076333cSespie static const char *
insertion_type_pname(enum insertion_type type)222*1076333cSespie insertion_type_pname (enum insertion_type type)
2231cc83814Sespie {
2241cc83814Sespie   if ((int) type < (int) bad_type)
225*1076333cSespie   {
226*1076333cSespie     if (type == rawdocbook)
227*1076333cSespie       return "docbook";
228*1076333cSespie     else if (type == rawhtml)
229*1076333cSespie       return "html";
230*1076333cSespie     else if (type == rawxml)
231*1076333cSespie       return "xml";
232*1076333cSespie     else if (type == rawtex)
233*1076333cSespie       return "tex";
234*1076333cSespie     else
2351cc83814Sespie       return insertion_type_names[(int) type];
236*1076333cSespie   }
2371cc83814Sespie   else
2381cc83814Sespie     return _("Broken-Type in insertion_type_pname");
2391cc83814Sespie }
2401cc83814Sespie 
2411cc83814Sespie /* Return the insertion_type associated with NAME.
2421cc83814Sespie    If the type is not one of the known ones, return BAD_TYPE. */
2431cc83814Sespie enum insertion_type
find_type_from_name(char * name)244*1076333cSespie find_type_from_name (char *name)
2451cc83814Sespie {
2461cc83814Sespie   int index = 0;
2471cc83814Sespie   while (index < (int) bad_type)
2481cc83814Sespie     {
2491cc83814Sespie       if (STREQ (name, insertion_type_names[index]))
2501cc83814Sespie         return (enum insertion_type) index;
251*1076333cSespie       if (index == rawdocbook && STREQ (name, "docbook"))
252*1076333cSespie         return rawdocbook;
2531cc83814Sespie       if (index == rawhtml && STREQ (name, "html"))
2541cc83814Sespie         return rawhtml;
255*1076333cSespie       if (index == rawxml && STREQ (name, "xml"))
256*1076333cSespie         return rawxml;
2571cc83814Sespie       if (index == rawtex && STREQ (name, "tex"))
2581cc83814Sespie         return rawtex;
2591cc83814Sespie       index++;
2601cc83814Sespie     }
2611cc83814Sespie   return bad_type;
2621cc83814Sespie }
2631cc83814Sespie 
264*1076333cSespie /* Simple function to query insertion_stack to see if we are inside a given
265*1076333cSespie    insertion type. */
2661cc83814Sespie int
is_in_insertion_of_type(int type)267*1076333cSespie is_in_insertion_of_type (int type)
268*1076333cSespie {
269*1076333cSespie   INSERTION_ELT *temp = insertion_stack;
270*1076333cSespie 
271*1076333cSespie   if (!insertion_level)
272*1076333cSespie     return 0;
273*1076333cSespie 
274*1076333cSespie   while (temp)
275*1076333cSespie     {
276*1076333cSespie       if (temp->insertion == type)
277*1076333cSespie         return 1;
278*1076333cSespie       temp = temp->next;
279*1076333cSespie     }
280*1076333cSespie 
281*1076333cSespie   return 0;
282*1076333cSespie }
283*1076333cSespie 
284*1076333cSespie 
285*1076333cSespie static int
defun_insertion(enum insertion_type type)286*1076333cSespie defun_insertion (enum insertion_type type)
2871cc83814Sespie {
2881cc83814Sespie   return 0
2891cc83814Sespie      || (type == defcv)
2901cc83814Sespie      || (type == deffn)
2911cc83814Sespie      || (type == defivar)
2921cc83814Sespie      || (type == defmac)
2931cc83814Sespie      || (type == defmethod)
2941cc83814Sespie      || (type == defop)
2951cc83814Sespie      || (type == defopt)
2961cc83814Sespie      || (type == defspec)
2971cc83814Sespie      || (type == deftp)
298*1076333cSespie      || (type == deftypecv)
2991cc83814Sespie      || (type == deftypefn)
3001cc83814Sespie      || (type == deftypefun)
3011cc83814Sespie      || (type == deftypeivar)
3021cc83814Sespie      || (type == deftypemethod)
3031cc83814Sespie      || (type == deftypeop)
3041cc83814Sespie      || (type == deftypevar)
3051cc83814Sespie      || (type == deftypevr)
3061cc83814Sespie      || (type == defun)
3071cc83814Sespie      || (type == defvar)
3081cc83814Sespie      || (type == defvr)
3091cc83814Sespie   ;
3101cc83814Sespie }
3111cc83814Sespie 
3121cc83814Sespie /* MAX_NS is the maximum nesting level for enumerations.  I picked 100
3131cc83814Sespie    which seemed reasonable.  This doesn't control the number of items,
3141cc83814Sespie    just the number of nested lists. */
3151cc83814Sespie #define max_stack_depth 100
3161cc83814Sespie #define ENUM_DIGITS 1
3171cc83814Sespie #define ENUM_ALPHA  2
3181cc83814Sespie typedef struct {
3191cc83814Sespie   int enumtype;
3201cc83814Sespie   int enumval;
3211cc83814Sespie } DIGIT_ALPHA;
3221cc83814Sespie 
3231cc83814Sespie DIGIT_ALPHA enumstack[max_stack_depth];
3241cc83814Sespie int enumstack_offset = 0;
3251cc83814Sespie int current_enumval = 1;
3261cc83814Sespie int current_enumtype = ENUM_DIGITS;
3271cc83814Sespie char *enumeration_arg = NULL;
3281cc83814Sespie 
329*1076333cSespie static void
start_enumerating(int at,int type)330*1076333cSespie start_enumerating (int at, int type)
3311cc83814Sespie {
3321cc83814Sespie   if ((enumstack_offset + 1) == max_stack_depth)
3331cc83814Sespie     {
3341cc83814Sespie       line_error (_("Enumeration stack overflow"));
3351cc83814Sespie       return;
3361cc83814Sespie     }
3371cc83814Sespie   enumstack[enumstack_offset].enumtype = current_enumtype;
3381cc83814Sespie   enumstack[enumstack_offset].enumval = current_enumval;
3391cc83814Sespie   enumstack_offset++;
3401cc83814Sespie   current_enumval = at;
3411cc83814Sespie   current_enumtype = type;
3421cc83814Sespie }
3431cc83814Sespie 
344*1076333cSespie static void
stop_enumerating(void)345*1076333cSespie stop_enumerating (void)
3461cc83814Sespie {
3471cc83814Sespie   --enumstack_offset;
3481cc83814Sespie   if (enumstack_offset < 0)
3491cc83814Sespie     enumstack_offset = 0;
3501cc83814Sespie 
3511cc83814Sespie   current_enumval = enumstack[enumstack_offset].enumval;
3521cc83814Sespie   current_enumtype = enumstack[enumstack_offset].enumtype;
3531cc83814Sespie }
3541cc83814Sespie 
3551cc83814Sespie /* Place a letter or digits into the output stream. */
356*1076333cSespie static void
enumerate_item(void)357*1076333cSespie enumerate_item (void)
3581cc83814Sespie {
3591cc83814Sespie   char temp[10];
3601cc83814Sespie 
3611cc83814Sespie   if (current_enumtype == ENUM_ALPHA)
3621cc83814Sespie     {
3631cc83814Sespie       if (current_enumval == ('z' + 1) || current_enumval == ('Z' + 1))
3641cc83814Sespie         {
3651cc83814Sespie           current_enumval = ((current_enumval - 1) == 'z' ? 'a' : 'A');
3661cc83814Sespie           warning (_("lettering overflow, restarting at %c"), current_enumval);
3671cc83814Sespie         }
3681cc83814Sespie       sprintf (temp, "%c. ", current_enumval);
3691cc83814Sespie     }
3701cc83814Sespie   else
3711cc83814Sespie     sprintf (temp, "%d. ", current_enumval);
3721cc83814Sespie 
3731cc83814Sespie   indent (output_column += (current_indent - strlen (temp)));
3741cc83814Sespie   add_word (temp);
3751cc83814Sespie   current_enumval++;
3761cc83814Sespie }
3771cc83814Sespie 
3781cc83814Sespie static void
enum_html(void)379*1076333cSespie enum_html (void)
3801cc83814Sespie {
3811cc83814Sespie   char type;
3821cc83814Sespie   int start;
3831cc83814Sespie 
3841cc83814Sespie   if (isdigit (*enumeration_arg))
3851cc83814Sespie     {
3861cc83814Sespie       type = '1';
3871cc83814Sespie       start = atoi (enumeration_arg);
3881cc83814Sespie     }
3891cc83814Sespie   else if (isupper (*enumeration_arg))
3901cc83814Sespie     {
3911cc83814Sespie       type = 'A';
3921cc83814Sespie       start = *enumeration_arg - 'A' + 1;
3931cc83814Sespie     }
3941cc83814Sespie   else
3951cc83814Sespie     {
3961cc83814Sespie       type = 'a';
3971cc83814Sespie       start = *enumeration_arg - 'a' + 1;
3981cc83814Sespie     }
3991cc83814Sespie 
400*1076333cSespie   add_html_block_elt_args ("<ol type=%c start=%d>\n", type, start);
4011cc83814Sespie }
4021cc83814Sespie 
4031cc83814Sespie /* Conditionally parse based on the current command name. */
4041cc83814Sespie void
command_name_condition(void)405*1076333cSespie command_name_condition (void)
4061cc83814Sespie {
4071cc83814Sespie   char *discarder = xmalloc (8 + strlen (command));
4081cc83814Sespie 
4091cc83814Sespie   sprintf (discarder, "\n%cend %s", COMMAND_PREFIX, command);
4101cc83814Sespie   discard_until (discarder);
4111cc83814Sespie   discard_until ("\n");
4121cc83814Sespie 
4131cc83814Sespie   free (discarder);
4141cc83814Sespie }
4151cc83814Sespie 
4161cc83814Sespie /* This is where the work for all the "insertion" style
4171cc83814Sespie    commands is done.  A huge switch statement handles the
4181cc83814Sespie    various setups, and generic code is on both sides. */
4191cc83814Sespie void
begin_insertion(enum insertion_type type)420*1076333cSespie begin_insertion (enum insertion_type type)
4211cc83814Sespie {
4221cc83814Sespie   int no_discard = 0;
4231cc83814Sespie 
4241cc83814Sespie   if (defun_insertion (type))
4251cc83814Sespie     {
4261cc83814Sespie       push_insertion (type, xstrdup (""));
4271cc83814Sespie       no_discard++;
4281cc83814Sespie     }
4291cc83814Sespie   else
4303fb98d4aSespie     {
4311cc83814Sespie       push_insertion (type, get_item_function ());
4323fb98d4aSespie     }
4331cc83814Sespie 
4341cc83814Sespie   switch (type)
4351cc83814Sespie     {
4361cc83814Sespie     case menu:
4371cc83814Sespie       if (!no_headers)
4381cc83814Sespie         close_paragraph ();
4391cc83814Sespie 
4401cc83814Sespie       filling_enabled = no_indent = 0;
4411cc83814Sespie       inhibit_paragraph_indentation = 1;
4421cc83814Sespie 
4431cc83814Sespie       if (html)
4441cc83814Sespie         {
4451cc83814Sespie           had_menu_commentary = 1;
4461cc83814Sespie         }
4473fb98d4aSespie       else if (!no_headers && !xml)
4481cc83814Sespie         add_word ("* Menu:\n");
4491cc83814Sespie 
4503fb98d4aSespie       if (xml)
4513fb98d4aSespie         xml_insert_element (MENU, START);
452*1076333cSespie       else
453*1076333cSespie         in_fixed_width_font++;
4543fb98d4aSespie 
4553fb98d4aSespie       next_menu_item_number = 1;
4561cc83814Sespie       in_menu++;
4571cc83814Sespie       no_discard++;
4581cc83814Sespie       break;
4591cc83814Sespie 
4601cc83814Sespie     case detailmenu:
4611cc83814Sespie       if (!in_menu)
4621cc83814Sespie         {
4631cc83814Sespie           if (!no_headers)
4641cc83814Sespie             close_paragraph ();
4651cc83814Sespie 
4661cc83814Sespie           filling_enabled = no_indent = 0;
4671cc83814Sespie           inhibit_paragraph_indentation = 1;
4681cc83814Sespie 
4691cc83814Sespie           no_discard++;
4701cc83814Sespie         }
4711cc83814Sespie 
472*1076333cSespie       if (xml)
473*1076333cSespie         {
474*1076333cSespie           xml_insert_element (DETAILMENU, START);
475*1076333cSespie           skip_whitespace_and_newlines();
476*1076333cSespie         }
477*1076333cSespie       else
4781cc83814Sespie         in_fixed_width_font++;
479*1076333cSespie 
4801cc83814Sespie       in_detailmenu++;
4811cc83814Sespie       break;
4821cc83814Sespie 
4831cc83814Sespie     case direntry:
4841cc83814Sespie       close_single_paragraph ();
4851cc83814Sespie       filling_enabled = no_indent = 0;
4861cc83814Sespie       inhibit_paragraph_indentation = 1;
4871cc83814Sespie       insert_string ("START-INFO-DIR-ENTRY\n");
4883fb98d4aSespie       break;
4893fb98d4aSespie 
4903fb98d4aSespie     case documentdescription:
4913fb98d4aSespie       {
4923fb98d4aSespie         char *desc;
4933fb98d4aSespie         int start_of_end;
4943fb98d4aSespie         int save_fixed_width;
4953fb98d4aSespie 
4963fb98d4aSespie         discard_until ("\n"); /* ignore the @documentdescription line */
4973fb98d4aSespie         start_of_end = get_until ("\n@end documentdescription", &desc);
4983fb98d4aSespie         save_fixed_width = in_fixed_width_font;
4993fb98d4aSespie 
5003fb98d4aSespie         in_fixed_width_font = 0;
5013fb98d4aSespie         document_description = expansion (desc, 0);
5023fb98d4aSespie         free (desc);
5033fb98d4aSespie 
5043fb98d4aSespie         in_fixed_width_font = save_fixed_width;
5053fb98d4aSespie         input_text_offset = start_of_end; /* go back to the @end to match */
5061cc83814Sespie       }
5071cc83814Sespie       break;
5081cc83814Sespie 
5093fb98d4aSespie     case copying:
5103fb98d4aSespie         /* Save the copying text away for @insertcopying,
5113fb98d4aSespie            typically used on the back of the @titlepage (for TeX) and
5123fb98d4aSespie            the Top node (for info/html).  */
513*1076333cSespie       if (input_text[input_text_offset] != '\n')
5143fb98d4aSespie         discard_until ("\n"); /* ignore remainder of @copying line */
5153fb98d4aSespie 
516*1076333cSespie         input_text_offset = get_until ("\n@end copying", &copying_text);
517*1076333cSespie         canon_white (copying_text);
5183fb98d4aSespie 
5193fb98d4aSespie       /* For info, output the copying text right away, so it will end up
5203fb98d4aSespie          in the header of the Info file, before the first node, and thus
5213fb98d4aSespie          get copied automatically to all the split files.  For xml, also
5223fb98d4aSespie          output it right away since xml output is never split.
5233fb98d4aSespie          For html, we output it specifically in html_output_head.
5243fb98d4aSespie          For plain text, there's no way to hide it, so the author must
5253fb98d4aSespie           use @insertcopying in the desired location.  */
526*1076333cSespie       if (docbook)
527*1076333cSespie 	{
528*1076333cSespie 	  if (!xml_in_bookinfo)
529*1076333cSespie 	    {
530*1076333cSespie 	      xml_insert_element (BOOKINFO, START);
531*1076333cSespie 	      xml_in_bookinfo = 1;
532*1076333cSespie 	    }
533*1076333cSespie           xml_insert_element (LEGALNOTICE, START);
534*1076333cSespie 	}
535*1076333cSespie 
5363fb98d4aSespie       if (!html && !no_headers)
5373fb98d4aSespie         cm_insert_copying ();
538*1076333cSespie 
539*1076333cSespie       if (docbook)
540*1076333cSespie         xml_insert_element (LEGALNOTICE, END);
541*1076333cSespie 
5423fb98d4aSespie       break;
5433fb98d4aSespie 
5441cc83814Sespie     case quotation:
5451cc83814Sespie       /* @quotation does filling (@display doesn't).  */
5461cc83814Sespie       if (html)
547*1076333cSespie         add_html_block_elt ("<blockquote>\n");
5481cc83814Sespie       else
5491cc83814Sespie         {
5503fb98d4aSespie           /* with close_single_paragraph, we get no blank line above
5513fb98d4aSespie              within @copying.  */
5523fb98d4aSespie           close_paragraph ();
5531cc83814Sespie           last_char_was_newline = no_indent = 0;
5541cc83814Sespie           indented_fill = filling_enabled = 1;
5551cc83814Sespie           inhibit_paragraph_indentation = 1;
5561cc83814Sespie         }
5571cc83814Sespie       current_indent += default_indentation_increment;
558*1076333cSespie       if (xml)
559*1076333cSespie         xml_insert_quotation (insertion_stack->item_function, START);
560*1076333cSespie       else if (strlen(insertion_stack->item_function))
561*1076333cSespie         execute_string ("@b{%s:} ", insertion_stack->item_function);
5621cc83814Sespie       break;
5631cc83814Sespie 
5641cc83814Sespie     case example:
5651cc83814Sespie     case smallexample:
5661cc83814Sespie     case lisp:
5671cc83814Sespie     case smalllisp:
568*1076333cSespie       in_fixed_width_font++;
569*1076333cSespie       /* fall through */
570*1076333cSespie 
571*1076333cSespie       /* Like @example but no fixed width font. */
572*1076333cSespie     case display:
573*1076333cSespie     case smalldisplay:
5741cc83814Sespie       /* Like @display but without indentation. */
5751cc83814Sespie     case smallformat:
5761cc83814Sespie     case format:
5771cc83814Sespie       close_single_paragraph ();
5781cc83814Sespie       inhibit_paragraph_indentation = 1;
5791cc83814Sespie       filling_enabled = 0;
5801cc83814Sespie       last_char_was_newline = 0;
5811cc83814Sespie 
5821cc83814Sespie       if (html)
583*1076333cSespie         /* Kludge alert: if <pre> is followed by a newline, IE3,
584*1076333cSespie            mozilla, maybe others render an extra blank line before the
585*1076333cSespie            pre-formatted block.  So don't output a newline.  */
586*1076333cSespie         add_html_block_elt_args ("<pre class=\"%s\">", command);
5871cc83814Sespie 
5881cc83814Sespie       if (type != format && type != smallformat)
589*1076333cSespie         {
590*1076333cSespie           current_indent += example_indentation_increment;
591*1076333cSespie           if (html)
592*1076333cSespie             {
593*1076333cSespie               /* Since we didn't put \n after <pre>, we need to insert
594*1076333cSespie                  the indentation by hand.  */
595*1076333cSespie               int i;
596*1076333cSespie               for (i = current_indent; i > 0; i--)
597*1076333cSespie                 add_char (' ');
598*1076333cSespie             }
599*1076333cSespie         }
6001cc83814Sespie       break;
6011cc83814Sespie 
6021cc83814Sespie     case multitable:
6031cc83814Sespie       do_multitable ();
6041cc83814Sespie       break;
6051cc83814Sespie 
6061cc83814Sespie     case table:
6071cc83814Sespie     case ftable:
6081cc83814Sespie     case vtable:
6091cc83814Sespie     case itemize:
6101cc83814Sespie       close_single_paragraph ();
6111cc83814Sespie       current_indent += default_indentation_increment;
6121cc83814Sespie       filling_enabled = indented_fill = 1;
6131cc83814Sespie #if defined (INDENT_PARAGRAPHS_IN_TABLE)
6141cc83814Sespie       inhibit_paragraph_indentation = 0;
6151cc83814Sespie #else
6161cc83814Sespie       inhibit_paragraph_indentation = 1;
6171cc83814Sespie #endif /* !INDENT_PARAGRAPHS_IN_TABLE */
6181cc83814Sespie 
6191cc83814Sespie       /* Make things work for losers who forget the itemize syntax. */
6201cc83814Sespie       if (type == itemize)
6211cc83814Sespie         {
6221cc83814Sespie           if (!(*insertion_stack->item_function))
6231cc83814Sespie             {
6241cc83814Sespie               free (insertion_stack->item_function);
6251cc83814Sespie               insertion_stack->item_function = xstrdup ("@bullet");
6261cc83814Sespie             }
6271cc83814Sespie         }
6281cc83814Sespie 
6291cc83814Sespie       if (!*insertion_stack->item_function)
6301cc83814Sespie         {
6311cc83814Sespie           line_error (_("%s requires an argument: the formatter for %citem"),
6321cc83814Sespie                       insertion_type_pname (type), COMMAND_PREFIX);
6331cc83814Sespie         }
6341cc83814Sespie 
6351cc83814Sespie       if (html)
6361cc83814Sespie         {
6371cc83814Sespie           if (type == itemize)
6381cc83814Sespie             {
639*1076333cSespie               add_html_block_elt ("<ul>\n");
6401cc83814Sespie               in_paragraph = 0;
6411cc83814Sespie             }
6421cc83814Sespie           else
643*1076333cSespie             { /* We are just starting, so this <dl>
644*1076333cSespie                  has no <dt> children yet.  */
645*1076333cSespie               html_deflist_has_term = 0;
646*1076333cSespie               add_html_block_elt ("<dl>\n");
647*1076333cSespie             }
6481cc83814Sespie         }
6493fb98d4aSespie       if (xml)
6503fb98d4aSespie         xml_begin_table (type, insertion_stack->item_function);
651*1076333cSespie 
652*1076333cSespie       while (input_text[input_text_offset] == '\n'
653*1076333cSespie           && input_text[input_text_offset+1] == '\n')
654*1076333cSespie         {
655*1076333cSespie           line_number++;
656*1076333cSespie           input_text_offset++;
657*1076333cSespie         }
658*1076333cSespie 
6591cc83814Sespie       break;
6601cc83814Sespie 
6611cc83814Sespie     case enumerate:
6621cc83814Sespie       close_single_paragraph ();
6631cc83814Sespie       no_indent = 0;
6641cc83814Sespie #if defined (INDENT_PARAGRAPHS_IN_TABLE)
6651cc83814Sespie       inhibit_paragraph_indentation = 0;
6661cc83814Sespie #else
6671cc83814Sespie       inhibit_paragraph_indentation = 1;
6681cc83814Sespie #endif /* !INDENT_PARAGRAPHS_IN_TABLE */
6691cc83814Sespie 
6701cc83814Sespie       current_indent += default_indentation_increment;
6711cc83814Sespie       filling_enabled = indented_fill = 1;
6721cc83814Sespie 
6731cc83814Sespie       if (html)
674*1076333cSespie         {
6751cc83814Sespie           enum_html ();
676*1076333cSespie           in_paragraph = 0;
677*1076333cSespie         }
6781cc83814Sespie 
6793fb98d4aSespie       if (xml)
6803fb98d4aSespie         xml_begin_enumerate (enumeration_arg);
6813fb98d4aSespie 
6821cc83814Sespie       if (isdigit (*enumeration_arg))
6831cc83814Sespie         start_enumerating (atoi (enumeration_arg), ENUM_DIGITS);
6841cc83814Sespie       else
6851cc83814Sespie         start_enumerating (*enumeration_arg, ENUM_ALPHA);
6861cc83814Sespie       break;
6871cc83814Sespie 
688*1076333cSespie       /* @group produces no output in info. */
6891cc83814Sespie     case group:
6901cc83814Sespie       /* Only close the paragraph if we are not inside of an
6911cc83814Sespie          @example-like environment. */
6923fb98d4aSespie       if (xml)
6933fb98d4aSespie         xml_insert_element (GROUP, START);
6943fb98d4aSespie       else if (!insertion_stack->next
6951cc83814Sespie           || (insertion_stack->next->insertion != display
6961cc83814Sespie               && insertion_stack->next->insertion != smalldisplay
6971cc83814Sespie               && insertion_stack->next->insertion != example
6981cc83814Sespie               && insertion_stack->next->insertion != smallexample
6991cc83814Sespie               && insertion_stack->next->insertion != lisp
7001cc83814Sespie               && insertion_stack->next->insertion != smalllisp
7011cc83814Sespie               && insertion_stack->next->insertion != format
7021cc83814Sespie               && insertion_stack->next->insertion != smallformat
7031cc83814Sespie               && insertion_stack->next->insertion != flushleft
7041cc83814Sespie               && insertion_stack->next->insertion != flushright))
7051cc83814Sespie         close_single_paragraph ();
7061cc83814Sespie       break;
7071cc83814Sespie 
7081cc83814Sespie     case cartouche:
709*1076333cSespie       if (html)
710*1076333cSespie 	add_html_block_elt ("<p><table class=\"cartouche\" summary=\"cartouche\" border=\"1\"><tr><td>\n");
711*1076333cSespie       if (in_menu)
712*1076333cSespie         no_discard++;
713*1076333cSespie       break;
714*1076333cSespie 
715*1076333cSespie     case floatenv:
716*1076333cSespie       /* Cannot nest floats, so complain.  */
717*1076333cSespie       if (float_active)
718*1076333cSespie         {
719*1076333cSespie           line_error (_("%cfloat environments cannot be nested"), COMMAND_PREFIX);
720*1076333cSespie           pop_insertion ();
721*1076333cSespie           break;
722*1076333cSespie         }
723*1076333cSespie 
724*1076333cSespie       float_active++;
725*1076333cSespie 
726*1076333cSespie       { /* Collect data about this float.  */
727*1076333cSespie         /* Example: @float [FLOATTYPE][,XREFLABEL][,POSITION] */
728*1076333cSespie         char floattype[200] = "";
729*1076333cSespie         char xreflabel[200] = "";
730*1076333cSespie         char position[200]  = "";
731*1076333cSespie         char *text;
732*1076333cSespie         char *caption;
733*1076333cSespie         char *shortcaption;
734*1076333cSespie         int start_of_end;
735*1076333cSespie         int save_line_number = line_number;
736*1076333cSespie         int save_input_text_offset = input_text_offset;
737*1076333cSespie         int i;
738*1076333cSespie 
739*1076333cSespie         if (strlen (insertion_stack->item_function) > 0)
740*1076333cSespie           {
741*1076333cSespie             int i = 0, t = 0, c = 0;
742*1076333cSespie             while (insertion_stack->item_function[i])
743*1076333cSespie               {
744*1076333cSespie                 if (insertion_stack->item_function[i] == ',')
745*1076333cSespie                   {
746*1076333cSespie                     switch (t)
747*1076333cSespie                       {
748*1076333cSespie                       case 0:
749*1076333cSespie                         floattype[c] = '\0';
750*1076333cSespie                         break;
751*1076333cSespie                       case 1:
752*1076333cSespie                         xreflabel[c] = '\0';
753*1076333cSespie                         break;
754*1076333cSespie                       case 2:
755*1076333cSespie                         position[c] = '\0';
756*1076333cSespie                         break;
757*1076333cSespie                       }
758*1076333cSespie                     c = 0;
759*1076333cSespie                     t++;
760*1076333cSespie                     i++;
761*1076333cSespie                     continue;
762*1076333cSespie                   }
763*1076333cSespie 
764*1076333cSespie                 switch (t)
765*1076333cSespie                   {
766*1076333cSespie                   case 0:
767*1076333cSespie                     floattype[c] = insertion_stack->item_function[i];
768*1076333cSespie                     break;
769*1076333cSespie                   case 1:
770*1076333cSespie                     xreflabel[c] = insertion_stack->item_function[i];
771*1076333cSespie                     break;
772*1076333cSespie                   case 2:
773*1076333cSespie                     position[c] = insertion_stack->item_function[i];
774*1076333cSespie                     break;
775*1076333cSespie                   }
776*1076333cSespie                 c++;
777*1076333cSespie                 i++;
778*1076333cSespie               }
779*1076333cSespie           }
780*1076333cSespie 
781*1076333cSespie         skip_whitespace_and_newlines ();
782*1076333cSespie 
783*1076333cSespie         start_of_end = get_until ("\n@end float", &text);
784*1076333cSespie 
785*1076333cSespie         /* Get also the @caption.  */
786*1076333cSespie         i = search_forward_until_pos ("\n@caption{",
787*1076333cSespie             save_input_text_offset, start_of_end);
788*1076333cSespie         if (i > -1)
789*1076333cSespie           {
790*1076333cSespie             input_text_offset = i + sizeof ("\n@caption{") - 1;
791*1076333cSespie             get_until_in_braces ("\n@end float", &caption);
792*1076333cSespie             input_text_offset = save_input_text_offset;
793*1076333cSespie           }
794*1076333cSespie         else
795*1076333cSespie           caption = "";
796*1076333cSespie 
797*1076333cSespie         /* ... and the @shortcaption.  */
798*1076333cSespie         i = search_forward_until_pos ("\n@shortcaption{",
799*1076333cSespie             save_input_text_offset, start_of_end);
800*1076333cSespie         if (i > -1)
801*1076333cSespie           {
802*1076333cSespie             input_text_offset = i + sizeof ("\n@shortcaption{") - 1;
803*1076333cSespie             get_until_in_braces ("\n@end float", &shortcaption);
804*1076333cSespie             input_text_offset = save_input_text_offset;
805*1076333cSespie           }
806*1076333cSespie         else
807*1076333cSespie           shortcaption = "";
808*1076333cSespie 
809*1076333cSespie         canon_white (xreflabel);
810*1076333cSespie         canon_white (floattype);
811*1076333cSespie         canon_white (position);
812*1076333cSespie         canon_white (caption);
813*1076333cSespie         canon_white (shortcaption);
814*1076333cSespie 
815*1076333cSespie         add_new_float (xstrdup (xreflabel),
816*1076333cSespie             xstrdup (caption), xstrdup (shortcaption),
817*1076333cSespie             xstrdup (floattype), xstrdup (position));
818*1076333cSespie 
819*1076333cSespie         /* Move to the start of the @float so the contents get processed as
820*1076333cSespie            usual.  */
821*1076333cSespie         input_text_offset = save_input_text_offset;
822*1076333cSespie         line_number = save_line_number;
823*1076333cSespie       }
824*1076333cSespie 
825*1076333cSespie       if (html)
826*1076333cSespie         add_html_block_elt ("<div class=\"float\">\n");
827*1076333cSespie       else if (docbook)
828*1076333cSespie         xml_insert_element (FLOAT, START);
829*1076333cSespie       else if (xml)
830*1076333cSespie         {
831*1076333cSespie           xml_insert_element_with_attribute (FLOAT, START,
832*1076333cSespie               "name=\"%s\"", current_float_id ());
833*1076333cSespie 
834*1076333cSespie           xml_insert_element (FLOATTYPE, START);
835*1076333cSespie           execute_string ("%s", current_float_type ());
836*1076333cSespie           xml_insert_element (FLOATTYPE, END);
837*1076333cSespie 
838*1076333cSespie           xml_insert_element (FLOATPOS, START);
839*1076333cSespie           execute_string ("%s", current_float_position ());
840*1076333cSespie           xml_insert_element (FLOATPOS, END);
841*1076333cSespie         }
842*1076333cSespie       else
843*1076333cSespie         { /* Info */
844*1076333cSespie           close_single_paragraph ();
845*1076333cSespie           inhibit_paragraph_indentation = 1;
846*1076333cSespie         }
847*1076333cSespie 
848*1076333cSespie       /* Anchor now.  Note that XML documents get their
849*1076333cSespie          anchors with <float name="anchor"> tag.  */
850*1076333cSespie       if ((!xml || docbook) && strlen (current_float_id ()) > 0)
851*1076333cSespie         execute_string ("@anchor{%s}", current_float_id ());
852*1076333cSespie 
853*1076333cSespie       break;
854*1076333cSespie 
855*1076333cSespie       /* Insertions that are no-ops in info, but do something in TeX. */
8561cc83814Sespie     case ifclear:
857*1076333cSespie     case ifdocbook:
8581cc83814Sespie     case ifhtml:
8591cc83814Sespie     case ifinfo:
860*1076333cSespie     case ifnotdocbook:
8611cc83814Sespie     case ifnothtml:
8621cc83814Sespie     case ifnotinfo:
8633fb98d4aSespie     case ifnotplaintext:
8641cc83814Sespie     case ifnottex:
865*1076333cSespie     case ifnotxml:
8663fb98d4aSespie     case ifplaintext:
8671cc83814Sespie     case ifset:
8681cc83814Sespie     case iftex:
869*1076333cSespie     case ifxml:
8701cc83814Sespie     case rawtex:
8711cc83814Sespie       if (in_menu)
8721cc83814Sespie         no_discard++;
8731cc83814Sespie       break;
8741cc83814Sespie 
875*1076333cSespie     case rawdocbook:
8761cc83814Sespie     case rawhtml:
877*1076333cSespie     case rawxml:
878*1076333cSespie       raw_output_block++;
879*1076333cSespie 
880*1076333cSespie       if (raw_output_block > 0)
881*1076333cSespie         {
882*1076333cSespie           xml_no_para = 1;
8831cc83814Sespie           escape_html = 0;
884*1076333cSespie           xml_keep_space++;
885*1076333cSespie         }
886*1076333cSespie 
887*1076333cSespie       {
888*1076333cSespie         /* Some deuglification for improved readability.  */
889*1076333cSespie         extern int xml_in_para;
890*1076333cSespie         if (xml && !xml_in_para && xml_indentation_increment > 0)
891*1076333cSespie           add_char ('\n');
892*1076333cSespie       }
893*1076333cSespie 
8941cc83814Sespie       break;
8951cc83814Sespie 
8961cc83814Sespie     case defcv:
8971cc83814Sespie     case deffn:
8981cc83814Sespie     case defivar:
8991cc83814Sespie     case defmac:
9001cc83814Sespie     case defmethod:
9011cc83814Sespie     case defop:
9021cc83814Sespie     case defopt:
9031cc83814Sespie     case defspec:
9041cc83814Sespie     case deftp:
905*1076333cSespie     case deftypecv:
9061cc83814Sespie     case deftypefn:
9071cc83814Sespie     case deftypefun:
9081cc83814Sespie     case deftypeivar:
9091cc83814Sespie     case deftypemethod:
9101cc83814Sespie     case deftypeop:
9111cc83814Sespie     case deftypevar:
9121cc83814Sespie     case deftypevr:
9131cc83814Sespie     case defun:
9141cc83814Sespie     case defvar:
9151cc83814Sespie     case defvr:
9161cc83814Sespie       inhibit_paragraph_indentation = 1;
9171cc83814Sespie       filling_enabled = indented_fill = 1;
9181cc83814Sespie       current_indent += default_indentation_increment;
9191cc83814Sespie       no_indent = 0;
920*1076333cSespie       if (xml)
921*1076333cSespie 	xml_begin_definition ();
9221cc83814Sespie       break;
9231cc83814Sespie 
9241cc83814Sespie     case flushleft:
9251cc83814Sespie       close_single_paragraph ();
9261cc83814Sespie       inhibit_paragraph_indentation = 1;
9271cc83814Sespie       filling_enabled = indented_fill = no_indent = 0;
9283fb98d4aSespie       if (html)
929*1076333cSespie         add_html_block_elt ("<div align=\"left\">");
9301cc83814Sespie       break;
9311cc83814Sespie 
9321cc83814Sespie     case flushright:
9331cc83814Sespie       close_single_paragraph ();
9341cc83814Sespie       filling_enabled = indented_fill = no_indent = 0;
9351cc83814Sespie       inhibit_paragraph_indentation = 1;
9361cc83814Sespie       force_flush_right++;
9373fb98d4aSespie       if (html)
938*1076333cSespie         add_html_block_elt ("<div align=\"right\">");
939*1076333cSespie       break;
940*1076333cSespie 
941*1076333cSespie     case titlepage:
942*1076333cSespie       xml_insert_element (TITLEPAGE, START);
9431cc83814Sespie       break;
9441cc83814Sespie 
9451cc83814Sespie     default:
9461cc83814Sespie       line_error ("begin_insertion internal error: type=%d", type);
9471cc83814Sespie     }
9481cc83814Sespie 
9491cc83814Sespie   if (!no_discard)
9501cc83814Sespie     discard_until ("\n");
9511cc83814Sespie }
9521cc83814Sespie 
9531cc83814Sespie /* Try to end the insertion with the specified TYPE.  With a value of
9541cc83814Sespie    `bad_type', TYPE gets translated to match the value currently on top
9551cc83814Sespie    of the stack.  Otherwise, if TYPE doesn't match the top of the
9561cc83814Sespie    insertion stack, give error. */
957*1076333cSespie static void
end_insertion(int type)958*1076333cSespie end_insertion (int type)
9591cc83814Sespie {
960*1076333cSespie   int temp_type;
9611cc83814Sespie 
9621cc83814Sespie   if (!insertion_level)
9631cc83814Sespie     return;
9641cc83814Sespie 
9651cc83814Sespie   temp_type = current_insertion_type ();
9661cc83814Sespie 
9671cc83814Sespie   if (type == bad_type)
9681cc83814Sespie     type = temp_type;
9691cc83814Sespie 
9701cc83814Sespie   if (type != temp_type)
9711cc83814Sespie     {
9721cc83814Sespie       line_error
9731cc83814Sespie         (_("`@end' expected `%s', but saw `%s'"),
9741cc83814Sespie          insertion_type_pname (temp_type), insertion_type_pname (type));
9751cc83814Sespie       return;
9761cc83814Sespie     }
9771cc83814Sespie 
9781cc83814Sespie   pop_insertion ();
9791cc83814Sespie 
9803fb98d4aSespie   if (xml)
9813fb98d4aSespie     {
9823fb98d4aSespie       switch (type)
9833fb98d4aSespie         {
9843fb98d4aSespie         case ifinfo:
9853fb98d4aSespie         case documentdescription:
9863fb98d4aSespie           break;
9873fb98d4aSespie         case quotation:
988*1076333cSespie           xml_insert_quotation ("", END);
9893fb98d4aSespie           break;
9903fb98d4aSespie         case example:
9913fb98d4aSespie           xml_insert_element (EXAMPLE, END);
992*1076333cSespie           if (docbook && current_insertion_type () == floatenv)
993*1076333cSespie             xml_insert_element (FLOATEXAMPLE, END);
9943fb98d4aSespie           break;
9953fb98d4aSespie         case smallexample:
9963fb98d4aSespie           xml_insert_element (SMALLEXAMPLE, END);
997*1076333cSespie           if (docbook && current_insertion_type () == floatenv)
998*1076333cSespie             xml_insert_element (FLOATEXAMPLE, END);
9993fb98d4aSespie           break;
10003fb98d4aSespie         case lisp:
10013fb98d4aSespie           xml_insert_element (LISP, END);
1002*1076333cSespie           if (docbook && current_insertion_type () == floatenv)
1003*1076333cSespie             xml_insert_element (FLOATEXAMPLE, END);
10043fb98d4aSespie           break;
10053fb98d4aSespie         case smalllisp:
10063fb98d4aSespie           xml_insert_element (SMALLLISP, END);
1007*1076333cSespie           if (docbook && current_insertion_type () == floatenv)
1008*1076333cSespie             xml_insert_element (FLOATEXAMPLE, END);
10093fb98d4aSespie           break;
10103fb98d4aSespie         case cartouche:
10113fb98d4aSespie           xml_insert_element (CARTOUCHE, END);
10123fb98d4aSespie           break;
10133fb98d4aSespie         case format:
1014*1076333cSespie 	  if (docbook && xml_in_bookinfo && xml_in_abstract)
1015*1076333cSespie 	    {
1016*1076333cSespie 	      xml_insert_element (ABSTRACT, END);
1017*1076333cSespie 	      xml_in_abstract = 0;
1018*1076333cSespie 	    }
1019*1076333cSespie 	  else
10203fb98d4aSespie 	    xml_insert_element (FORMAT, END);
10213fb98d4aSespie           break;
10223fb98d4aSespie         case smallformat:
10233fb98d4aSespie           xml_insert_element (SMALLFORMAT, END);
10243fb98d4aSespie           break;
10253fb98d4aSespie         case display:
10263fb98d4aSespie           xml_insert_element (DISPLAY, END);
10273fb98d4aSespie           break;
10283fb98d4aSespie         case smalldisplay:
10293fb98d4aSespie           xml_insert_element (SMALLDISPLAY, END);
10303fb98d4aSespie           break;
10313fb98d4aSespie         case table:
10323fb98d4aSespie         case ftable:
10333fb98d4aSespie         case vtable:
10343fb98d4aSespie         case itemize:
10353fb98d4aSespie           xml_end_table (type);
10363fb98d4aSespie           break;
10373fb98d4aSespie         case enumerate:
1038*1076333cSespie           xml_end_enumerate ();
10393fb98d4aSespie           break;
10403fb98d4aSespie         case group:
10413fb98d4aSespie           xml_insert_element (GROUP, END);
10423fb98d4aSespie           break;
1043*1076333cSespie 	case titlepage:
1044*1076333cSespie 	  xml_insert_element (TITLEPAGE, END);
1045*1076333cSespie 	  break;
10463fb98d4aSespie         }
10473fb98d4aSespie     }
10481cc83814Sespie   switch (type)
10491cc83814Sespie     {
10501cc83814Sespie       /* Insertions which have no effect on paragraph formatting. */
10513fb98d4aSespie     case copying:
1052*1076333cSespie       line_number--;
1053*1076333cSespie       break;
1054*1076333cSespie 
10551cc83814Sespie     case ifclear:
1056*1076333cSespie     case ifdocbook:
10571cc83814Sespie     case ifinfo:
10583fb98d4aSespie     case ifhtml:
1059*1076333cSespie     case ifnotdocbook:
10601cc83814Sespie     case ifnothtml:
10611cc83814Sespie     case ifnotinfo:
10623fb98d4aSespie     case ifnotplaintext:
10631cc83814Sespie     case ifnottex:
1064*1076333cSespie     case ifnotxml:
10653fb98d4aSespie     case ifplaintext:
10661cc83814Sespie     case ifset:
10671cc83814Sespie     case iftex:
1068*1076333cSespie     case ifxml:
10691cc83814Sespie     case rawtex:
1070*1076333cSespie     case titlepage:
10711cc83814Sespie       break;
10721cc83814Sespie 
1073*1076333cSespie     case rawdocbook:
10741cc83814Sespie     case rawhtml:
1075*1076333cSespie     case rawxml:
1076*1076333cSespie       raw_output_block--;
1077*1076333cSespie 
1078*1076333cSespie       if (raw_output_block <= 0)
1079*1076333cSespie         {
1080*1076333cSespie           xml_no_para = 0;
10811cc83814Sespie           escape_html = 1;
1082*1076333cSespie           xml_keep_space--;
1083*1076333cSespie         }
1084*1076333cSespie 
1085*1076333cSespie       if ((xml || html) && output_paragraph[output_paragraph_offset-1] == '\n')
1086*1076333cSespie         output_paragraph_offset--;
10871cc83814Sespie       break;
10881cc83814Sespie 
10891cc83814Sespie     case detailmenu:
1090*1076333cSespie       if (xml)
1091*1076333cSespie         xml_insert_element (DETAILMENU, END);
1092*1076333cSespie 
10931cc83814Sespie       in_detailmenu--;          /* No longer hacking menus. */
10941cc83814Sespie       if (!in_menu)
10951cc83814Sespie         {
10961cc83814Sespie           if (!no_headers)
10971cc83814Sespie             close_insertion_paragraph ();
10981cc83814Sespie         }
10991cc83814Sespie       break;
11001cc83814Sespie 
11013fb98d4aSespie     case direntry:              /* Eaten if html. */
11023fb98d4aSespie       insert_string ("END-INFO-DIR-ENTRY\n\n");
11033fb98d4aSespie       close_insertion_paragraph ();
11043fb98d4aSespie       break;
11053fb98d4aSespie 
1106*1076333cSespie     case documentdescription:
1107*1076333cSespie       if (xml)
1108*1076333cSespie         insert_string (document_description);
1109*1076333cSespie         xml_insert_element (DOCUMENTDESCRIPTION, END);
1110*1076333cSespie       break;
1111*1076333cSespie 
11121cc83814Sespie     case menu:
11131cc83814Sespie       in_menu--;                /* No longer hacking menus. */
1114*1076333cSespie       if (html && !no_headers)
1115*1076333cSespie         add_html_block_elt ("</ul>\n");
1116*1076333cSespie       else if (!no_headers && !xml)
11171cc83814Sespie         close_insertion_paragraph ();
11181cc83814Sespie       break;
11191cc83814Sespie 
11201cc83814Sespie     case multitable:
11211cc83814Sespie       end_multitable ();
11221cc83814Sespie       break;
11231cc83814Sespie 
11241cc83814Sespie     case enumerate:
11251cc83814Sespie       stop_enumerating ();
11261cc83814Sespie       close_insertion_paragraph ();
11271cc83814Sespie       current_indent -= default_indentation_increment;
11281cc83814Sespie       if (html)
1129*1076333cSespie         add_html_block_elt ("</ol>\n");
11301cc83814Sespie       break;
11311cc83814Sespie 
11321cc83814Sespie     case flushleft:
11333fb98d4aSespie       if (html)
1134*1076333cSespie         add_html_block_elt ("</div>\n");
1135*1076333cSespie       close_insertion_paragraph ();
1136*1076333cSespie       break;
1137*1076333cSespie 
1138*1076333cSespie     case cartouche:
1139*1076333cSespie       if (html)
1140*1076333cSespie 	add_html_block_elt ("</td></tr></table>\n");
11413fb98d4aSespie       close_insertion_paragraph ();
11423fb98d4aSespie       break;
11433fb98d4aSespie 
11441cc83814Sespie     case group:
1145*1076333cSespie       if (!xml || docbook)
11461cc83814Sespie         close_insertion_paragraph ();
11471cc83814Sespie       break;
11481cc83814Sespie 
1149*1076333cSespie     case floatenv:
1150*1076333cSespie       if (xml)
1151*1076333cSespie         xml_insert_element (FLOAT, END);
1152*1076333cSespie       else
1153*1076333cSespie         {
1154*1076333cSespie           if (html)
1155*1076333cSespie             add_html_block_elt ("<p><strong class=\"float-caption\">");
1156*1076333cSespie           else
1157*1076333cSespie             close_paragraph ();
1158*1076333cSespie 
1159*1076333cSespie           no_indent = 1;
1160*1076333cSespie 
1161*1076333cSespie           /* Legend:
1162*1076333cSespie                1) @float Foo,lbl & no caption:    Foo 1.1
1163*1076333cSespie                2) @float Foo & no caption:        Foo
1164*1076333cSespie                3) @float ,lbl & no caption:       1.1
1165*1076333cSespie                4) @float & no caption:                    */
1166*1076333cSespie 
1167*1076333cSespie           if (!xml && !html)
1168*1076333cSespie             indent (current_indent);
1169*1076333cSespie 
1170*1076333cSespie           if (strlen (current_float_type ()))
1171*1076333cSespie             execute_string ("%s", current_float_type ());
1172*1076333cSespie 
1173*1076333cSespie           if (strlen (current_float_id ()) > 0)
1174*1076333cSespie             {
1175*1076333cSespie               if (strlen (current_float_type ()) > 0)
1176*1076333cSespie                 add_char (' ');
1177*1076333cSespie 
1178*1076333cSespie               add_word (current_float_number ());
1179*1076333cSespie             }
1180*1076333cSespie 
1181*1076333cSespie           if (strlen (current_float_title ()) > 0)
1182*1076333cSespie             {
1183*1076333cSespie               if (strlen (current_float_type ()) > 0
1184*1076333cSespie                   || strlen (current_float_id ()) > 0)
1185*1076333cSespie                 insert_string (": ");
1186*1076333cSespie 
1187*1076333cSespie               execute_string ("%s", current_float_title ());
1188*1076333cSespie             }
1189*1076333cSespie 
1190*1076333cSespie           /* Indent the following paragraph. */
1191*1076333cSespie           inhibit_paragraph_indentation = 0;
1192*1076333cSespie 
1193*1076333cSespie           if (html)
1194*1076333cSespie             add_word ("</strong></p></div>\n");
1195*1076333cSespie           else
1196*1076333cSespie             close_paragraph ();
1197*1076333cSespie         }
1198*1076333cSespie       float_active--;
1199*1076333cSespie       break;
1200*1076333cSespie 
12011cc83814Sespie     case format:
12021cc83814Sespie     case smallformat:
12031cc83814Sespie     case display:
12041cc83814Sespie     case smalldisplay:
12051cc83814Sespie     case example:
12061cc83814Sespie     case smallexample:
12071cc83814Sespie     case lisp:
12081cc83814Sespie     case smalllisp:
12091cc83814Sespie     case quotation:
12101cc83814Sespie       /* @format and @smallformat are the only fixed_width insertion
12111cc83814Sespie          without a change in indentation. */
1212*1076333cSespie       if (type != format && type != smallformat && type != quotation)
1213*1076333cSespie         current_indent -= example_indentation_increment;
1214*1076333cSespie       else if (type == quotation)
12151cc83814Sespie         current_indent -= default_indentation_increment;
12161cc83814Sespie 
12171cc83814Sespie       if (html)
1218*1076333cSespie         { /* The complex code in close_paragraph that kills whitespace
1219*1076333cSespie              does not function here, since we've inserted non-whitespace
1220*1076333cSespie              (the </whatever>) before it.  The indentation already got
1221*1076333cSespie              inserted at the end of the last example line, so we have to
1222*1076333cSespie              delete it, or browsers wind up showing an extra blank line.  */
1223*1076333cSespie           kill_self_indent (default_indentation_increment);
1224*1076333cSespie           add_html_block_elt (type == quotation
1225*1076333cSespie               ? "</blockquote>\n" : "</pre>\n");
1226*1076333cSespie         }
12271cc83814Sespie 
12281cc83814Sespie       /* The ending of one of these insertions always marks the
1229*1076333cSespie          start of a new paragraph, except for the XML output. */
1230*1076333cSespie       if (!xml || docbook)
12311cc83814Sespie         close_insertion_paragraph ();
1232*1076333cSespie 
1233*1076333cSespie       /* </pre> closes paragraph without messing with </p>.  */
1234*1076333cSespie       if (html && type != quotation)
1235*1076333cSespie           paragraph_is_open = 0;
12361cc83814Sespie       break;
12371cc83814Sespie 
12381cc83814Sespie     case table:
12391cc83814Sespie     case ftable:
12401cc83814Sespie     case vtable:
12411cc83814Sespie       current_indent -= default_indentation_increment;
12421cc83814Sespie       if (html)
1243*1076333cSespie         add_html_block_elt ("</dl>\n");
1244*1076333cSespie       close_insertion_paragraph ();
12451cc83814Sespie       break;
12461cc83814Sespie 
12471cc83814Sespie     case itemize:
12481cc83814Sespie       current_indent -= default_indentation_increment;
12491cc83814Sespie       if (html)
1250*1076333cSespie         add_html_block_elt ("</ul>\n");
12511cc83814Sespie       close_insertion_paragraph ();
12521cc83814Sespie       break;
12531cc83814Sespie 
12541cc83814Sespie     case flushright:
12551cc83814Sespie       force_flush_right--;
12563fb98d4aSespie       if (html)
1257*1076333cSespie         add_html_block_elt ("</div>\n");
12581cc83814Sespie       close_insertion_paragraph ();
12591cc83814Sespie       break;
12601cc83814Sespie 
12611cc83814Sespie     /* Handle the @defun insertions with this default clause. */
12621cc83814Sespie     default:
12631cc83814Sespie       {
1264*1076333cSespie         int base_type;
12651cc83814Sespie 
12661cc83814Sespie         if (type < defcv || type > defvr)
12671cc83814Sespie           line_error ("end_insertion internal error: type=%d", type);
12681cc83814Sespie 
12691cc83814Sespie         base_type = get_base_type (type);
12701cc83814Sespie         switch (base_type)
12711cc83814Sespie           {
12721cc83814Sespie           case deffn:
12731cc83814Sespie           case defvr:
12741cc83814Sespie           case deftp:
1275*1076333cSespie           case deftypecv:
12761cc83814Sespie           case deftypefn:
12771cc83814Sespie           case deftypevr:
12781cc83814Sespie           case defcv:
12791cc83814Sespie           case defop:
12801cc83814Sespie           case deftypemethod:
12811cc83814Sespie           case deftypeop:
12821cc83814Sespie           case deftypeivar:
12831cc83814Sespie             if (html)
1284*1076333cSespie               {
1285*1076333cSespie                 if (paragraph_is_open)
1286*1076333cSespie                   add_html_block_elt ("</p>");
1287*1076333cSespie                 /* close the div and blockquote which has been opened in defun.c */
1288*1076333cSespie                 if (!rollback_empty_tag ("blockquote"))
1289*1076333cSespie                   add_html_block_elt ("</blockquote>");
1290*1076333cSespie                 add_html_block_elt ("</div>\n");
1291*1076333cSespie               }
1292*1076333cSespie 	    if (xml)
1293*1076333cSespie 	      xml_end_definition ();
12941cc83814Sespie             break;
12951cc83814Sespie           } /* switch (base_type)... */
12961cc83814Sespie 
12971cc83814Sespie         current_indent -= default_indentation_increment;
12981cc83814Sespie         close_insertion_paragraph ();
12991cc83814Sespie       }
13001cc83814Sespie       break;
13011cc83814Sespie 
13021cc83814Sespie     }
13031cc83814Sespie 
13041cc83814Sespie   if (current_indent < 0)
13051cc83814Sespie     line_error ("end_insertion internal error: current indent=%d",
13061cc83814Sespie                 current_indent);
13071cc83814Sespie }
13081cc83814Sespie 
13091cc83814Sespie /* Insertions cannot cross certain boundaries, such as node beginnings.  In
13101cc83814Sespie    code that creates such boundaries, you should call `discard_insertions'
13111cc83814Sespie    before doing anything else.  It prints the errors for you, and cleans up
13121cc83814Sespie    the insertion stack.
13131cc83814Sespie 
13141cc83814Sespie    With nonzero SPECIALS_OK argument, allows unmatched
13151cc83814Sespie    @if... conditionals, otherwise not.  This is because conditionals can
13161cc83814Sespie    cross node boundaries.  Always happens with the @top node, for example.  */
13171cc83814Sespie void
discard_insertions(int specials_ok)1318*1076333cSespie discard_insertions (int specials_ok)
13191cc83814Sespie {
13201cc83814Sespie   int real_line_number = line_number;
13211cc83814Sespie   while (insertion_stack)
13221cc83814Sespie     {
13231cc83814Sespie       if (specials_ok
13241cc83814Sespie           && ((ifclear <= insertion_stack->insertion
13251cc83814Sespie                && insertion_stack->insertion <= iftex)
1326*1076333cSespie               || insertion_stack->insertion == rawdocbook
13271cc83814Sespie               || insertion_stack->insertion == rawhtml
1328*1076333cSespie               || insertion_stack->insertion == rawxml
13291cc83814Sespie               || insertion_stack->insertion == rawtex))
13301cc83814Sespie         break;
13311cc83814Sespie       else
13321cc83814Sespie         {
1333*1076333cSespie           const char *offender = insertion_type_pname (insertion_stack->insertion);
13341cc83814Sespie 
13353fb98d4aSespie           file_line_error (insertion_stack->filename,
13363fb98d4aSespie                            insertion_stack->line_number,
13373fb98d4aSespie                            _("No matching `%cend %s'"), COMMAND_PREFIX,
13383fb98d4aSespie                            offender);
13391cc83814Sespie           pop_insertion ();
13401cc83814Sespie         }
13411cc83814Sespie     }
13421cc83814Sespie   line_number = real_line_number;
13431cc83814Sespie }
13441cc83814Sespie 
13451cc83814Sespie /* Insertion (environment) commands.  */
13461cc83814Sespie 
13471cc83814Sespie void
cm_quotation(void)1348*1076333cSespie cm_quotation (void)
13491cc83814Sespie {
1350*1076333cSespie   /* We start the blockquote element in the insertion.  */
13511cc83814Sespie   begin_insertion (quotation);
13521cc83814Sespie }
13531cc83814Sespie 
13541cc83814Sespie void
cm_example(void)1355*1076333cSespie cm_example (void)
13561cc83814Sespie {
1357*1076333cSespie   if (docbook && current_insertion_type () == floatenv)
1358*1076333cSespie     xml_begin_docbook_float (FLOATEXAMPLE);
1359*1076333cSespie 
13603fb98d4aSespie   if (xml)
1361*1076333cSespie     {
1362*1076333cSespie       /* Rollback previous newlines.  These occur between
1363*1076333cSespie          </para> and <example>.  */
1364*1076333cSespie       if (output_paragraph[output_paragraph_offset-1] == '\n')
1365*1076333cSespie         output_paragraph_offset--;
1366*1076333cSespie 
13673fb98d4aSespie       xml_insert_element (EXAMPLE, START);
1368*1076333cSespie 
1369*1076333cSespie       /* Make sure example text is starting on a new line
1370*1076333cSespie          for improved readability.  */
1371*1076333cSespie       if (docbook)
1372*1076333cSespie         add_char ('\n');
1373*1076333cSespie     }
1374*1076333cSespie 
13751cc83814Sespie   begin_insertion (example);
13761cc83814Sespie }
13771cc83814Sespie 
13781cc83814Sespie void
cm_smallexample(void)1379*1076333cSespie cm_smallexample (void)
13801cc83814Sespie {
1381*1076333cSespie   if (docbook && current_insertion_type () == floatenv)
1382*1076333cSespie     xml_begin_docbook_float (FLOATEXAMPLE);
1383*1076333cSespie 
13843fb98d4aSespie   if (xml)
1385*1076333cSespie     {
1386*1076333cSespie       /* See cm_example comments about newlines.  */
1387*1076333cSespie       if (output_paragraph[output_paragraph_offset-1] == '\n')
1388*1076333cSespie         output_paragraph_offset--;
13893fb98d4aSespie       xml_insert_element (SMALLEXAMPLE, START);
1390*1076333cSespie       if (docbook)
1391*1076333cSespie         add_char ('\n');
1392*1076333cSespie     }
1393*1076333cSespie 
13941cc83814Sespie   begin_insertion (smallexample);
13951cc83814Sespie }
13961cc83814Sespie 
13971cc83814Sespie void
cm_lisp(void)1398*1076333cSespie cm_lisp (void)
13991cc83814Sespie {
1400*1076333cSespie   if (docbook && current_insertion_type () == floatenv)
1401*1076333cSespie     xml_begin_docbook_float (FLOATEXAMPLE);
1402*1076333cSespie 
14033fb98d4aSespie   if (xml)
1404*1076333cSespie     {
1405*1076333cSespie       /* See cm_example comments about newlines.  */
1406*1076333cSespie       if (output_paragraph[output_paragraph_offset-1] == '\n')
1407*1076333cSespie         output_paragraph_offset--;
14083fb98d4aSespie       xml_insert_element (LISP, START);
1409*1076333cSespie       if (docbook)
1410*1076333cSespie         add_char ('\n');
1411*1076333cSespie     }
1412*1076333cSespie 
14131cc83814Sespie   begin_insertion (lisp);
14141cc83814Sespie }
14151cc83814Sespie 
14161cc83814Sespie void
cm_smalllisp(void)1417*1076333cSespie cm_smalllisp (void)
14181cc83814Sespie {
1419*1076333cSespie   if (docbook && current_insertion_type () == floatenv)
1420*1076333cSespie     xml_begin_docbook_float (FLOATEXAMPLE);
1421*1076333cSespie 
14223fb98d4aSespie   if (xml)
1423*1076333cSespie     {
1424*1076333cSespie       /* See cm_example comments about newlines.  */
1425*1076333cSespie       if (output_paragraph[output_paragraph_offset-1] == '\n')
1426*1076333cSespie         output_paragraph_offset--;
14273fb98d4aSespie       xml_insert_element (SMALLLISP, START);
1428*1076333cSespie       if (docbook)
1429*1076333cSespie         add_char ('\n');
1430*1076333cSespie     }
1431*1076333cSespie 
14321cc83814Sespie   begin_insertion (smalllisp);
14331cc83814Sespie }
14341cc83814Sespie 
14351cc83814Sespie void
cm_cartouche(void)1436*1076333cSespie cm_cartouche (void)
14371cc83814Sespie {
1438*1076333cSespie   if (docbook && current_insertion_type () == floatenv)
1439*1076333cSespie     xml_begin_docbook_float (CARTOUCHE);
1440*1076333cSespie 
14413fb98d4aSespie   if (xml)
14423fb98d4aSespie     xml_insert_element (CARTOUCHE, START);
14431cc83814Sespie   begin_insertion (cartouche);
14441cc83814Sespie }
14451cc83814Sespie 
14461cc83814Sespie void
cm_copying(void)1447*1076333cSespie cm_copying (void)
14483fb98d4aSespie {
14493fb98d4aSespie   begin_insertion (copying);
14503fb98d4aSespie }
14513fb98d4aSespie 
14523fb98d4aSespie /* Not an insertion, despite the name, but it goes with cm_copying.  */
14533fb98d4aSespie void
cm_insert_copying(void)1454*1076333cSespie cm_insert_copying (void)
14553fb98d4aSespie {
1456*1076333cSespie   if (!copying_text)
1457*1076333cSespie     {
1458*1076333cSespie       warning ("@copying not used before %s", command);
1459*1076333cSespie       return;
1460*1076333cSespie     }
1461*1076333cSespie 
1462*1076333cSespie   execute_string ("%s", copying_text);
1463*1076333cSespie 
1464*1076333cSespie   if (!xml && !html)
1465*1076333cSespie     {
1466*1076333cSespie       add_word ("\n\n");
1467*1076333cSespie       /* Update output_position so that the node positions in the tag
1468*1076333cSespie          tables will take account of the copying text.  */
1469*1076333cSespie       flush_output ();
14703fb98d4aSespie     }
14713fb98d4aSespie }
14723fb98d4aSespie 
14733fb98d4aSespie void
cm_format(void)1474*1076333cSespie cm_format (void)
14751cc83814Sespie {
14763fb98d4aSespie   if (xml)
1477*1076333cSespie     {
1478*1076333cSespie       if (docbook && xml_in_bookinfo)
1479*1076333cSespie 	{
1480*1076333cSespie 	  xml_insert_element (ABSTRACT, START);
1481*1076333cSespie 	  xml_in_abstract = 1;
1482*1076333cSespie 	}
1483*1076333cSespie       else
1484*1076333cSespie         {
1485*1076333cSespie           /* See cm_example comments about newlines.  */
1486*1076333cSespie           if (output_paragraph[output_paragraph_offset-1] == '\n')
1487*1076333cSespie             output_paragraph_offset--;
14883fb98d4aSespie           xml_insert_element (FORMAT, START);
1489*1076333cSespie           if (docbook)
1490*1076333cSespie             add_char ('\n');
1491*1076333cSespie         }
1492*1076333cSespie     }
14931cc83814Sespie   begin_insertion (format);
14941cc83814Sespie }
14951cc83814Sespie 
14961cc83814Sespie void
cm_smallformat(void)1497*1076333cSespie cm_smallformat (void)
14981cc83814Sespie {
14993fb98d4aSespie   if (xml)
1500*1076333cSespie     {
1501*1076333cSespie       /* See cm_example comments about newlines.  */
1502*1076333cSespie       if (output_paragraph[output_paragraph_offset-1] == '\n')
1503*1076333cSespie         output_paragraph_offset--;
15043fb98d4aSespie       xml_insert_element (SMALLFORMAT, START);
1505*1076333cSespie       if (docbook)
1506*1076333cSespie         add_char ('\n');
1507*1076333cSespie     }
1508*1076333cSespie 
15091cc83814Sespie   begin_insertion (smallformat);
15101cc83814Sespie }
15111cc83814Sespie 
15121cc83814Sespie void
cm_display(void)1513*1076333cSespie cm_display (void)
15141cc83814Sespie {
15153fb98d4aSespie   if (xml)
1516*1076333cSespie     {
1517*1076333cSespie       /* See cm_example comments about newlines.  */
1518*1076333cSespie       if (output_paragraph[output_paragraph_offset-1] == '\n')
1519*1076333cSespie         output_paragraph_offset--;
15203fb98d4aSespie       xml_insert_element (DISPLAY, START);
1521*1076333cSespie       if (docbook)
1522*1076333cSespie         add_char ('\n');
1523*1076333cSespie     }
1524*1076333cSespie 
15251cc83814Sespie   begin_insertion (display);
15261cc83814Sespie }
15271cc83814Sespie 
15281cc83814Sespie void
cm_smalldisplay(void)1529*1076333cSespie cm_smalldisplay (void)
15301cc83814Sespie {
15313fb98d4aSespie   if (xml)
1532*1076333cSespie     {
1533*1076333cSespie       /* See cm_example comments about newlines.  */
1534*1076333cSespie       if (output_paragraph[output_paragraph_offset-1] == '\n')
1535*1076333cSespie         output_paragraph_offset--;
15363fb98d4aSespie       xml_insert_element (SMALLDISPLAY, START);
1537*1076333cSespie       if (docbook)
1538*1076333cSespie         add_char ('\n');
1539*1076333cSespie     }
1540*1076333cSespie 
15411cc83814Sespie   begin_insertion (smalldisplay);
15421cc83814Sespie }
15431cc83814Sespie 
15441cc83814Sespie void
cm_direntry(void)1545*1076333cSespie cm_direntry (void)
15461cc83814Sespie {
1547*1076333cSespie   if (html || xml || no_headers)
15481cc83814Sespie     command_name_condition ();
15491cc83814Sespie   else
15501cc83814Sespie     begin_insertion (direntry);
15511cc83814Sespie }
15521cc83814Sespie 
15531cc83814Sespie void
cm_documentdescription(void)1554*1076333cSespie cm_documentdescription (void)
15553fb98d4aSespie {
1556*1076333cSespie   if (html)
15573fb98d4aSespie     begin_insertion (documentdescription);
1558*1076333cSespie 
1559*1076333cSespie   else if (xml)
1560*1076333cSespie     {
1561*1076333cSespie       xml_insert_element (DOCUMENTDESCRIPTION, START);
1562*1076333cSespie       begin_insertion (documentdescription);
1563*1076333cSespie     }
1564*1076333cSespie 
15653fb98d4aSespie   else
15663fb98d4aSespie     command_name_condition ();
15673fb98d4aSespie }
15683fb98d4aSespie 
15693fb98d4aSespie 
15703fb98d4aSespie void
cm_itemize(void)1571*1076333cSespie cm_itemize (void)
15721cc83814Sespie {
15731cc83814Sespie   begin_insertion (itemize);
15741cc83814Sespie }
15751cc83814Sespie 
15761cc83814Sespie /* Start an enumeration insertion of type TYPE.  If the user supplied
15771cc83814Sespie    no argument on the line, then use DEFAULT_STRING as the initial string. */
15781cc83814Sespie static void
do_enumeration(int type,char * default_string)1579*1076333cSespie do_enumeration (int type, char *default_string)
15801cc83814Sespie {
15811cc83814Sespie   get_until_in_line (0, ".", &enumeration_arg);
15821cc83814Sespie   canon_white (enumeration_arg);
15831cc83814Sespie 
15841cc83814Sespie   if (!*enumeration_arg)
15851cc83814Sespie     {
15861cc83814Sespie       free (enumeration_arg);
15871cc83814Sespie       enumeration_arg = xstrdup (default_string);
15881cc83814Sespie     }
15891cc83814Sespie 
15901cc83814Sespie   if (!isdigit (*enumeration_arg) && !isletter (*enumeration_arg))
15911cc83814Sespie     {
15921cc83814Sespie       warning (_("%s requires letter or digit"), insertion_type_pname (type));
15931cc83814Sespie 
15941cc83814Sespie       switch (type)
15951cc83814Sespie         {
15961cc83814Sespie         case enumerate:
15971cc83814Sespie           default_string = "1";
15981cc83814Sespie           break;
15991cc83814Sespie         }
16001cc83814Sespie       enumeration_arg = xstrdup (default_string);
16011cc83814Sespie     }
16021cc83814Sespie   begin_insertion (type);
16031cc83814Sespie }
16041cc83814Sespie 
16051cc83814Sespie void
cm_enumerate(void)1606*1076333cSespie cm_enumerate (void)
16071cc83814Sespie {
16081cc83814Sespie   do_enumeration (enumerate, "1");
16091cc83814Sespie }
16101cc83814Sespie 
16113fb98d4aSespie /*  Handle verbatim environment:
16123fb98d4aSespie     find_end_verbatim == 0:  process until end of file
16133fb98d4aSespie     find_end_verbatim != 0:  process until 'COMMAND_PREFIXend verbatim'
16143fb98d4aSespie                              or end of file
16153fb98d4aSespie 
16163fb98d4aSespie   We cannot simply copy input stream onto output stream; as the
16173fb98d4aSespie   verbatim environment may be encapsulated in an @example environment,
16183fb98d4aSespie   for example. */
16193fb98d4aSespie void
handle_verbatim_environment(int find_end_verbatim)1620*1076333cSespie handle_verbatim_environment (int find_end_verbatim)
16213fb98d4aSespie {
16223fb98d4aSespie   int character;
16233fb98d4aSespie   int seen_end = 0;
16243fb98d4aSespie   int save_filling_enabled = filling_enabled;
16253fb98d4aSespie   int save_inhibit_paragraph_indentation = inhibit_paragraph_indentation;
1626*1076333cSespie   int save_escape_html = escape_html;
16273fb98d4aSespie 
1628*1076333cSespie   if (!insertion_stack)
1629*1076333cSespie     close_single_paragraph (); /* no blank lines if not at outer level */
16303fb98d4aSespie   inhibit_paragraph_indentation = 1;
16313fb98d4aSespie   filling_enabled = 0;
16323fb98d4aSespie   in_fixed_width_font++;
16333fb98d4aSespie   last_char_was_newline = 0;
16343fb98d4aSespie 
16353fb98d4aSespie   /* No indentation: this is verbatim after all
16363fb98d4aSespie      If you want indent, enclose @verbatim in @example
16373fb98d4aSespie        current_indent += default_indentation_increment;
16383fb98d4aSespie    */
16393fb98d4aSespie 
16403fb98d4aSespie   if (html)
1641*1076333cSespie     { /* If inside @example, we'll be preceded by the indentation
1642*1076333cSespie          already.  Browsers will ignore those spaces because we're about
1643*1076333cSespie          to start another <pre> (don't ask me).  So, wipe them out for
1644*1076333cSespie          cleanliness, and re-insert.  */
1645*1076333cSespie       int i;
1646*1076333cSespie       kill_self_indent (default_indentation_increment);
1647*1076333cSespie       add_html_block_elt ("<pre class=\"verbatim\">");
1648*1076333cSespie       for (i = current_indent; i > 0; i--)
1649*1076333cSespie         add_char (' ');
1650*1076333cSespie     }
1651*1076333cSespie   else if (xml)
1652*1076333cSespie     {
1653*1076333cSespie       xml_insert_element (VERBATIM, START);
1654*1076333cSespie       escape_html = 0;
1655*1076333cSespie       add_word ("<![CDATA[");
1656*1076333cSespie     }
16573fb98d4aSespie 
16583fb98d4aSespie   while (input_text_offset < input_text_length)
16593fb98d4aSespie     {
16603fb98d4aSespie       character = curchar ();
16613fb98d4aSespie 
16623fb98d4aSespie       if (character == '\n')
16633fb98d4aSespie         line_number++;
1664*1076333cSespie 
1665*1076333cSespie       /* Assume no newlines in END_VERBATIM. */
16663fb98d4aSespie       else if (find_end_verbatim && (character == COMMAND_PREFIX) /* @ */
16673fb98d4aSespie           && (input_text_length - input_text_offset > sizeof (END_VERBATIM))
16683fb98d4aSespie           && !strncmp (&input_text[input_text_offset+1], END_VERBATIM,
16693fb98d4aSespie                        sizeof (END_VERBATIM)-1))
16703fb98d4aSespie         {
16713fb98d4aSespie           input_text_offset += sizeof (END_VERBATIM);
16723fb98d4aSespie           seen_end = 1;
16733fb98d4aSespie           break;
16743fb98d4aSespie         }
16753fb98d4aSespie 
1676*1076333cSespie       if (html && character == '&' && escape_html)
1677*1076333cSespie         add_word ("&amp;");
1678*1076333cSespie       else if (html && character == '<' && escape_html)
1679*1076333cSespie         add_word ("&lt;");
1680*1076333cSespie       else
16813fb98d4aSespie         add_char (character);
1682*1076333cSespie 
16833fb98d4aSespie       input_text_offset++;
16843fb98d4aSespie     }
16853fb98d4aSespie 
16863fb98d4aSespie   if (find_end_verbatim && !seen_end)
16873fb98d4aSespie     warning (_("end of file inside verbatim block"));
16883fb98d4aSespie 
16893fb98d4aSespie   if (html)
1690*1076333cSespie     { /* See comments in example case above.  */
1691*1076333cSespie       kill_self_indent (default_indentation_increment);
16923fb98d4aSespie       add_word ("</pre>");
1693*1076333cSespie     }
1694*1076333cSespie   else if (xml)
1695*1076333cSespie     {
1696*1076333cSespie       add_word ("]]>");
1697*1076333cSespie       xml_insert_element (VERBATIM, END);
1698*1076333cSespie       escape_html = save_escape_html;
1699*1076333cSespie     }
17003fb98d4aSespie 
17013fb98d4aSespie   in_fixed_width_font--;
17023fb98d4aSespie   filling_enabled = save_filling_enabled;
17033fb98d4aSespie   inhibit_paragraph_indentation = save_inhibit_paragraph_indentation;
17043fb98d4aSespie }
17053fb98d4aSespie 
17063fb98d4aSespie void
cm_verbatim(void)1707*1076333cSespie cm_verbatim (void)
17083fb98d4aSespie {
17093fb98d4aSespie   handle_verbatim_environment (1);
17103fb98d4aSespie }
17113fb98d4aSespie 
17121cc83814Sespie void
cm_table(void)1713*1076333cSespie cm_table (void)
17141cc83814Sespie {
17151cc83814Sespie   begin_insertion (table);
17161cc83814Sespie }
17171cc83814Sespie 
17181cc83814Sespie void
cm_multitable(void)1719*1076333cSespie cm_multitable (void)
17201cc83814Sespie {
17211cc83814Sespie   begin_insertion (multitable); /* @@ */
17221cc83814Sespie }
17231cc83814Sespie 
17241cc83814Sespie void
cm_ftable(void)1725*1076333cSespie cm_ftable (void)
17261cc83814Sespie {
17271cc83814Sespie   begin_insertion (ftable);
17281cc83814Sespie }
17291cc83814Sespie 
17301cc83814Sespie void
cm_vtable(void)1731*1076333cSespie cm_vtable (void)
17321cc83814Sespie {
17331cc83814Sespie   begin_insertion (vtable);
17341cc83814Sespie }
17351cc83814Sespie 
17361cc83814Sespie void
cm_group(void)1737*1076333cSespie cm_group (void)
17381cc83814Sespie {
17391cc83814Sespie   begin_insertion (group);
17401cc83814Sespie }
17411cc83814Sespie 
17421cc83814Sespie /* Insert raw HTML (no escaping of `<' etc.). */
17431cc83814Sespie void
cm_html(int arg)1744*1076333cSespie cm_html (int arg)
17451cc83814Sespie {
17461cc83814Sespie   if (process_html)
17471cc83814Sespie     begin_insertion (rawhtml);
17481cc83814Sespie   else
17491cc83814Sespie     command_name_condition ();
17501cc83814Sespie }
17511cc83814Sespie 
17521cc83814Sespie void
cm_xml(int arg)1753*1076333cSespie cm_xml (int arg)
1754*1076333cSespie {
1755*1076333cSespie   if (process_xml)
1756*1076333cSespie     begin_insertion (rawxml);
1757*1076333cSespie   else
1758*1076333cSespie     command_name_condition ();
1759*1076333cSespie }
1760*1076333cSespie 
1761*1076333cSespie void
cm_docbook(int arg)1762*1076333cSespie cm_docbook (int arg)
1763*1076333cSespie {
1764*1076333cSespie   if (process_docbook)
1765*1076333cSespie     begin_insertion (rawdocbook);
1766*1076333cSespie   else
1767*1076333cSespie     command_name_condition ();
1768*1076333cSespie }
1769*1076333cSespie 
1770*1076333cSespie void
cm_ifdocbook(void)1771*1076333cSespie cm_ifdocbook (void)
1772*1076333cSespie {
1773*1076333cSespie   if (process_docbook)
1774*1076333cSespie     begin_insertion (ifdocbook);
1775*1076333cSespie   else
1776*1076333cSespie     command_name_condition ();
1777*1076333cSespie }
1778*1076333cSespie 
1779*1076333cSespie void
cm_ifnotdocbook(void)1780*1076333cSespie cm_ifnotdocbook (void)
1781*1076333cSespie {
1782*1076333cSespie   if (!process_docbook)
1783*1076333cSespie     begin_insertion (ifnotdocbook);
1784*1076333cSespie   else
1785*1076333cSespie     command_name_condition ();
1786*1076333cSespie }
1787*1076333cSespie 
1788*1076333cSespie void
cm_ifhtml(void)1789*1076333cSespie cm_ifhtml (void)
17901cc83814Sespie {
17911cc83814Sespie   if (process_html)
17921cc83814Sespie     begin_insertion (ifhtml);
17931cc83814Sespie   else
17941cc83814Sespie     command_name_condition ();
17951cc83814Sespie }
17961cc83814Sespie 
17971cc83814Sespie void
cm_ifnothtml(void)1798*1076333cSespie cm_ifnothtml (void)
17991cc83814Sespie {
18001cc83814Sespie   if (!process_html)
18011cc83814Sespie     begin_insertion (ifnothtml);
18021cc83814Sespie   else
18031cc83814Sespie     command_name_condition ();
18041cc83814Sespie }
18051cc83814Sespie 
18061cc83814Sespie 
18071cc83814Sespie void
cm_ifinfo(void)1808*1076333cSespie cm_ifinfo (void)
18093fb98d4aSespie {
18103fb98d4aSespie   if (process_info)
18113fb98d4aSespie     begin_insertion (ifinfo);
18123fb98d4aSespie   else
18133fb98d4aSespie     command_name_condition ();
18143fb98d4aSespie }
18153fb98d4aSespie 
18163fb98d4aSespie void
cm_ifnotinfo(void)1817*1076333cSespie cm_ifnotinfo (void)
18183fb98d4aSespie {
18193fb98d4aSespie   if (!process_info)
18203fb98d4aSespie     begin_insertion (ifnotinfo);
18213fb98d4aSespie   else
18223fb98d4aSespie     command_name_condition ();
18233fb98d4aSespie }
18243fb98d4aSespie 
18253fb98d4aSespie 
18263fb98d4aSespie void
cm_ifplaintext(void)1827*1076333cSespie cm_ifplaintext (void)
18283fb98d4aSespie {
18293fb98d4aSespie   if (process_plaintext)
18303fb98d4aSespie     begin_insertion (ifplaintext);
18313fb98d4aSespie   else
18323fb98d4aSespie     command_name_condition ();
18333fb98d4aSespie }
18343fb98d4aSespie 
18353fb98d4aSespie void
cm_ifnotplaintext(void)1836*1076333cSespie cm_ifnotplaintext (void)
18373fb98d4aSespie {
18383fb98d4aSespie   if (!process_plaintext)
18393fb98d4aSespie     begin_insertion (ifnotplaintext);
18403fb98d4aSespie   else
18413fb98d4aSespie     command_name_condition ();
18423fb98d4aSespie }
18433fb98d4aSespie 
18443fb98d4aSespie 
18453fb98d4aSespie void
cm_tex(void)1846*1076333cSespie cm_tex (void)
18471cc83814Sespie {
18481cc83814Sespie   if (process_tex)
18491cc83814Sespie     begin_insertion (rawtex);
18501cc83814Sespie   else
18511cc83814Sespie     command_name_condition ();
18521cc83814Sespie }
18531cc83814Sespie 
18541cc83814Sespie void
cm_iftex(void)1855*1076333cSespie cm_iftex (void)
18561cc83814Sespie {
18571cc83814Sespie   if (process_tex)
18581cc83814Sespie     begin_insertion (iftex);
18591cc83814Sespie   else
18601cc83814Sespie     command_name_condition ();
18611cc83814Sespie }
18621cc83814Sespie 
18631cc83814Sespie void
cm_ifnottex(void)1864*1076333cSespie cm_ifnottex (void)
18651cc83814Sespie {
18661cc83814Sespie   if (!process_tex)
18671cc83814Sespie     begin_insertion (ifnottex);
18681cc83814Sespie   else
18691cc83814Sespie     command_name_condition ();
18701cc83814Sespie }
1871*1076333cSespie 
1872*1076333cSespie void
cm_ifxml(void)1873*1076333cSespie cm_ifxml (void)
1874*1076333cSespie {
1875*1076333cSespie   if (process_xml)
1876*1076333cSespie     begin_insertion (ifxml);
1877*1076333cSespie   else
1878*1076333cSespie     command_name_condition ();
1879*1076333cSespie }
1880*1076333cSespie 
1881*1076333cSespie void
cm_ifnotxml(void)1882*1076333cSespie cm_ifnotxml (void)
1883*1076333cSespie {
1884*1076333cSespie   if (!process_xml)
1885*1076333cSespie     begin_insertion (ifnotxml);
1886*1076333cSespie   else
1887*1076333cSespie     command_name_condition ();
1888*1076333cSespie }
1889*1076333cSespie 
18901cc83814Sespie 
1891*1076333cSespie /* Generic xrefable block with a caption.  */
1892*1076333cSespie void
cm_float(void)1893*1076333cSespie cm_float (void)
1894*1076333cSespie {
1895*1076333cSespie   begin_insertion (floatenv);
1896*1076333cSespie }
1897*1076333cSespie 
1898*1076333cSespie void
cm_caption(int arg)1899*1076333cSespie cm_caption (int arg)
1900*1076333cSespie {
1901*1076333cSespie   char *temp;
1902*1076333cSespie 
1903*1076333cSespie   /* This is a no_op command for most formats, as we handle it during @float
1904*1076333cSespie      insertion.  For XML though, we handle it here to keep document structure
1905*1076333cSespie      as close as possible, to the Texinfo source.  */
1906*1076333cSespie 
1907*1076333cSespie   /* Everything is already handled at START.  */
1908*1076333cSespie   if (arg == END)
1909*1076333cSespie     return;
1910*1076333cSespie 
1911*1076333cSespie   /* Check if it's mislocated.  */
1912*1076333cSespie   if (current_insertion_type () != floatenv)
1913*1076333cSespie     line_error (_("@%s not meaningful outside `@float' environment"), command);
1914*1076333cSespie 
1915*1076333cSespie   get_until_in_braces ("\n@end float", &temp);
1916*1076333cSespie 
1917*1076333cSespie   if (xml)
1918*1076333cSespie     {
1919*1076333cSespie       int elt = STREQ (command, "shortcaption") ? SHORTCAPTION : CAPTION;
1920*1076333cSespie       xml_insert_element (elt, START);
1921*1076333cSespie       if (!docbook)
1922*1076333cSespie         execute_string ("%s", temp);
1923*1076333cSespie       xml_insert_element (elt, END);
1924*1076333cSespie     }
1925*1076333cSespie 
1926*1076333cSespie   free (temp);
1927*1076333cSespie }
1928*1076333cSespie 
19291cc83814Sespie /* Begin an insertion where the lines are not filled or indented. */
19301cc83814Sespie void
cm_flushleft(void)1931*1076333cSespie cm_flushleft (void)
19321cc83814Sespie {
19331cc83814Sespie   begin_insertion (flushleft);
19341cc83814Sespie }
19351cc83814Sespie 
19361cc83814Sespie /* Begin an insertion where the lines are not filled, and each line is
19371cc83814Sespie    forced to the right-hand side of the page. */
19381cc83814Sespie void
cm_flushright(void)1939*1076333cSespie cm_flushright (void)
19401cc83814Sespie {
19411cc83814Sespie   begin_insertion (flushright);
19421cc83814Sespie }
19431cc83814Sespie 
19441cc83814Sespie void
cm_menu(void)1945*1076333cSespie cm_menu (void)
19461cc83814Sespie {
1947*1076333cSespie   if (current_node == NULL && !macro_expansion_output_stream)
19481cc83814Sespie     {
19491cc83814Sespie       warning (_("@menu seen before first @node, creating `Top' node"));
19501cc83814Sespie       warning (_("perhaps your @top node should be wrapped in @ifnottex rather than @ifinfo?"));
19511cc83814Sespie       /* Include @top command so we can construct the implicit node tree.  */
19521cc83814Sespie       execute_string ("@node top\n@top Top\n");
19531cc83814Sespie     }
19541cc83814Sespie   begin_insertion (menu);
19551cc83814Sespie }
19561cc83814Sespie 
19571cc83814Sespie void
cm_detailmenu(void)1958*1076333cSespie cm_detailmenu (void)
19591cc83814Sespie {
1960*1076333cSespie   if (current_node == NULL && !macro_expansion_output_stream)
19611cc83814Sespie     { /* Problems anyway, @detailmenu should always be inside @menu.  */
19621cc83814Sespie       warning (_("@detailmenu seen before first node, creating `Top' node"));
19631cc83814Sespie       execute_string ("@node top\n@top Top\n");
19641cc83814Sespie     }
19651cc83814Sespie   begin_insertion (detailmenu);
19661cc83814Sespie }
1967*1076333cSespie 
1968*1076333cSespie /* Title page commands. */
1969*1076333cSespie 
1970*1076333cSespie void
cm_titlepage(void)1971*1076333cSespie cm_titlepage (void)
1972*1076333cSespie {
1973*1076333cSespie   titlepage_cmd_present = 1;
1974*1076333cSespie   if (xml && !docbook)
1975*1076333cSespie     begin_insertion (titlepage);
1976*1076333cSespie   else
1977*1076333cSespie     command_name_condition ();
1978*1076333cSespie }
1979*1076333cSespie 
1980*1076333cSespie void
cm_author(void)1981*1076333cSespie cm_author (void)
1982*1076333cSespie {
1983*1076333cSespie   char *rest;
1984*1076333cSespie   get_rest_of_line (1, &rest);
1985*1076333cSespie 
1986*1076333cSespie   if (is_in_insertion_of_type (quotation))
1987*1076333cSespie     {
1988*1076333cSespie       if (html)
1989*1076333cSespie         add_word_args ("&mdash; %s", rest);
1990*1076333cSespie       else if (docbook)
1991*1076333cSespie         {
1992*1076333cSespie           /* FIXME Ideally, we should use an attribution element,
1993*1076333cSespie              but they are supposed to be at the start of quotation
1994*1076333cSespie              blocks.  So to avoid looking ahead mess, let's just
1995*1076333cSespie              use mdash like HTML for now.  */
1996*1076333cSespie           xml_insert_entity ("mdash");
1997*1076333cSespie           add_word (rest);
1998*1076333cSespie         }
1999*1076333cSespie       else if (xml)
2000*1076333cSespie         {
2001*1076333cSespie           xml_insert_element (AUTHOR, START);
2002*1076333cSespie           add_word (rest);
2003*1076333cSespie           xml_insert_element (AUTHOR, END);
2004*1076333cSespie         }
2005*1076333cSespie       else
2006*1076333cSespie         add_word_args ("-- %s", rest);
2007*1076333cSespie     }
2008*1076333cSespie   else if (is_in_insertion_of_type (titlepage))
2009*1076333cSespie     {
2010*1076333cSespie       if (xml && !docbook)
2011*1076333cSespie         {
2012*1076333cSespie           xml_insert_element (AUTHOR, START);
2013*1076333cSespie           add_word (rest);
2014*1076333cSespie           xml_insert_element (AUTHOR, END);
2015*1076333cSespie         }
2016*1076333cSespie     }
2017*1076333cSespie   else
2018*1076333cSespie     line_error (_("@%s not meaningful outside `@titlepage' and `@quotation' environments"),
2019*1076333cSespie         command);
2020*1076333cSespie 
2021*1076333cSespie   free (rest);
2022*1076333cSespie }
2023*1076333cSespie 
2024*1076333cSespie void
cm_titlepage_cmds(void)2025*1076333cSespie cm_titlepage_cmds (void)
2026*1076333cSespie {
2027*1076333cSespie   char *rest;
2028*1076333cSespie 
2029*1076333cSespie   get_rest_of_line (1, &rest);
2030*1076333cSespie 
2031*1076333cSespie   if (!is_in_insertion_of_type (titlepage))
2032*1076333cSespie     line_error (_("@%s not meaningful outside `@titlepage' environment"),
2033*1076333cSespie         command);
2034*1076333cSespie 
2035*1076333cSespie   if (xml && !docbook)
2036*1076333cSespie     {
2037*1076333cSespie       int elt = 0;
2038*1076333cSespie 
2039*1076333cSespie       if (STREQ (command, "title"))
2040*1076333cSespie         elt = BOOKTITLE;
2041*1076333cSespie       else if (STREQ (command, "subtitle"))
2042*1076333cSespie         elt = BOOKSUBTITLE;
2043*1076333cSespie 
2044*1076333cSespie       xml_insert_element (elt, START);
2045*1076333cSespie       add_word (rest);
2046*1076333cSespie       xml_insert_element (elt, END);
2047*1076333cSespie     }
2048*1076333cSespie 
2049*1076333cSespie     free (rest);
2050*1076333cSespie }
20511cc83814Sespie 
20521cc83814Sespie /* End existing insertion block. */
20531cc83814Sespie void
cm_end(void)2054*1076333cSespie cm_end (void)
20551cc83814Sespie {
20561cc83814Sespie   char *temp;
2057*1076333cSespie   int type;
2058*1076333cSespie 
2059*1076333cSespie   get_rest_of_line (0, &temp);
20601cc83814Sespie 
20611cc83814Sespie   if (!insertion_level)
20621cc83814Sespie     {
20631cc83814Sespie       line_error (_("Unmatched `%c%s'"), COMMAND_PREFIX, command);
20641cc83814Sespie       return;
20651cc83814Sespie     }
20661cc83814Sespie 
20671cc83814Sespie   if (temp[0] == 0)
20681cc83814Sespie     line_error (_("`%c%s' needs something after it"), COMMAND_PREFIX, command);
20691cc83814Sespie 
20701cc83814Sespie   type = find_type_from_name (temp);
20711cc83814Sespie 
20721cc83814Sespie   if (type == bad_type)
20731cc83814Sespie     {
2074*1076333cSespie       line_error (_("Bad argument `%s' to `@%s', using `%s'"),
2075*1076333cSespie            temp, command, insertion_type_pname (current_insertion_type ()));
20761cc83814Sespie     }
20773fb98d4aSespie   if (xml && type == menu) /* fixme */
20783fb98d4aSespie     {
20793fb98d4aSespie       xml_end_menu ();
20803fb98d4aSespie     }
20811cc83814Sespie   end_insertion (type);
20821cc83814Sespie   free (temp);
20831cc83814Sespie }
20841cc83814Sespie 
20851cc83814Sespie /* @itemx, @item. */
20861cc83814Sespie 
20871cc83814Sespie static int itemx_flag = 0;
20881cc83814Sespie 
20891cc83814Sespie /* Return whether CMD takes a brace-delimited {arg}.  */
2090*1076333cSespie int
command_needs_braces(char * cmd)2091*1076333cSespie command_needs_braces (char *cmd)
20921cc83814Sespie {
20931cc83814Sespie   int i;
20941cc83814Sespie   for (i = 0; command_table[i].name; i++)
20951cc83814Sespie     {
20961cc83814Sespie       if (STREQ (command_table[i].name, cmd))
20971cc83814Sespie         return command_table[i].argument_in_braces == BRACE_ARGS;
20981cc83814Sespie     }
20991cc83814Sespie 
21001cc83814Sespie   return 0; /* macro or alias */
21011cc83814Sespie }
21021cc83814Sespie 
21031cc83814Sespie 
21041cc83814Sespie void
cm_item(void)2105*1076333cSespie cm_item (void)
21061cc83814Sespie {
21071cc83814Sespie   char *rest_of_line, *item_func;
21081cc83814Sespie 
21091cc83814Sespie   /* Can only hack "@item" while inside of an insertion. */
21101cc83814Sespie   if (insertion_level)
21111cc83814Sespie     {
21121cc83814Sespie       INSERTION_ELT *stack = insertion_stack;
21131cc83814Sespie       int original_input_text_offset;
21141cc83814Sespie 
21151cc83814Sespie       skip_whitespace ();
21161cc83814Sespie       original_input_text_offset = input_text_offset;
21171cc83814Sespie 
21181cc83814Sespie       get_rest_of_line (0, &rest_of_line);
21191cc83814Sespie       item_func = current_item_function ();
21201cc83814Sespie 
21211cc83814Sespie     /* Do the right thing depending on which insertion function is active. */
21221cc83814Sespie     switch_top:
21231cc83814Sespie       switch (stack->insertion)
21241cc83814Sespie         {
21251cc83814Sespie         case multitable:
21261cc83814Sespie           multitable_item ();
21271cc83814Sespie           /* Support text directly after the @item.  */
21281cc83814Sespie           if (*rest_of_line)
21291cc83814Sespie             {
21301cc83814Sespie               line_number--;
21311cc83814Sespie               input_text_offset = original_input_text_offset;
21321cc83814Sespie             }
21331cc83814Sespie           break;
21341cc83814Sespie 
21351cc83814Sespie         case ifclear:
21361cc83814Sespie         case ifhtml:
21371cc83814Sespie         case ifinfo:
21381cc83814Sespie         case ifnothtml:
21391cc83814Sespie         case ifnotinfo:
21403fb98d4aSespie         case ifnotplaintext:
21411cc83814Sespie         case ifnottex:
2142*1076333cSespie 	case ifnotxml:
21433fb98d4aSespie         case ifplaintext:
21441cc83814Sespie         case ifset:
21451cc83814Sespie         case iftex:
2146*1076333cSespie 	case ifxml:
2147*1076333cSespie         case rawdocbook:
21481cc83814Sespie         case rawhtml:
2149*1076333cSespie         case rawxml:
21501cc83814Sespie         case rawtex:
21511cc83814Sespie         case tex:
21521cc83814Sespie         case cartouche:
21531cc83814Sespie           stack = stack->next;
21541cc83814Sespie           if (!stack)
21551cc83814Sespie             goto no_insertion;
21561cc83814Sespie           else
21571cc83814Sespie             goto switch_top;
21581cc83814Sespie           break;
21591cc83814Sespie 
21601cc83814Sespie         case menu:
21611cc83814Sespie         case quotation:
21621cc83814Sespie         case example:
21631cc83814Sespie         case smallexample:
21641cc83814Sespie         case lisp:
21651cc83814Sespie         case smalllisp:
21661cc83814Sespie         case format:
21671cc83814Sespie         case smallformat:
21681cc83814Sespie         case display:
21691cc83814Sespie         case smalldisplay:
21701cc83814Sespie         case group:
21711cc83814Sespie           line_error (_("@%s not meaningful inside `@%s' block"),
21721cc83814Sespie                       command,
21731cc83814Sespie                       insertion_type_pname (current_insertion_type ()));
21741cc83814Sespie           break;
21751cc83814Sespie 
21761cc83814Sespie         case itemize:
21771cc83814Sespie         case enumerate:
21781cc83814Sespie           if (itemx_flag)
21791cc83814Sespie             {
21801cc83814Sespie               line_error (_("@itemx not meaningful inside `%s' block"),
21811cc83814Sespie                           insertion_type_pname (current_insertion_type ()));
21821cc83814Sespie             }
21831cc83814Sespie           else
21841cc83814Sespie             {
21851cc83814Sespie               if (html)
2186*1076333cSespie                 add_html_block_elt ("<li>");
21873fb98d4aSespie               else if (xml)
21883fb98d4aSespie                 xml_begin_item ();
21891cc83814Sespie               else
21901cc83814Sespie                 {
21911cc83814Sespie                   start_paragraph ();
21921cc83814Sespie                   kill_self_indent (-1);
21931cc83814Sespie                   filling_enabled = indented_fill = 1;
21941cc83814Sespie 
21951cc83814Sespie                   if (current_item_function ())
21961cc83814Sespie                     {
21971cc83814Sespie                       output_column = current_indent - 2;
21981cc83814Sespie                       indent (output_column);
21991cc83814Sespie 
22001cc83814Sespie                       /* The item marker can be given with or without
22011cc83814Sespie                          braces -- @bullet and @bullet{} are both ok.
22021cc83814Sespie                          Or it might be something that doesn't take
22031cc83814Sespie                          braces at all, such as "o" or "#" or "@ ".
22041cc83814Sespie                          Thus, only supply braces if the item marker is
22051cc83814Sespie                          a command, they haven't supplied braces
22061cc83814Sespie                          themselves, and we know it needs them.  */
22071cc83814Sespie                       if (item_func && *item_func)
22081cc83814Sespie                         {
22091cc83814Sespie                           if (*item_func == COMMAND_PREFIX
22101cc83814Sespie                               && item_func[strlen (item_func) - 1] != '}'
22111cc83814Sespie                               && command_needs_braces (item_func + 1))
22121cc83814Sespie                             execute_string ("%s{}", item_func);
22131cc83814Sespie                           else
22141cc83814Sespie                             execute_string ("%s", item_func);
22151cc83814Sespie                         }
22161cc83814Sespie                       insert (' ');
22171cc83814Sespie                       output_column++;
22181cc83814Sespie                     }
22191cc83814Sespie                   else
22201cc83814Sespie                     enumerate_item ();
22211cc83814Sespie 
22221cc83814Sespie                   /* Special hack.  This makes `close_paragraph' a no-op until
22231cc83814Sespie                      `start_paragraph' has been called. */
22241cc83814Sespie                   must_start_paragraph = 1;
22251cc83814Sespie                 }
22261cc83814Sespie 
22271cc83814Sespie               /* Handle text directly after the @item.  */
22281cc83814Sespie               if (*rest_of_line)
22291cc83814Sespie                 {
22301cc83814Sespie                   line_number--;
22311cc83814Sespie                   input_text_offset = original_input_text_offset;
22321cc83814Sespie                 }
22331cc83814Sespie             }
22341cc83814Sespie           break;
22351cc83814Sespie 
22361cc83814Sespie         case table:
22371cc83814Sespie         case ftable:
22381cc83814Sespie         case vtable:
22391cc83814Sespie           if (html)
2240*1076333cSespie             { /* If nothing has been output since the last <dd>,
22411cc83814Sespie                  remove the empty <dd> element.  Some browsers render
22421cc83814Sespie                  an extra empty line for <dd><dt>, which makes @itemx
22431cc83814Sespie                  conversion look ugly.  */
2244*1076333cSespie               rollback_empty_tag ("dd");
22451cc83814Sespie 
22461cc83814Sespie               /* Force the browser to render one blank line before
2247*1076333cSespie                  each new @item in a table.  But don't do that if
22481cc83814Sespie                  this is the first <dt> after the <dl>, or if we are
22491cc83814Sespie                  converting @itemx.
22501cc83814Sespie 
22511cc83814Sespie                  Note that there are some browsers which ignore <br>
22521cc83814Sespie                  in this context, but I cannot find any way to force
22531cc83814Sespie                  them all render exactly one blank line.  */
2254*1076333cSespie               if (!itemx_flag && html_deflist_has_term)
2255*1076333cSespie                 add_html_block_elt ("<br>");
22561cc83814Sespie 
2257*1076333cSespie               /* We are about to insert a <dt>, so this <dl> has a term.
2258*1076333cSespie                  Feel free to insert a <br> next time. :)  */
2259*1076333cSespie               html_deflist_has_term = 1;
2260*1076333cSespie 
2261*1076333cSespie               add_html_block_elt ("<dt>");
22621cc83814Sespie               if (item_func && *item_func)
22631cc83814Sespie                 execute_string ("%s{%s}", item_func, rest_of_line);
22641cc83814Sespie               else
22651cc83814Sespie                 execute_string ("%s", rest_of_line);
22661cc83814Sespie 
22671cc83814Sespie               if (current_insertion_type () == ftable)
22681cc83814Sespie                 execute_string ("%cfindex %s\n", COMMAND_PREFIX, rest_of_line);
22691cc83814Sespie 
22701cc83814Sespie               if (current_insertion_type () == vtable)
22711cc83814Sespie                 execute_string ("%cvindex %s\n", COMMAND_PREFIX, rest_of_line);
2272*1076333cSespie 
2273*1076333cSespie               add_html_block_elt ("<dd>");
22741cc83814Sespie             }
22753fb98d4aSespie           else if (xml) /* && docbook)*/ /* 05-08 */
22763fb98d4aSespie             {
22773fb98d4aSespie               xml_begin_table_item ();
2278*1076333cSespie 
2279*1076333cSespie               if (!docbook && current_insertion_type () == ftable)
2280*1076333cSespie                 execute_string ("%cfindex %s\n", COMMAND_PREFIX, rest_of_line);
2281*1076333cSespie 
2282*1076333cSespie               if (!docbook && current_insertion_type () == vtable)
2283*1076333cSespie                 execute_string ("%cvindex %s\n", COMMAND_PREFIX, rest_of_line);
2284*1076333cSespie 
22853fb98d4aSespie               if (item_func && *item_func)
22863fb98d4aSespie                 execute_string ("%s{%s}", item_func, rest_of_line);
22873fb98d4aSespie               else
22883fb98d4aSespie                 execute_string ("%s", rest_of_line);
22893fb98d4aSespie               xml_continue_table_item ();
22903fb98d4aSespie             }
22911cc83814Sespie           else
22921cc83814Sespie             {
22931cc83814Sespie               /* We need this to determine if we have two @item's in a row
22941cc83814Sespie                  (see test just below).  */
22951cc83814Sespie               static int last_item_output_position = 0;
22961cc83814Sespie 
22971cc83814Sespie               /* Get rid of extra characters. */
22981cc83814Sespie               kill_self_indent (-1);
22991cc83814Sespie 
23001cc83814Sespie               /* If we have one @item followed directly by another @item,
23011cc83814Sespie                  we need to insert a blank line.  This is not true for
23021cc83814Sespie                  @itemx, though.  */
23031cc83814Sespie               if (!itemx_flag && last_item_output_position == output_position)
23041cc83814Sespie                 insert ('\n');
23051cc83814Sespie 
23061cc83814Sespie               /* `close_paragraph' almost does what we want.  The problem
23071cc83814Sespie                  is when paragraph_is_open, and last_char_was_newline, and
23081cc83814Sespie                  the last newline has been turned into a space, because
23091cc83814Sespie                  filling_enabled. I handle it here. */
23101cc83814Sespie               if (last_char_was_newline && filling_enabled &&
23111cc83814Sespie                   paragraph_is_open)
23121cc83814Sespie                 insert ('\n');
23131cc83814Sespie               close_paragraph ();
23141cc83814Sespie 
23151cc83814Sespie #if defined (INDENT_PARAGRAPHS_IN_TABLE)
23161cc83814Sespie               /* Indent on a new line, but back up one indentation level. */
23171cc83814Sespie               {
23181cc83814Sespie                 int save = inhibit_paragraph_indentation;
23191cc83814Sespie                 inhibit_paragraph_indentation = 1;
23201cc83814Sespie                 /* At this point, inserting any non-whitespace character will
23211cc83814Sespie                    force the existing indentation to be output. */
23221cc83814Sespie                 add_char ('i');
23231cc83814Sespie                 inhibit_paragraph_indentation = save;
23241cc83814Sespie               }
23251cc83814Sespie #else /* !INDENT_PARAGRAPHS_IN_TABLE */
23261cc83814Sespie               add_char ('i');
23271cc83814Sespie #endif /* !INDENT_PARAGRAPHS_IN_TABLE */
23281cc83814Sespie 
23291cc83814Sespie               output_paragraph_offset--;
23301cc83814Sespie               kill_self_indent (default_indentation_increment + 1);
23311cc83814Sespie 
23321cc83814Sespie               /* Add item's argument to the line. */
23331cc83814Sespie               filling_enabled = 0;
23341cc83814Sespie               if (item_func && *item_func)
23351cc83814Sespie                 execute_string ("%s{%s}", item_func, rest_of_line);
23361cc83814Sespie               else
23371cc83814Sespie                 execute_string ("%s", rest_of_line);
23381cc83814Sespie 
23391cc83814Sespie               if (current_insertion_type () == ftable)
23401cc83814Sespie                 execute_string ("%cfindex %s\n", COMMAND_PREFIX, rest_of_line);
23411cc83814Sespie               else if (current_insertion_type () == vtable)
23421cc83814Sespie                 execute_string ("%cvindex %s\n", COMMAND_PREFIX, rest_of_line);
23431cc83814Sespie 
23441cc83814Sespie               /* Start a new line, and let start_paragraph ()
23451cc83814Sespie                  do the indenting of it for you. */
23461cc83814Sespie               close_single_paragraph ();
23471cc83814Sespie               indented_fill = filling_enabled = 1;
23481cc83814Sespie               last_item_output_position = output_position;
23491cc83814Sespie             }
23501cc83814Sespie         }
23511cc83814Sespie       free (rest_of_line);
23521cc83814Sespie     }
23531cc83814Sespie   else
23541cc83814Sespie     {
23551cc83814Sespie     no_insertion:
23561cc83814Sespie       line_error (_("%c%s found outside of an insertion block"),
23571cc83814Sespie                   COMMAND_PREFIX, command);
23581cc83814Sespie     }
23591cc83814Sespie }
23601cc83814Sespie 
23611cc83814Sespie void
cm_itemx(void)2362*1076333cSespie cm_itemx (void)
23631cc83814Sespie {
23641cc83814Sespie   itemx_flag++;
23651cc83814Sespie   cm_item ();
23661cc83814Sespie   itemx_flag--;
23671cc83814Sespie }
2368*1076333cSespie 
2369*1076333cSespie int headitem_flag = 0;
2370*1076333cSespie 
2371*1076333cSespie void
cm_headitem(void)2372*1076333cSespie cm_headitem (void)
2373*1076333cSespie {
2374*1076333cSespie   headitem_flag = 1;
2375*1076333cSespie   cm_item ();
2376*1076333cSespie }
2377