No empty .Rs/.Re
[netbsd-mini2440.git] / gnu / dist / texinfo / makeinfo / insertion.c
blobe5e8772431f8cb6aff35d0b333af56b86b7acf5f
1 /* $NetBSD$ */
3 /* insertion.c -- insertions for Texinfo.
4 Id: insertion.c,v 1.55 2004/11/11 18:34:28 karl Exp
6 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
7 Foundation, Inc.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software Foundation,
21 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 #include "system.h"
24 #include "cmds.h"
25 #include "defun.h"
26 #include "float.h"
27 #include "html.h"
28 #include "insertion.h"
29 #include "macro.h"
30 #include "makeinfo.h"
31 #include "multi.h"
32 #include "xml.h"
34 /* Must match list in insertion.h. */
35 static char *insertion_type_names[] =
37 "cartouche", "copying", "defcv", "deffn", "defivar", "defmac",
38 "defmethod", "defop", "defopt", "defspec", "deftp", "deftypecv",
39 "deftypefn", "deftypefun", "deftypeivar", "deftypemethod",
40 "deftypeop", "deftypevar", "deftypevr", "defun", "defvar", "defvr",
41 "detailmenu", "direntry", "display", "documentdescription",
42 "enumerate", "example", "float", "flushleft", "flushright", "format",
43 "ftable", "group", "ifclear", "ifdocbook", "ifhtml", "ifinfo",
44 "ifnotdocbook", "ifnothtml", "ifnotinfo", "ifnotplaintext", "ifnottex",
45 "ifnotxml", "ifplaintext", "ifset", "iftex", "ifxml", "itemize", "lisp",
46 "menu", "multitable", "quotation", "rawdocbook", "rawhtml", "rawtex",
47 "rawxml", "smalldisplay", "smallexample", "smallformat", "smalllisp",
48 "verbatim", "table", "tex", "vtable", "titlepage", "bad_type"
51 /* All nested environments. */
52 INSERTION_ELT *insertion_stack = NULL;
54 /* How deeply we're nested. */
55 int insertion_level = 0;
57 /* Set to 1 if we've processed (commentary) text in a @menu that
58 wasn't part of a menu item. */
59 int had_menu_commentary;
61 /* How to examine menu lines. */
62 int in_detailmenu = 0;
64 /* Whether to examine menu lines. */
65 int in_menu = 0;
67 /* Set to 1 if <p> is written in normal context.
68 Used for menu and itemize. */
69 int in_paragraph = 0;
71 /* Since an insertion is already in the stack before we reach the switch
72 statement, we cannot use is_in_insertion_of_type (always returns true.) Also
73 making it return the level found, and comparing it with the current level is
74 no use, due to the order of stack. */
75 static int float_active = 0;
77 /* Unsetting escape_html blindly causes text inside @html/etc. to be escaped if
78 used within a rmacro. */
79 static int raw_output_block = 0;
81 /* Non-zero if a <dl> element has a <dt> element in it. We use this when
82 deciding whether to insert a <br> or not. */
83 static int html_deflist_has_term = 0;
85 void
86 init_insertion_stack (void)
88 insertion_stack = NULL;
91 /* Return the type of the current insertion. */
92 static enum insertion_type
93 current_insertion_type (void)
95 return insertion_level ? insertion_stack->insertion : bad_type;
98 /* Return the string which is the function to wrap around items, or NULL
99 if we're not in an environment where @item is ok. */
100 static char *
101 current_item_function (void)
103 int done = 0;
104 INSERTION_ELT *elt = insertion_stack;
106 /* Skip down through the stack until we find an insertion with an
107 itemize function defined, i.e., skip conditionals, @cartouche, etc. */
108 while (!done && elt)
110 switch (elt->insertion)
112 /* This list should match the one in cm_item. */
113 case ifclear:
114 case ifhtml:
115 case ifinfo:
116 case ifnothtml:
117 case ifnotinfo:
118 case ifnotplaintext:
119 case ifnottex:
120 case ifnotxml:
121 case ifplaintext:
122 case ifset:
123 case iftex:
124 case ifxml:
125 case rawdocbook:
126 case rawhtml:
127 case rawxml:
128 case rawtex:
129 case tex:
130 case cartouche:
131 elt = elt->next;
132 break;
134 default:
135 done = 1;
139 /* item_function usually gets assigned the empty string. */
140 return done && (*elt->item_function) ? elt->item_function : NULL;
143 /* Parse the item marker function off the input. If result is just "@",
144 change it to "@ ", since "@" by itself is not a command. This makes
145 "@ ", "@\t", and "@\n" all the same, but their default meanings are
146 the same anyway, and let's not worry about supporting redefining them. */
147 static char *
148 get_item_function (void)
150 char *item_function;
151 char *item_loc;
153 get_rest_of_line (0, &item_function);
155 /* If the document erroneously says
156 @itemize @bullet @item foobar
157 it's nicer to give an error up front than repeat `@bullet expected
158 braces' until we get a segmentation fault. */
159 item_loc = strstr (item_function, "@item");
160 if (item_loc)
162 line_error (_("@item not allowed in argument to @itemize"));
163 *item_loc = 0;
166 /* If we hit the end of text in get_rest_of_line, backing up
167 input pointer will cause the last character of the last line
168 be pushed back onto the input, which is wrong. */
169 if (input_text_offset < input_text_length)
170 backup_input_pointer ();
172 if (STREQ (item_function, "@"))
174 free (item_function);
175 item_function = xstrdup ("@ ");
178 return item_function;
181 /* Push the state of the current insertion on the stack. */
182 static void
183 push_insertion (enum insertion_type type, char *item_function)
185 INSERTION_ELT *new = xmalloc (sizeof (INSERTION_ELT));
187 new->item_function = item_function;
188 new->filling_enabled = filling_enabled;
189 new->indented_fill = indented_fill;
190 new->insertion = type;
191 new->line_number = line_number;
192 new->filename = xstrdup (input_filename);
193 new->inhibited = inhibit_paragraph_indentation;
194 new->in_fixed_width_font = in_fixed_width_font;
195 new->next = insertion_stack;
196 insertion_stack = new;
197 insertion_level++;
200 /* Pop the value on top of the insertion stack into the
201 global variables. */
202 void
203 pop_insertion (void)
205 INSERTION_ELT *temp = insertion_stack;
207 if (temp == NULL)
208 return;
210 in_fixed_width_font = temp->in_fixed_width_font;
211 inhibit_paragraph_indentation = temp->inhibited;
212 filling_enabled = temp->filling_enabled;
213 indented_fill = temp->indented_fill;
214 free_and_clear (&(temp->item_function));
215 free_and_clear (&(temp->filename));
216 insertion_stack = insertion_stack->next;
217 free (temp);
218 insertion_level--;
221 /* Return a pointer to the print name of this
222 enumerated type. */
223 static const char *
224 insertion_type_pname (enum insertion_type type)
226 if ((int) type < (int) bad_type)
228 if (type == rawdocbook)
229 return "docbook";
230 else if (type == rawhtml)
231 return "html";
232 else if (type == rawxml)
233 return "xml";
234 else if (type == rawtex)
235 return "tex";
236 else
237 return insertion_type_names[(int) type];
239 else
240 return _("Broken-Type in insertion_type_pname");
243 /* Return the insertion_type associated with NAME.
244 If the type is not one of the known ones, return BAD_TYPE. */
245 enum insertion_type
246 find_type_from_name (char *name)
248 int index = 0;
249 while (index < (int) bad_type)
251 if (STREQ (name, insertion_type_names[index]))
252 return (enum insertion_type) index;
253 if (index == rawdocbook && STREQ (name, "docbook"))
254 return rawdocbook;
255 if (index == rawhtml && STREQ (name, "html"))
256 return rawhtml;
257 if (index == rawxml && STREQ (name, "xml"))
258 return rawxml;
259 if (index == rawtex && STREQ (name, "tex"))
260 return rawtex;
261 index++;
263 return bad_type;
266 /* Simple function to query insertion_stack to see if we are inside a given
267 insertion type. */
269 is_in_insertion_of_type (int type)
271 INSERTION_ELT *temp = insertion_stack;
273 if (!insertion_level)
274 return 0;
276 while (temp)
278 if (temp->insertion == type)
279 return 1;
280 temp = temp->next;
283 return 0;
287 static int
288 defun_insertion (enum insertion_type type)
290 return 0
291 || (type == defcv)
292 || (type == deffn)
293 || (type == defivar)
294 || (type == defmac)
295 || (type == defmethod)
296 || (type == defop)
297 || (type == defopt)
298 || (type == defspec)
299 || (type == deftp)
300 || (type == deftypecv)
301 || (type == deftypefn)
302 || (type == deftypefun)
303 || (type == deftypeivar)
304 || (type == deftypemethod)
305 || (type == deftypeop)
306 || (type == deftypevar)
307 || (type == deftypevr)
308 || (type == defun)
309 || (type == defvar)
310 || (type == defvr)
314 /* MAX_NS is the maximum nesting level for enumerations. I picked 100
315 which seemed reasonable. This doesn't control the number of items,
316 just the number of nested lists. */
317 #define max_stack_depth 100
318 #define ENUM_DIGITS 1
319 #define ENUM_ALPHA 2
320 typedef struct {
321 int enumtype;
322 int enumval;
323 } DIGIT_ALPHA;
325 DIGIT_ALPHA enumstack[max_stack_depth];
326 int enumstack_offset = 0;
327 int current_enumval = 1;
328 int current_enumtype = ENUM_DIGITS;
329 char *enumeration_arg = NULL;
331 static void
332 start_enumerating (int at, int type)
334 if ((enumstack_offset + 1) == max_stack_depth)
336 line_error (_("Enumeration stack overflow"));
337 return;
339 enumstack[enumstack_offset].enumtype = current_enumtype;
340 enumstack[enumstack_offset].enumval = current_enumval;
341 enumstack_offset++;
342 current_enumval = at;
343 current_enumtype = type;
346 static void
347 stop_enumerating (void)
349 --enumstack_offset;
350 if (enumstack_offset < 0)
351 enumstack_offset = 0;
353 current_enumval = enumstack[enumstack_offset].enumval;
354 current_enumtype = enumstack[enumstack_offset].enumtype;
357 /* Place a letter or digits into the output stream. */
358 static void
359 enumerate_item (void)
361 char temp[10];
363 if (current_enumtype == ENUM_ALPHA)
365 if (current_enumval == ('z' + 1) || current_enumval == ('Z' + 1))
367 current_enumval = ((current_enumval - 1) == 'z' ? 'a' : 'A');
368 warning (_("lettering overflow, restarting at %c"), current_enumval);
370 sprintf (temp, "%c. ", current_enumval);
372 else
373 sprintf (temp, "%d. ", current_enumval);
375 indent (output_column += (current_indent - strlen (temp)));
376 add_word (temp);
377 current_enumval++;
380 static void
381 enum_html (void)
383 char type;
384 int start;
386 if (isdigit (*enumeration_arg))
388 type = '1';
389 start = atoi (enumeration_arg);
391 else if (isupper (*enumeration_arg))
393 type = 'A';
394 start = *enumeration_arg - 'A' + 1;
396 else
398 type = 'a';
399 start = *enumeration_arg - 'a' + 1;
402 add_html_block_elt_args ("<ol type=%c start=%d>\n", type, start);
405 /* Conditionally parse based on the current command name. */
406 void
407 command_name_condition (void)
409 char *discarder = xmalloc (8 + strlen (command));
411 sprintf (discarder, "\n%cend %s", COMMAND_PREFIX, command);
412 discard_until (discarder);
413 discard_until ("\n");
415 free (discarder);
418 /* This is where the work for all the "insertion" style
419 commands is done. A huge switch statement handles the
420 various setups, and generic code is on both sides. */
421 void
422 begin_insertion (enum insertion_type type)
424 int no_discard = 0;
426 if (defun_insertion (type))
428 push_insertion (type, xstrdup (""));
429 no_discard++;
431 else
433 push_insertion (type, get_item_function ());
436 switch (type)
438 case menu:
439 if (!no_headers)
440 close_paragraph ();
442 filling_enabled = no_indent = 0;
443 inhibit_paragraph_indentation = 1;
445 if (html)
447 had_menu_commentary = 1;
449 else if (!no_headers && !xml)
450 add_word ("* Menu:\n");
452 if (xml)
453 xml_insert_element (MENU, START);
454 else
455 in_fixed_width_font++;
457 next_menu_item_number = 1;
458 in_menu++;
459 no_discard++;
460 break;
462 case detailmenu:
463 if (!in_menu)
465 if (!no_headers)
466 close_paragraph ();
468 filling_enabled = no_indent = 0;
469 inhibit_paragraph_indentation = 1;
471 no_discard++;
474 if (xml)
476 xml_insert_element (DETAILMENU, START);
477 skip_whitespace_and_newlines();
479 else
480 in_fixed_width_font++;
482 in_detailmenu++;
483 break;
485 case direntry:
486 close_single_paragraph ();
487 filling_enabled = no_indent = 0;
488 inhibit_paragraph_indentation = 1;
489 insert_string ("START-INFO-DIR-ENTRY\n");
490 break;
492 case documentdescription:
494 char *desc;
495 int start_of_end;
496 int save_fixed_width;
498 discard_until ("\n"); /* ignore the @documentdescription line */
499 start_of_end = get_until ("\n@end documentdescription", &desc);
500 save_fixed_width = in_fixed_width_font;
502 in_fixed_width_font = 0;
503 document_description = expansion (desc, 0);
504 free (desc);
506 in_fixed_width_font = save_fixed_width;
507 input_text_offset = start_of_end; /* go back to the @end to match */
509 break;
511 case copying:
512 /* Save the copying text away for @insertcopying,
513 typically used on the back of the @titlepage (for TeX) and
514 the Top node (for info/html). */
515 if (input_text[input_text_offset] != '\n')
516 discard_until ("\n"); /* ignore remainder of @copying line */
518 input_text_offset = get_until ("\n@end copying", &copying_text);
519 canon_white (copying_text);
521 /* For info, output the copying text right away, so it will end up
522 in the header of the Info file, before the first node, and thus
523 get copied automatically to all the split files. For xml, also
524 output it right away since xml output is never split.
525 For html, we output it specifically in html_output_head.
526 For plain text, there's no way to hide it, so the author must
527 use @insertcopying in the desired location. */
528 if (docbook)
530 if (!xml_in_bookinfo)
532 xml_insert_element (BOOKINFO, START);
533 xml_in_bookinfo = 1;
535 xml_insert_element (LEGALNOTICE, START);
538 if (!html && !no_headers)
539 cm_insert_copying ();
541 if (docbook)
542 xml_insert_element (LEGALNOTICE, END);
544 break;
546 case quotation:
547 /* @quotation does filling (@display doesn't). */
548 if (html)
549 add_html_block_elt ("<blockquote>\n");
550 else
552 /* with close_single_paragraph, we get no blank line above
553 within @copying. */
554 close_paragraph ();
555 last_char_was_newline = no_indent = 0;
556 indented_fill = filling_enabled = 1;
557 inhibit_paragraph_indentation = 1;
559 current_indent += default_indentation_increment;
560 if (xml)
561 xml_insert_quotation (insertion_stack->item_function, START);
562 else if (strlen(insertion_stack->item_function))
563 execute_string ("@b{%s:} ", insertion_stack->item_function);
564 break;
566 case example:
567 case smallexample:
568 case lisp:
569 case smalllisp:
570 in_fixed_width_font++;
571 /* fall through */
573 /* Like @example but no fixed width font. */
574 case display:
575 case smalldisplay:
576 /* Like @display but without indentation. */
577 case smallformat:
578 case format:
579 close_single_paragraph ();
580 inhibit_paragraph_indentation = 1;
581 filling_enabled = 0;
582 last_char_was_newline = 0;
584 if (html)
585 /* Kludge alert: if <pre> is followed by a newline, IE3,
586 mozilla, maybe others render an extra blank line before the
587 pre-formatted block. So don't output a newline. */
588 add_html_block_elt_args ("<pre class=\"%s\">", command);
590 if (type != format && type != smallformat)
592 current_indent += example_indentation_increment;
593 if (html)
595 /* Since we didn't put \n after <pre>, we need to insert
596 the indentation by hand. */
597 int i;
598 for (i = current_indent; i > 0; i--)
599 add_char (' ');
602 break;
604 case multitable:
605 do_multitable ();
606 break;
608 case table:
609 case ftable:
610 case vtable:
611 case itemize:
612 close_single_paragraph ();
613 current_indent += default_indentation_increment;
614 filling_enabled = indented_fill = 1;
615 #if defined (INDENT_PARAGRAPHS_IN_TABLE)
616 inhibit_paragraph_indentation = 0;
617 #else
618 inhibit_paragraph_indentation = 1;
619 #endif /* !INDENT_PARAGRAPHS_IN_TABLE */
621 /* Make things work for losers who forget the itemize syntax. */
622 if (type == itemize)
624 if (!(*insertion_stack->item_function))
626 free (insertion_stack->item_function);
627 insertion_stack->item_function = xstrdup ("@bullet");
631 if (!*insertion_stack->item_function)
633 line_error (_("%s requires an argument: the formatter for %citem"),
634 insertion_type_pname (type), COMMAND_PREFIX);
637 if (html)
639 if (type == itemize)
641 add_html_block_elt ("<ul>\n");
642 in_paragraph = 0;
644 else
645 { /* We are just starting, so this <dl>
646 has no <dt> children yet. */
647 html_deflist_has_term = 0;
648 add_html_block_elt ("<dl>\n");
651 if (xml)
652 xml_begin_table (type, insertion_stack->item_function);
654 while (input_text[input_text_offset] == '\n'
655 && input_text[input_text_offset+1] == '\n')
657 line_number++;
658 input_text_offset++;
661 break;
663 case enumerate:
664 close_single_paragraph ();
665 no_indent = 0;
666 #if defined (INDENT_PARAGRAPHS_IN_TABLE)
667 inhibit_paragraph_indentation = 0;
668 #else
669 inhibit_paragraph_indentation = 1;
670 #endif /* !INDENT_PARAGRAPHS_IN_TABLE */
672 current_indent += default_indentation_increment;
673 filling_enabled = indented_fill = 1;
675 if (html)
677 enum_html ();
678 in_paragraph = 0;
681 if (xml)
682 xml_begin_enumerate (enumeration_arg);
684 if (isdigit (*enumeration_arg))
685 start_enumerating (atoi (enumeration_arg), ENUM_DIGITS);
686 else
687 start_enumerating (*enumeration_arg, ENUM_ALPHA);
688 break;
690 /* @group produces no output in info. */
691 case group:
692 /* Only close the paragraph if we are not inside of an
693 @example-like environment. */
694 if (xml)
695 xml_insert_element (GROUP, START);
696 else if (!insertion_stack->next
697 || (insertion_stack->next->insertion != display
698 && insertion_stack->next->insertion != smalldisplay
699 && insertion_stack->next->insertion != example
700 && insertion_stack->next->insertion != smallexample
701 && insertion_stack->next->insertion != lisp
702 && insertion_stack->next->insertion != smalllisp
703 && insertion_stack->next->insertion != format
704 && insertion_stack->next->insertion != smallformat
705 && insertion_stack->next->insertion != flushleft
706 && insertion_stack->next->insertion != flushright))
707 close_single_paragraph ();
708 break;
710 case cartouche:
711 if (html)
712 add_html_block_elt ("<p><table class=\"cartouche\" summary=\"cartouche\" border=\"1\"><tr><td>\n");
713 if (in_menu)
714 no_discard++;
715 break;
717 case floatenv:
718 /* Cannot nest floats, so complain. */
719 if (float_active)
721 line_error (_("%cfloat environments cannot be nested"), COMMAND_PREFIX);
722 pop_insertion ();
723 break;
726 float_active++;
728 { /* Collect data about this float. */
729 /* Example: @float [FLOATTYPE][,XREFLABEL][,POSITION] */
730 char floattype[200] = "";
731 char xreflabel[200] = "";
732 char position[200] = "";
733 char *text;
734 char *caption;
735 char *shortcaption;
736 int start_of_end;
737 int save_line_number = line_number;
738 int save_input_text_offset = input_text_offset;
739 int i;
741 if (strlen (insertion_stack->item_function) > 0)
743 int i = 0, t = 0, c = 0;
744 while (insertion_stack->item_function[i])
746 if (insertion_stack->item_function[i] == ',')
748 switch (t)
750 case 0:
751 floattype[c] = '\0';
752 break;
753 case 1:
754 xreflabel[c] = '\0';
755 break;
756 case 2:
757 position[c] = '\0';
758 break;
760 c = 0;
761 t++;
762 i++;
763 continue;
766 switch (t)
768 case 0:
769 floattype[c] = insertion_stack->item_function[i];
770 break;
771 case 1:
772 xreflabel[c] = insertion_stack->item_function[i];
773 break;
774 case 2:
775 position[c] = insertion_stack->item_function[i];
776 break;
778 c++;
779 i++;
783 skip_whitespace_and_newlines ();
785 start_of_end = get_until ("\n@end float", &text);
787 /* Get also the @caption. */
788 i = search_forward_until_pos ("\n@caption{",
789 save_input_text_offset, start_of_end);
790 if (i > -1)
792 input_text_offset = i + sizeof ("\n@caption{") - 1;
793 get_until_in_braces ("\n@end float", &caption);
794 input_text_offset = save_input_text_offset;
796 else
797 caption = "";
799 /* ... and the @shortcaption. */
800 i = search_forward_until_pos ("\n@shortcaption{",
801 save_input_text_offset, start_of_end);
802 if (i > -1)
804 input_text_offset = i + sizeof ("\n@shortcaption{") - 1;
805 get_until_in_braces ("\n@end float", &shortcaption);
806 input_text_offset = save_input_text_offset;
808 else
809 shortcaption = "";
811 canon_white (xreflabel);
812 canon_white (floattype);
813 canon_white (position);
814 canon_white (caption);
815 canon_white (shortcaption);
817 add_new_float (xstrdup (xreflabel),
818 xstrdup (caption), xstrdup (shortcaption),
819 xstrdup (floattype), xstrdup (position));
821 /* Move to the start of the @float so the contents get processed as
822 usual. */
823 input_text_offset = save_input_text_offset;
824 line_number = save_line_number;
827 if (html)
828 add_html_block_elt ("<div class=\"float\">\n");
829 else if (docbook)
830 xml_insert_element (FLOAT, START);
831 else if (xml)
833 xml_insert_element_with_attribute (FLOAT, START,
834 "name=\"%s\"", current_float_id ());
836 xml_insert_element (FLOATTYPE, START);
837 execute_string ("%s", current_float_type ());
838 xml_insert_element (FLOATTYPE, END);
840 xml_insert_element (FLOATPOS, START);
841 execute_string ("%s", current_float_position ());
842 xml_insert_element (FLOATPOS, END);
844 else
845 { /* Info */
846 close_single_paragraph ();
847 inhibit_paragraph_indentation = 1;
850 /* Anchor now. Note that XML documents get their
851 anchors with <float name="anchor"> tag. */
852 if ((!xml || docbook) && strlen (current_float_id ()) > 0)
853 execute_string ("@anchor{%s}", current_float_id ());
855 break;
857 /* Insertions that are no-ops in info, but do something in TeX. */
858 case ifclear:
859 case ifdocbook:
860 case ifhtml:
861 case ifinfo:
862 case ifnotdocbook:
863 case ifnothtml:
864 case ifnotinfo:
865 case ifnotplaintext:
866 case ifnottex:
867 case ifnotxml:
868 case ifplaintext:
869 case ifset:
870 case iftex:
871 case ifxml:
872 case rawtex:
873 if (in_menu)
874 no_discard++;
875 break;
877 case rawdocbook:
878 case rawhtml:
879 case rawxml:
880 raw_output_block++;
882 if (raw_output_block > 0)
884 xml_no_para = 1;
885 escape_html = 0;
886 xml_keep_space++;
890 /* Some deuglification for improved readability. */
891 extern int xml_in_para;
892 if (xml && !xml_in_para && xml_indentation_increment > 0)
893 add_char ('\n');
896 break;
898 case defcv:
899 case deffn:
900 case defivar:
901 case defmac:
902 case defmethod:
903 case defop:
904 case defopt:
905 case defspec:
906 case deftp:
907 case deftypecv:
908 case deftypefn:
909 case deftypefun:
910 case deftypeivar:
911 case deftypemethod:
912 case deftypeop:
913 case deftypevar:
914 case deftypevr:
915 case defun:
916 case defvar:
917 case defvr:
918 inhibit_paragraph_indentation = 1;
919 filling_enabled = indented_fill = 1;
920 current_indent += default_indentation_increment;
921 no_indent = 0;
922 if (xml)
923 xml_begin_definition ();
924 break;
926 case flushleft:
927 close_single_paragraph ();
928 inhibit_paragraph_indentation = 1;
929 filling_enabled = indented_fill = no_indent = 0;
930 if (html)
931 add_html_block_elt ("<div align=\"left\">");
932 break;
934 case flushright:
935 close_single_paragraph ();
936 filling_enabled = indented_fill = no_indent = 0;
937 inhibit_paragraph_indentation = 1;
938 force_flush_right++;
939 if (html)
940 add_html_block_elt ("<div align=\"right\">");
941 break;
943 case titlepage:
944 xml_insert_element (TITLEPAGE, START);
945 break;
947 default:
948 line_error ("begin_insertion internal error: type=%d", type);
951 if (!no_discard)
952 discard_until ("\n");
955 /* Try to end the insertion with the specified TYPE. With a value of
956 `bad_type', TYPE gets translated to match the value currently on top
957 of the stack. Otherwise, if TYPE doesn't match the top of the
958 insertion stack, give error. */
959 static void
960 end_insertion (int type)
962 int temp_type;
964 if (!insertion_level)
965 return;
967 temp_type = current_insertion_type ();
969 if (type == bad_type)
970 type = temp_type;
972 if (type != temp_type)
974 line_error
975 (_("`@end' expected `%s', but saw `%s'"),
976 insertion_type_pname (temp_type), insertion_type_pname (type));
977 return;
980 pop_insertion ();
982 if (xml)
984 switch (type)
986 case ifinfo:
987 case documentdescription:
988 break;
989 case quotation:
990 xml_insert_quotation ("", END);
991 break;
992 case example:
993 xml_insert_element (EXAMPLE, END);
994 if (docbook && current_insertion_type () == floatenv)
995 xml_insert_element (FLOATEXAMPLE, END);
996 break;
997 case smallexample:
998 xml_insert_element (SMALLEXAMPLE, END);
999 if (docbook && current_insertion_type () == floatenv)
1000 xml_insert_element (FLOATEXAMPLE, END);
1001 break;
1002 case lisp:
1003 xml_insert_element (LISP, END);
1004 if (docbook && current_insertion_type () == floatenv)
1005 xml_insert_element (FLOATEXAMPLE, END);
1006 break;
1007 case smalllisp:
1008 xml_insert_element (SMALLLISP, END);
1009 if (docbook && current_insertion_type () == floatenv)
1010 xml_insert_element (FLOATEXAMPLE, END);
1011 break;
1012 case cartouche:
1013 xml_insert_element (CARTOUCHE, END);
1014 break;
1015 case format:
1016 if (docbook && xml_in_bookinfo && xml_in_abstract)
1018 xml_insert_element (ABSTRACT, END);
1019 xml_in_abstract = 0;
1021 else
1022 xml_insert_element (FORMAT, END);
1023 break;
1024 case smallformat:
1025 xml_insert_element (SMALLFORMAT, END);
1026 break;
1027 case display:
1028 xml_insert_element (DISPLAY, END);
1029 break;
1030 case smalldisplay:
1031 xml_insert_element (SMALLDISPLAY, END);
1032 break;
1033 case table:
1034 case ftable:
1035 case vtable:
1036 case itemize:
1037 xml_end_table (type);
1038 break;
1039 case enumerate:
1040 xml_end_enumerate ();
1041 break;
1042 case group:
1043 xml_insert_element (GROUP, END);
1044 break;
1045 case titlepage:
1046 xml_insert_element (TITLEPAGE, END);
1047 break;
1050 switch (type)
1052 /* Insertions which have no effect on paragraph formatting. */
1053 case copying:
1054 line_number--;
1055 break;
1057 case ifclear:
1058 case ifdocbook:
1059 case ifinfo:
1060 case ifhtml:
1061 case ifnotdocbook:
1062 case ifnothtml:
1063 case ifnotinfo:
1064 case ifnotplaintext:
1065 case ifnottex:
1066 case ifnotxml:
1067 case ifplaintext:
1068 case ifset:
1069 case iftex:
1070 case ifxml:
1071 case rawtex:
1072 case titlepage:
1073 break;
1075 case rawdocbook:
1076 case rawhtml:
1077 case rawxml:
1078 raw_output_block--;
1080 if (raw_output_block <= 0)
1082 xml_no_para = 0;
1083 escape_html = 1;
1084 xml_keep_space--;
1087 if ((xml || html) && output_paragraph[output_paragraph_offset-1] == '\n')
1088 output_paragraph_offset--;
1089 break;
1091 case detailmenu:
1092 if (xml)
1093 xml_insert_element (DETAILMENU, END);
1095 in_detailmenu--; /* No longer hacking menus. */
1096 if (!in_menu)
1098 if (!no_headers)
1099 close_insertion_paragraph ();
1101 break;
1103 case direntry: /* Eaten if html. */
1104 insert_string ("END-INFO-DIR-ENTRY\n\n");
1105 close_insertion_paragraph ();
1106 break;
1108 case documentdescription:
1109 if (xml)
1110 insert_string (document_description);
1111 xml_insert_element (DOCUMENTDESCRIPTION, END);
1112 break;
1114 case menu:
1115 in_menu--; /* No longer hacking menus. */
1116 if (html && !no_headers)
1117 add_html_block_elt ("</ul>\n");
1118 else if (!no_headers && !xml)
1119 close_insertion_paragraph ();
1120 break;
1122 case multitable:
1123 end_multitable ();
1124 break;
1126 case enumerate:
1127 stop_enumerating ();
1128 close_insertion_paragraph ();
1129 current_indent -= default_indentation_increment;
1130 if (html)
1131 add_html_block_elt ("</ol>\n");
1132 break;
1134 case flushleft:
1135 if (html)
1136 add_html_block_elt ("</div>\n");
1137 close_insertion_paragraph ();
1138 break;
1140 case cartouche:
1141 if (html)
1142 add_html_block_elt ("</td></tr></table>\n");
1143 close_insertion_paragraph ();
1144 break;
1146 case group:
1147 if (!xml || docbook)
1148 close_insertion_paragraph ();
1149 break;
1151 case floatenv:
1152 if (xml)
1153 xml_insert_element (FLOAT, END);
1154 else
1156 if (html)
1157 add_html_block_elt ("<p><strong class=\"float-caption\">");
1158 else
1159 close_paragraph ();
1161 no_indent = 1;
1163 /* Legend:
1164 1) @float Foo,lbl & no caption: Foo 1.1
1165 2) @float Foo & no caption: Foo
1166 3) @float ,lbl & no caption: 1.1
1167 4) @float & no caption: */
1169 if (!xml && !html)
1170 indent (current_indent);
1172 if (strlen (current_float_type ()))
1173 execute_string ("%s", current_float_type ());
1175 if (strlen (current_float_id ()) > 0)
1177 if (strlen (current_float_type ()) > 0)
1178 add_char (' ');
1180 add_word (current_float_number ());
1183 if (strlen (current_float_title ()) > 0)
1185 if (strlen (current_float_type ()) > 0
1186 || strlen (current_float_id ()) > 0)
1187 insert_string (": ");
1189 execute_string ("%s", current_float_title ());
1192 /* Indent the following paragraph. */
1193 inhibit_paragraph_indentation = 0;
1195 if (html)
1196 add_word ("</strong></p></div>\n");
1197 else
1198 close_paragraph ();
1200 float_active--;
1201 break;
1203 case format:
1204 case smallformat:
1205 case display:
1206 case smalldisplay:
1207 case example:
1208 case smallexample:
1209 case lisp:
1210 case smalllisp:
1211 case quotation:
1212 /* @format and @smallformat are the only fixed_width insertion
1213 without a change in indentation. */
1214 if (type != format && type != smallformat && type != quotation)
1215 current_indent -= example_indentation_increment;
1216 else if (type == quotation)
1217 current_indent -= default_indentation_increment;
1219 if (html)
1220 { /* The complex code in close_paragraph that kills whitespace
1221 does not function here, since we've inserted non-whitespace
1222 (the </whatever>) before it. The indentation already got
1223 inserted at the end of the last example line, so we have to
1224 delete it, or browsers wind up showing an extra blank line. */
1225 kill_self_indent (default_indentation_increment);
1226 add_html_block_elt (type == quotation
1227 ? "</blockquote>\n" : "</pre>\n");
1230 /* The ending of one of these insertions always marks the
1231 start of a new paragraph, except for the XML output. */
1232 if (!xml || docbook)
1233 close_insertion_paragraph ();
1235 /* </pre> closes paragraph without messing with </p>. */
1236 if (html && type != quotation)
1237 paragraph_is_open = 0;
1238 break;
1240 case table:
1241 case ftable:
1242 case vtable:
1243 current_indent -= default_indentation_increment;
1244 if (html)
1245 add_html_block_elt ("</dl>\n");
1246 close_insertion_paragraph ();
1247 break;
1249 case itemize:
1250 current_indent -= default_indentation_increment;
1251 if (html)
1252 add_html_block_elt ("</ul>\n");
1253 close_insertion_paragraph ();
1254 break;
1256 case flushright:
1257 force_flush_right--;
1258 if (html)
1259 add_html_block_elt ("</div>\n");
1260 close_insertion_paragraph ();
1261 break;
1263 /* Handle the @defun insertions with this default clause. */
1264 default:
1266 int base_type;
1268 if (type < defcv || type > defvr)
1269 line_error ("end_insertion internal error: type=%d", type);
1271 base_type = get_base_type (type);
1272 switch (base_type)
1274 case deffn:
1275 case defvr:
1276 case deftp:
1277 case deftypecv:
1278 case deftypefn:
1279 case deftypevr:
1280 case defcv:
1281 case defop:
1282 case deftypemethod:
1283 case deftypeop:
1284 case deftypeivar:
1285 if (html)
1287 if (paragraph_is_open)
1288 add_html_block_elt ("</p>");
1289 /* close the div and blockquote which has been opened in defun.c */
1290 if (!rollback_empty_tag ("blockquote"))
1291 add_html_block_elt ("</blockquote>");
1292 add_html_block_elt ("</div>\n");
1294 if (xml)
1295 xml_end_definition ();
1296 break;
1297 } /* switch (base_type)... */
1299 current_indent -= default_indentation_increment;
1300 close_insertion_paragraph ();
1302 break;
1306 if (current_indent < 0)
1307 line_error ("end_insertion internal error: current indent=%d",
1308 current_indent);
1311 /* Insertions cannot cross certain boundaries, such as node beginnings. In
1312 code that creates such boundaries, you should call `discard_insertions'
1313 before doing anything else. It prints the errors for you, and cleans up
1314 the insertion stack.
1316 With nonzero SPECIALS_OK argument, allows unmatched
1317 @if... conditionals, otherwise not. This is because conditionals can
1318 cross node boundaries. Always happens with the @top node, for example. */
1319 void
1320 discard_insertions (int specials_ok)
1322 int real_line_number = line_number;
1323 while (insertion_stack)
1325 if (specials_ok
1326 && ((ifclear <= insertion_stack->insertion
1327 && insertion_stack->insertion <= iftex)
1328 || insertion_stack->insertion == rawdocbook
1329 || insertion_stack->insertion == rawhtml
1330 || insertion_stack->insertion == rawxml
1331 || insertion_stack->insertion == rawtex))
1332 break;
1333 else
1335 const char *offender = insertion_type_pname (insertion_stack->insertion);
1337 file_line_error (insertion_stack->filename,
1338 insertion_stack->line_number,
1339 _("No matching `%cend %s'"), COMMAND_PREFIX,
1340 offender);
1341 pop_insertion ();
1344 line_number = real_line_number;
1347 /* Insertion (environment) commands. */
1349 void
1350 cm_quotation (void)
1352 /* We start the blockquote element in the insertion. */
1353 begin_insertion (quotation);
1356 void
1357 cm_example (void)
1359 if (docbook && current_insertion_type () == floatenv)
1360 xml_begin_docbook_float (FLOATEXAMPLE);
1362 if (xml)
1364 /* Rollback previous newlines. These occur between
1365 </para> and <example>. */
1366 if (output_paragraph[output_paragraph_offset-1] == '\n')
1367 output_paragraph_offset--;
1369 xml_insert_element (EXAMPLE, START);
1371 /* Make sure example text is starting on a new line
1372 for improved readability. */
1373 if (docbook)
1374 add_char ('\n');
1377 begin_insertion (example);
1380 void
1381 cm_smallexample (void)
1383 if (docbook && current_insertion_type () == floatenv)
1384 xml_begin_docbook_float (FLOATEXAMPLE);
1386 if (xml)
1388 /* See cm_example comments about newlines. */
1389 if (output_paragraph[output_paragraph_offset-1] == '\n')
1390 output_paragraph_offset--;
1391 xml_insert_element (SMALLEXAMPLE, START);
1392 if (docbook)
1393 add_char ('\n');
1396 begin_insertion (smallexample);
1399 void
1400 cm_lisp (void)
1402 if (docbook && current_insertion_type () == floatenv)
1403 xml_begin_docbook_float (FLOATEXAMPLE);
1405 if (xml)
1407 /* See cm_example comments about newlines. */
1408 if (output_paragraph[output_paragraph_offset-1] == '\n')
1409 output_paragraph_offset--;
1410 xml_insert_element (LISP, START);
1411 if (docbook)
1412 add_char ('\n');
1415 begin_insertion (lisp);
1418 void
1419 cm_smalllisp (void)
1421 if (docbook && current_insertion_type () == floatenv)
1422 xml_begin_docbook_float (FLOATEXAMPLE);
1424 if (xml)
1426 /* See cm_example comments about newlines. */
1427 if (output_paragraph[output_paragraph_offset-1] == '\n')
1428 output_paragraph_offset--;
1429 xml_insert_element (SMALLLISP, START);
1430 if (docbook)
1431 add_char ('\n');
1434 begin_insertion (smalllisp);
1437 void
1438 cm_cartouche (void)
1440 if (docbook && current_insertion_type () == floatenv)
1441 xml_begin_docbook_float (CARTOUCHE);
1443 if (xml)
1444 xml_insert_element (CARTOUCHE, START);
1445 begin_insertion (cartouche);
1448 void
1449 cm_copying (void)
1451 begin_insertion (copying);
1454 /* Not an insertion, despite the name, but it goes with cm_copying. */
1455 void
1456 cm_insert_copying (void)
1458 if (!copying_text)
1460 warning ("@copying not used before %s", command);
1461 return;
1464 execute_string ("%s", copying_text);
1466 if (!xml && !html)
1468 add_word ("\n\n");
1469 /* Update output_position so that the node positions in the tag
1470 tables will take account of the copying text. */
1471 flush_output ();
1475 void
1476 cm_format (void)
1478 if (xml)
1480 if (docbook && xml_in_bookinfo)
1482 xml_insert_element (ABSTRACT, START);
1483 xml_in_abstract = 1;
1485 else
1487 /* See cm_example comments about newlines. */
1488 if (output_paragraph[output_paragraph_offset-1] == '\n')
1489 output_paragraph_offset--;
1490 xml_insert_element (FORMAT, START);
1491 if (docbook)
1492 add_char ('\n');
1495 begin_insertion (format);
1498 void
1499 cm_smallformat (void)
1501 if (xml)
1503 /* See cm_example comments about newlines. */
1504 if (output_paragraph[output_paragraph_offset-1] == '\n')
1505 output_paragraph_offset--;
1506 xml_insert_element (SMALLFORMAT, START);
1507 if (docbook)
1508 add_char ('\n');
1511 begin_insertion (smallformat);
1514 void
1515 cm_display (void)
1517 if (xml)
1519 /* See cm_example comments about newlines. */
1520 if (output_paragraph[output_paragraph_offset-1] == '\n')
1521 output_paragraph_offset--;
1522 xml_insert_element (DISPLAY, START);
1523 if (docbook)
1524 add_char ('\n');
1527 begin_insertion (display);
1530 void
1531 cm_smalldisplay (void)
1533 if (xml)
1535 /* See cm_example comments about newlines. */
1536 if (output_paragraph[output_paragraph_offset-1] == '\n')
1537 output_paragraph_offset--;
1538 xml_insert_element (SMALLDISPLAY, START);
1539 if (docbook)
1540 add_char ('\n');
1543 begin_insertion (smalldisplay);
1546 void
1547 cm_direntry (void)
1549 if (html || xml || no_headers)
1550 command_name_condition ();
1551 else
1552 begin_insertion (direntry);
1555 void
1556 cm_documentdescription (void)
1558 if (html)
1559 begin_insertion (documentdescription);
1561 else if (xml)
1563 xml_insert_element (DOCUMENTDESCRIPTION, START);
1564 begin_insertion (documentdescription);
1567 else
1568 command_name_condition ();
1572 void
1573 cm_itemize (void)
1575 begin_insertion (itemize);
1578 /* Start an enumeration insertion of type TYPE. If the user supplied
1579 no argument on the line, then use DEFAULT_STRING as the initial string. */
1580 static void
1581 do_enumeration (int type, char *default_string)
1583 get_until_in_line (0, ".", &enumeration_arg);
1584 canon_white (enumeration_arg);
1586 if (!*enumeration_arg)
1588 free (enumeration_arg);
1589 enumeration_arg = xstrdup (default_string);
1592 if (!isdigit (*enumeration_arg) && !isletter (*enumeration_arg))
1594 warning (_("%s requires letter or digit"), insertion_type_pname (type));
1596 switch (type)
1598 case enumerate:
1599 default_string = "1";
1600 break;
1602 enumeration_arg = xstrdup (default_string);
1604 begin_insertion (type);
1607 void
1608 cm_enumerate (void)
1610 do_enumeration (enumerate, "1");
1613 /* Handle verbatim environment:
1614 find_end_verbatim == 0: process until end of file
1615 find_end_verbatim != 0: process until 'COMMAND_PREFIXend verbatim'
1616 or end of file
1618 We cannot simply copy input stream onto output stream; as the
1619 verbatim environment may be encapsulated in an @example environment,
1620 for example. */
1621 void
1622 handle_verbatim_environment (int find_end_verbatim)
1624 int character;
1625 int seen_end = 0;
1626 int save_filling_enabled = filling_enabled;
1627 int save_inhibit_paragraph_indentation = inhibit_paragraph_indentation;
1628 int save_escape_html = escape_html;
1630 if (!insertion_stack)
1631 close_single_paragraph (); /* no blank lines if not at outer level */
1632 inhibit_paragraph_indentation = 1;
1633 filling_enabled = 0;
1634 in_fixed_width_font++;
1635 last_char_was_newline = 0;
1637 /* No indentation: this is verbatim after all
1638 If you want indent, enclose @verbatim in @example
1639 current_indent += default_indentation_increment;
1642 if (html)
1643 { /* If inside @example, we'll be preceded by the indentation
1644 already. Browsers will ignore those spaces because we're about
1645 to start another <pre> (don't ask me). So, wipe them out for
1646 cleanliness, and re-insert. */
1647 int i;
1648 kill_self_indent (default_indentation_increment);
1649 add_html_block_elt ("<pre class=\"verbatim\">");
1650 for (i = current_indent; i > 0; i--)
1651 add_char (' ');
1653 else if (xml)
1655 xml_insert_element (VERBATIM, START);
1656 escape_html = 0;
1657 add_word ("<![CDATA[");
1660 while (input_text_offset < input_text_length)
1662 character = curchar ();
1664 if (character == '\n')
1665 line_number++;
1667 /* Assume no newlines in END_VERBATIM. */
1668 else if (find_end_verbatim && (character == COMMAND_PREFIX) /* @ */
1669 && (input_text_length - input_text_offset > sizeof (END_VERBATIM))
1670 && !strncmp (&input_text[input_text_offset+1], END_VERBATIM,
1671 sizeof (END_VERBATIM)-1))
1673 input_text_offset += sizeof (END_VERBATIM);
1674 seen_end = 1;
1675 break;
1678 if (html && character == '&' && escape_html)
1679 add_word ("&amp;");
1680 else if (html && character == '<' && escape_html)
1681 add_word ("&lt;");
1682 else
1683 add_char (character);
1685 input_text_offset++;
1688 if (find_end_verbatim && !seen_end)
1689 warning (_("end of file inside verbatim block"));
1691 if (html)
1692 { /* See comments in example case above. */
1693 kill_self_indent (default_indentation_increment);
1694 add_word ("</pre>");
1696 else if (xml)
1698 add_word ("]]>");
1699 xml_insert_element (VERBATIM, END);
1700 escape_html = save_escape_html;
1703 in_fixed_width_font--;
1704 filling_enabled = save_filling_enabled;
1705 inhibit_paragraph_indentation = save_inhibit_paragraph_indentation;
1708 void
1709 cm_verbatim (void)
1711 handle_verbatim_environment (1);
1714 void
1715 cm_table (void)
1717 begin_insertion (table);
1720 void
1721 cm_multitable (void)
1723 begin_insertion (multitable); /* @@ */
1726 void
1727 cm_ftable (void)
1729 begin_insertion (ftable);
1732 void
1733 cm_vtable (void)
1735 begin_insertion (vtable);
1738 void
1739 cm_group (void)
1741 begin_insertion (group);
1744 /* Insert raw HTML (no escaping of `<' etc.). */
1745 void
1746 cm_html (int arg)
1748 if (process_html)
1749 begin_insertion (rawhtml);
1750 else
1751 command_name_condition ();
1754 void
1755 cm_xml (int arg)
1757 if (process_xml)
1758 begin_insertion (rawxml);
1759 else
1760 command_name_condition ();
1763 void
1764 cm_docbook (int arg)
1766 if (process_docbook)
1767 begin_insertion (rawdocbook);
1768 else
1769 command_name_condition ();
1772 void
1773 cm_ifdocbook (void)
1775 if (process_docbook)
1776 begin_insertion (ifdocbook);
1777 else
1778 command_name_condition ();
1781 void
1782 cm_ifnotdocbook (void)
1784 if (!process_docbook)
1785 begin_insertion (ifnotdocbook);
1786 else
1787 command_name_condition ();
1790 void
1791 cm_ifhtml (void)
1793 if (process_html)
1794 begin_insertion (ifhtml);
1795 else
1796 command_name_condition ();
1799 void
1800 cm_ifnothtml (void)
1802 if (!process_html)
1803 begin_insertion (ifnothtml);
1804 else
1805 command_name_condition ();
1809 void
1810 cm_ifinfo (void)
1812 if (process_info)
1813 begin_insertion (ifinfo);
1814 else
1815 command_name_condition ();
1818 void
1819 cm_ifnotinfo (void)
1821 if (!process_info)
1822 begin_insertion (ifnotinfo);
1823 else
1824 command_name_condition ();
1828 void
1829 cm_ifplaintext (void)
1831 if (process_plaintext)
1832 begin_insertion (ifplaintext);
1833 else
1834 command_name_condition ();
1837 void
1838 cm_ifnotplaintext (void)
1840 if (!process_plaintext)
1841 begin_insertion (ifnotplaintext);
1842 else
1843 command_name_condition ();
1847 void
1848 cm_tex (void)
1850 if (process_tex)
1851 begin_insertion (rawtex);
1852 else
1853 command_name_condition ();
1856 void
1857 cm_iftex (void)
1859 if (process_tex)
1860 begin_insertion (iftex);
1861 else
1862 command_name_condition ();
1865 void
1866 cm_ifnottex (void)
1868 if (!process_tex)
1869 begin_insertion (ifnottex);
1870 else
1871 command_name_condition ();
1874 void
1875 cm_ifxml (void)
1877 if (process_xml)
1878 begin_insertion (ifxml);
1879 else
1880 command_name_condition ();
1883 void
1884 cm_ifnotxml (void)
1886 if (!process_xml)
1887 begin_insertion (ifnotxml);
1888 else
1889 command_name_condition ();
1893 /* Generic xrefable block with a caption. */
1894 void
1895 cm_float (void)
1897 begin_insertion (floatenv);
1900 void
1901 cm_caption (int arg)
1903 char *temp;
1905 /* This is a no_op command for most formats, as we handle it during @float
1906 insertion. For XML though, we handle it here to keep document structure
1907 as close as possible, to the Texinfo source. */
1909 /* Everything is already handled at START. */
1910 if (arg == END)
1911 return;
1913 /* Check if it's mislocated. */
1914 if (current_insertion_type () != floatenv)
1915 line_error (_("@%s not meaningful outside `@float' environment"), command);
1917 get_until_in_braces ("\n@end float", &temp);
1919 if (xml)
1921 int elt = STREQ (command, "shortcaption") ? SHORTCAPTION : CAPTION;
1922 xml_insert_element (elt, START);
1923 if (!docbook)
1924 execute_string ("%s", temp);
1925 xml_insert_element (elt, END);
1928 free (temp);
1931 /* Begin an insertion where the lines are not filled or indented. */
1932 void
1933 cm_flushleft (void)
1935 begin_insertion (flushleft);
1938 /* Begin an insertion where the lines are not filled, and each line is
1939 forced to the right-hand side of the page. */
1940 void
1941 cm_flushright (void)
1943 begin_insertion (flushright);
1946 void
1947 cm_menu (void)
1949 if (current_node == NULL && !macro_expansion_output_stream)
1951 warning (_("@menu seen before first @node, creating `Top' node"));
1952 warning (_("perhaps your @top node should be wrapped in @ifnottex rather than @ifinfo?"));
1953 /* Include @top command so we can construct the implicit node tree. */
1954 execute_string ("@node top\n@top Top\n");
1956 begin_insertion (menu);
1959 void
1960 cm_detailmenu (void)
1962 if (current_node == NULL && !macro_expansion_output_stream)
1963 { /* Problems anyway, @detailmenu should always be inside @menu. */
1964 warning (_("@detailmenu seen before first node, creating `Top' node"));
1965 execute_string ("@node top\n@top Top\n");
1967 begin_insertion (detailmenu);
1970 /* Title page commands. */
1972 void
1973 cm_titlepage (void)
1975 titlepage_cmd_present = 1;
1976 if (xml && !docbook)
1977 begin_insertion (titlepage);
1978 else
1979 command_name_condition ();
1982 void
1983 cm_author (void)
1985 char *rest;
1986 get_rest_of_line (1, &rest);
1988 if (is_in_insertion_of_type (quotation))
1990 if (html)
1991 add_word_args ("&mdash; %s", rest);
1992 else if (docbook)
1994 /* FIXME Ideally, we should use an attribution element,
1995 but they are supposed to be at the start of quotation
1996 blocks. So to avoid looking ahead mess, let's just
1997 use mdash like HTML for now. */
1998 xml_insert_entity ("mdash");
1999 add_word (rest);
2001 else if (xml)
2003 xml_insert_element (AUTHOR, START);
2004 add_word (rest);
2005 xml_insert_element (AUTHOR, END);
2007 else
2008 add_word_args ("-- %s", rest);
2010 else if (is_in_insertion_of_type (titlepage))
2012 if (xml && !docbook)
2014 xml_insert_element (AUTHOR, START);
2015 add_word (rest);
2016 xml_insert_element (AUTHOR, END);
2019 else
2020 line_error (_("@%s not meaningful outside `@titlepage' and `@quotation' environments"),
2021 command);
2023 free (rest);
2026 void
2027 cm_titlepage_cmds (void)
2029 char *rest;
2031 get_rest_of_line (1, &rest);
2033 if (!is_in_insertion_of_type (titlepage))
2034 line_error (_("@%s not meaningful outside `@titlepage' environment"),
2035 command);
2037 if (xml && !docbook)
2039 int elt = 0;
2041 if (STREQ (command, "title"))
2042 elt = BOOKTITLE;
2043 else if (STREQ (command, "subtitle"))
2044 elt = BOOKSUBTITLE;
2046 xml_insert_element (elt, START);
2047 add_word (rest);
2048 xml_insert_element (elt, END);
2051 free (rest);
2054 /* End existing insertion block. */
2055 void
2056 cm_end (void)
2058 char *temp;
2059 int type;
2061 get_rest_of_line (0, &temp);
2063 if (!insertion_level)
2065 line_error (_("Unmatched `%c%s'"), COMMAND_PREFIX, command);
2066 return;
2069 if (temp[0] == 0)
2070 line_error (_("`%c%s' needs something after it"), COMMAND_PREFIX, command);
2072 type = find_type_from_name (temp);
2074 if (type == bad_type)
2076 line_error (_("Bad argument `%s' to `@%s', using `%s'"),
2077 temp, command, insertion_type_pname (current_insertion_type ()));
2079 if (xml && type == menu) /* fixme */
2081 xml_end_menu ();
2083 end_insertion (type);
2084 free (temp);
2087 /* @itemx, @item. */
2089 static int itemx_flag = 0;
2091 /* Return whether CMD takes a brace-delimited {arg}. */
2093 command_needs_braces (char *cmd)
2095 int i;
2096 for (i = 0; command_table[i].name; i++)
2098 if (STREQ (command_table[i].name, cmd))
2099 return command_table[i].argument_in_braces == BRACE_ARGS;
2102 return 0; /* macro or alias */
2106 void
2107 cm_item (void)
2109 char *rest_of_line, *item_func;
2111 /* Can only hack "@item" while inside of an insertion. */
2112 if (insertion_level)
2114 INSERTION_ELT *stack = insertion_stack;
2115 int original_input_text_offset;
2117 skip_whitespace ();
2118 original_input_text_offset = input_text_offset;
2120 get_rest_of_line (0, &rest_of_line);
2121 item_func = current_item_function ();
2123 /* Do the right thing depending on which insertion function is active. */
2124 switch_top:
2125 switch (stack->insertion)
2127 case multitable:
2128 multitable_item ();
2129 /* Support text directly after the @item. */
2130 if (*rest_of_line)
2132 line_number--;
2133 input_text_offset = original_input_text_offset;
2135 break;
2137 case ifclear:
2138 case ifhtml:
2139 case ifinfo:
2140 case ifnothtml:
2141 case ifnotinfo:
2142 case ifnotplaintext:
2143 case ifnottex:
2144 case ifnotxml:
2145 case ifplaintext:
2146 case ifset:
2147 case iftex:
2148 case ifxml:
2149 case rawdocbook:
2150 case rawhtml:
2151 case rawxml:
2152 case rawtex:
2153 case tex:
2154 case cartouche:
2155 stack = stack->next;
2156 if (!stack)
2157 goto no_insertion;
2158 else
2159 goto switch_top;
2160 break;
2162 case menu:
2163 case quotation:
2164 case example:
2165 case smallexample:
2166 case lisp:
2167 case smalllisp:
2168 case format:
2169 case smallformat:
2170 case display:
2171 case smalldisplay:
2172 case group:
2173 line_error (_("@%s not meaningful inside `@%s' block"),
2174 command,
2175 insertion_type_pname (current_insertion_type ()));
2176 break;
2178 case itemize:
2179 case enumerate:
2180 if (itemx_flag)
2182 line_error (_("@itemx not meaningful inside `%s' block"),
2183 insertion_type_pname (current_insertion_type ()));
2185 else
2187 if (html)
2188 add_html_block_elt ("<li>");
2189 else if (xml)
2190 xml_begin_item ();
2191 else
2193 start_paragraph ();
2194 kill_self_indent (-1);
2195 filling_enabled = indented_fill = 1;
2197 if (current_item_function ())
2199 output_column = current_indent - 2;
2200 indent (output_column);
2202 /* The item marker can be given with or without
2203 braces -- @bullet and @bullet{} are both ok.
2204 Or it might be something that doesn't take
2205 braces at all, such as "o" or "#" or "@ ".
2206 Thus, only supply braces if the item marker is
2207 a command, they haven't supplied braces
2208 themselves, and we know it needs them. */
2209 if (item_func && *item_func)
2211 if (*item_func == COMMAND_PREFIX
2212 && item_func[strlen (item_func) - 1] != '}'
2213 && command_needs_braces (item_func + 1))
2214 execute_string ("%s{}", item_func);
2215 else
2216 execute_string ("%s", item_func);
2218 insert (' ');
2219 output_column++;
2221 else
2222 enumerate_item ();
2224 /* Special hack. This makes `close_paragraph' a no-op until
2225 `start_paragraph' has been called. */
2226 must_start_paragraph = 1;
2229 /* Handle text directly after the @item. */
2230 if (*rest_of_line)
2232 line_number--;
2233 input_text_offset = original_input_text_offset;
2236 break;
2238 case table:
2239 case ftable:
2240 case vtable:
2241 if (html)
2242 { /* If nothing has been output since the last <dd>,
2243 remove the empty <dd> element. Some browsers render
2244 an extra empty line for <dd><dt>, which makes @itemx
2245 conversion look ugly. */
2246 rollback_empty_tag ("dd");
2248 /* Force the browser to render one blank line before
2249 each new @item in a table. But don't do that if
2250 this is the first <dt> after the <dl>, or if we are
2251 converting @itemx.
2253 Note that there are some browsers which ignore <br>
2254 in this context, but I cannot find any way to force
2255 them all render exactly one blank line. */
2256 if (!itemx_flag && html_deflist_has_term)
2257 add_html_block_elt ("<br>");
2259 /* We are about to insert a <dt>, so this <dl> has a term.
2260 Feel free to insert a <br> next time. :) */
2261 html_deflist_has_term = 1;
2263 add_html_block_elt ("<dt>");
2264 if (item_func && *item_func)
2265 execute_string ("%s{%s}", item_func, rest_of_line);
2266 else
2267 execute_string ("%s", rest_of_line);
2269 if (current_insertion_type () == ftable)
2270 execute_string ("%cfindex %s\n", COMMAND_PREFIX, rest_of_line);
2272 if (current_insertion_type () == vtable)
2273 execute_string ("%cvindex %s\n", COMMAND_PREFIX, rest_of_line);
2275 add_html_block_elt ("<dd>");
2277 else if (xml) /* && docbook)*/ /* 05-08 */
2279 xml_begin_table_item ();
2281 if (!docbook && current_insertion_type () == ftable)
2282 execute_string ("%cfindex %s\n", COMMAND_PREFIX, rest_of_line);
2284 if (!docbook && current_insertion_type () == vtable)
2285 execute_string ("%cvindex %s\n", COMMAND_PREFIX, rest_of_line);
2287 if (item_func && *item_func)
2288 execute_string ("%s{%s}", item_func, rest_of_line);
2289 else
2290 execute_string ("%s", rest_of_line);
2291 xml_continue_table_item ();
2293 else
2295 /* We need this to determine if we have two @item's in a row
2296 (see test just below). */
2297 static int last_item_output_position = 0;
2299 /* Get rid of extra characters. */
2300 kill_self_indent (-1);
2302 /* If we have one @item followed directly by another @item,
2303 we need to insert a blank line. This is not true for
2304 @itemx, though. */
2305 if (!itemx_flag && last_item_output_position == output_position)
2306 insert ('\n');
2308 /* `close_paragraph' almost does what we want. The problem
2309 is when paragraph_is_open, and last_char_was_newline, and
2310 the last newline has been turned into a space, because
2311 filling_enabled. I handle it here. */
2312 if (last_char_was_newline && filling_enabled &&
2313 paragraph_is_open)
2314 insert ('\n');
2315 close_paragraph ();
2317 #if defined (INDENT_PARAGRAPHS_IN_TABLE)
2318 /* Indent on a new line, but back up one indentation level. */
2320 int save = inhibit_paragraph_indentation;
2321 inhibit_paragraph_indentation = 1;
2322 /* At this point, inserting any non-whitespace character will
2323 force the existing indentation to be output. */
2324 add_char ('i');
2325 inhibit_paragraph_indentation = save;
2327 #else /* !INDENT_PARAGRAPHS_IN_TABLE */
2328 add_char ('i');
2329 #endif /* !INDENT_PARAGRAPHS_IN_TABLE */
2331 output_paragraph_offset--;
2332 kill_self_indent (default_indentation_increment + 1);
2334 /* Add item's argument to the line. */
2335 filling_enabled = 0;
2336 if (item_func && *item_func)
2337 execute_string ("%s{%s}", item_func, rest_of_line);
2338 else
2339 execute_string ("%s", rest_of_line);
2341 if (current_insertion_type () == ftable)
2342 execute_string ("%cfindex %s\n", COMMAND_PREFIX, rest_of_line);
2343 else if (current_insertion_type () == vtable)
2344 execute_string ("%cvindex %s\n", COMMAND_PREFIX, rest_of_line);
2346 /* Start a new line, and let start_paragraph ()
2347 do the indenting of it for you. */
2348 close_single_paragraph ();
2349 indented_fill = filling_enabled = 1;
2350 last_item_output_position = output_position;
2353 free (rest_of_line);
2355 else
2357 no_insertion:
2358 line_error (_("%c%s found outside of an insertion block"),
2359 COMMAND_PREFIX, command);
2363 void
2364 cm_itemx (void)
2366 itemx_flag++;
2367 cm_item ();
2368 itemx_flag--;
2371 int headitem_flag = 0;
2373 void
2374 cm_headitem (void)
2376 headitem_flag = 1;
2377 cm_item ();