MFC 1.45 for the 2.0 release: Properly set B_INVAL after failed read.
[dragonfly.git] / contrib / texinfo-4 / makeinfo / insertion.c
blob05a20440eba3a216af05a0d3114625970e0ed37a
1 /* insertion.c -- insertions for Texinfo.
2 $Id: insertion.c,v 1.55 2004/11/11 18:34:28 karl Exp $
4 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
5 Foundation, Inc.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21 #include "system.h"
22 #include "cmds.h"
23 #include "defun.h"
24 #include "float.h"
25 #include "html.h"
26 #include "insertion.h"
27 #include "macro.h"
28 #include "makeinfo.h"
29 #include "multi.h"
30 #include "xml.h"
32 /* Must match list in insertion.h. */
33 static char *insertion_type_names[] =
35 "cartouche", "copying", "defcv", "deffn", "defivar", "defmac",
36 "defmethod", "defop", "defopt", "defspec", "deftp", "deftypecv",
37 "deftypefn", "deftypefun", "deftypeivar", "deftypemethod",
38 "deftypeop", "deftypevar", "deftypevr", "defun", "defvar", "defvr",
39 "detailmenu", "direntry", "display", "documentdescription",
40 "enumerate", "example", "float", "flushleft", "flushright", "format",
41 "ftable", "group", "ifclear", "ifdocbook", "ifhtml", "ifinfo",
42 "ifnotdocbook", "ifnothtml", "ifnotinfo", "ifnotplaintext", "ifnottex",
43 "ifnotxml", "ifplaintext", "ifset", "iftex", "ifxml", "itemize", "lisp",
44 "menu", "multitable", "quotation", "rawdocbook", "rawhtml", "rawtex",
45 "rawxml", "smalldisplay", "smallexample", "smallformat", "smalllisp",
46 "verbatim", "table", "tex", "vtable", "titlepage", "bad_type"
49 /* All nested environments. */
50 INSERTION_ELT *insertion_stack = NULL;
52 /* How deeply we're nested. */
53 int insertion_level = 0;
55 /* Set to 1 if we've processed (commentary) text in a @menu that
56 wasn't part of a menu item. */
57 int had_menu_commentary;
59 /* How to examine menu lines. */
60 int in_detailmenu = 0;
62 /* Whether to examine menu lines. */
63 int in_menu = 0;
65 /* Set to 1 if <p> is written in normal context.
66 Used for menu and itemize. */
67 int in_paragraph = 0;
69 /* Since an insertion is already in the stack before we reach the switch
70 statement, we cannot use is_in_insertion_of_type (always returns true.) Also
71 making it return the level found, and comparing it with the current level is
72 no use, due to the order of stack. */
73 static int float_active = 0;
75 /* Unsetting escape_html blindly causes text inside @html/etc. to be escaped if
76 used within a rmacro. */
77 static int raw_output_block = 0;
79 /* Non-zero if a <dl> element has a <dt> element in it. We use this when
80 deciding whether to insert a <br> or not. */
81 static int html_deflist_has_term = 0;
83 void
84 init_insertion_stack (void)
86 insertion_stack = NULL;
89 /* Return the type of the current insertion. */
90 static enum insertion_type
91 current_insertion_type (void)
93 return insertion_level ? insertion_stack->insertion : bad_type;
96 /* Return the string which is the function to wrap around items, or NULL
97 if we're not in an environment where @item is ok. */
98 static char *
99 current_item_function (void)
101 int done = 0;
102 INSERTION_ELT *elt = insertion_stack;
104 /* Skip down through the stack until we find an insertion with an
105 itemize function defined, i.e., skip conditionals, @cartouche, etc. */
106 while (!done && elt)
108 switch (elt->insertion)
110 /* This list should match the one in cm_item. */
111 case ifclear:
112 case ifhtml:
113 case ifinfo:
114 case ifnothtml:
115 case ifnotinfo:
116 case ifnotplaintext:
117 case ifnottex:
118 case ifnotxml:
119 case ifplaintext:
120 case ifset:
121 case iftex:
122 case ifxml:
123 case rawdocbook:
124 case rawhtml:
125 case rawxml:
126 case rawtex:
127 case tex:
128 case cartouche:
129 elt = elt->next;
130 break;
132 default:
133 done = 1;
137 /* item_function usually gets assigned the empty string. */
138 return done && (*elt->item_function) ? elt->item_function : NULL;
141 /* Parse the item marker function off the input. If result is just "@",
142 change it to "@ ", since "@" by itself is not a command. This makes
143 "@ ", "@\t", and "@\n" all the same, but their default meanings are
144 the same anyway, and let's not worry about supporting redefining them. */
145 static char *
146 get_item_function (void)
148 char *item_function;
149 char *item_loc;
151 get_rest_of_line (0, &item_function);
153 /* If the document erroneously says
154 @itemize @bullet @item foobar
155 it's nicer to give an error up front than repeat `@bullet expected
156 braces' until we get a segmentation fault. */
157 item_loc = strstr (item_function, "@item");
158 if (item_loc)
160 line_error (_("@item not allowed in argument to @itemize"));
161 *item_loc = 0;
164 /* If we hit the end of text in get_rest_of_line, backing up
165 input pointer will cause the last character of the last line
166 be pushed back onto the input, which is wrong. */
167 if (input_text_offset < input_text_length)
168 backup_input_pointer ();
170 if (STREQ (item_function, "@"))
172 free (item_function);
173 item_function = xstrdup ("@ ");
176 return item_function;
179 /* Push the state of the current insertion on the stack. */
180 static void
181 push_insertion (enum insertion_type type, char *item_function)
183 INSERTION_ELT *new = xmalloc (sizeof (INSERTION_ELT));
185 new->item_function = item_function;
186 new->filling_enabled = filling_enabled;
187 new->indented_fill = indented_fill;
188 new->insertion = type;
189 new->line_number = line_number;
190 new->filename = xstrdup (input_filename);
191 new->inhibited = inhibit_paragraph_indentation;
192 new->in_fixed_width_font = in_fixed_width_font;
193 new->next = insertion_stack;
194 insertion_stack = new;
195 insertion_level++;
198 /* Pop the value on top of the insertion stack into the
199 global variables. */
200 void
201 pop_insertion (void)
203 INSERTION_ELT *temp = insertion_stack;
205 if (temp == NULL)
206 return;
208 in_fixed_width_font = temp->in_fixed_width_font;
209 inhibit_paragraph_indentation = temp->inhibited;
210 filling_enabled = temp->filling_enabled;
211 indented_fill = temp->indented_fill;
212 free_and_clear (&(temp->item_function));
213 free_and_clear (&(temp->filename));
214 insertion_stack = insertion_stack->next;
215 free (temp);
216 insertion_level--;
219 /* Return a pointer to the print name of this
220 enumerated type. */
221 static const char *
222 insertion_type_pname (enum insertion_type type)
224 if ((int) type < (int) bad_type)
226 if (type == rawdocbook)
227 return "docbook";
228 else if (type == rawhtml)
229 return "html";
230 else if (type == rawxml)
231 return "xml";
232 else if (type == rawtex)
233 return "tex";
234 else
235 return insertion_type_names[(int) type];
237 else
238 return _("Broken-Type in insertion_type_pname");
241 /* Return the insertion_type associated with NAME.
242 If the type is not one of the known ones, return BAD_TYPE. */
243 enum insertion_type
244 find_type_from_name (char *name)
246 int index = 0;
247 while (index < (int) bad_type)
249 if (STREQ (name, insertion_type_names[index]))
250 return (enum insertion_type) index;
251 if (index == rawdocbook && STREQ (name, "docbook"))
252 return rawdocbook;
253 if (index == rawhtml && STREQ (name, "html"))
254 return rawhtml;
255 if (index == rawxml && STREQ (name, "xml"))
256 return rawxml;
257 if (index == rawtex && STREQ (name, "tex"))
258 return rawtex;
259 index++;
261 return bad_type;
264 /* Simple function to query insertion_stack to see if we are inside a given
265 insertion type. */
267 is_in_insertion_of_type (int type)
269 INSERTION_ELT *temp = insertion_stack;
271 if (!insertion_level)
272 return 0;
274 while (temp)
276 if (temp->insertion == type)
277 return 1;
278 temp = temp->next;
281 return 0;
285 static int
286 defun_insertion (enum insertion_type type)
288 return 0
289 || (type == defcv)
290 || (type == deffn)
291 || (type == defivar)
292 || (type == defmac)
293 || (type == defmethod)
294 || (type == defop)
295 || (type == defopt)
296 || (type == defspec)
297 || (type == deftp)
298 || (type == deftypecv)
299 || (type == deftypefn)
300 || (type == deftypefun)
301 || (type == deftypeivar)
302 || (type == deftypemethod)
303 || (type == deftypeop)
304 || (type == deftypevar)
305 || (type == deftypevr)
306 || (type == defun)
307 || (type == defvar)
308 || (type == defvr)
312 /* MAX_NS is the maximum nesting level for enumerations. I picked 100
313 which seemed reasonable. This doesn't control the number of items,
314 just the number of nested lists. */
315 #define max_stack_depth 100
316 #define ENUM_DIGITS 1
317 #define ENUM_ALPHA 2
318 typedef struct {
319 int enumtype;
320 int enumval;
321 } DIGIT_ALPHA;
323 DIGIT_ALPHA enumstack[max_stack_depth];
324 int enumstack_offset = 0;
325 int current_enumval = 1;
326 int current_enumtype = ENUM_DIGITS;
327 char *enumeration_arg = NULL;
329 static void
330 start_enumerating (int at, int type)
332 if ((enumstack_offset + 1) == max_stack_depth)
334 line_error (_("Enumeration stack overflow"));
335 return;
337 enumstack[enumstack_offset].enumtype = current_enumtype;
338 enumstack[enumstack_offset].enumval = current_enumval;
339 enumstack_offset++;
340 current_enumval = at;
341 current_enumtype = type;
344 static void
345 stop_enumerating (void)
347 --enumstack_offset;
348 if (enumstack_offset < 0)
349 enumstack_offset = 0;
351 current_enumval = enumstack[enumstack_offset].enumval;
352 current_enumtype = enumstack[enumstack_offset].enumtype;
355 /* Place a letter or digits into the output stream. */
356 static void
357 enumerate_item (void)
359 char temp[10];
361 if (current_enumtype == ENUM_ALPHA)
363 if (current_enumval == ('z' + 1) || current_enumval == ('Z' + 1))
365 current_enumval = ((current_enumval - 1) == 'z' ? 'a' : 'A');
366 warning (_("lettering overflow, restarting at %c"), current_enumval);
368 sprintf (temp, "%c. ", current_enumval);
370 else
371 sprintf (temp, "%d. ", current_enumval);
373 indent (output_column += (current_indent - strlen (temp)));
374 add_word (temp);
375 current_enumval++;
378 static void
379 enum_html (void)
381 char type;
382 int start;
384 if (isdigit (*enumeration_arg))
386 type = '1';
387 start = atoi (enumeration_arg);
389 else if (isupper (*enumeration_arg))
391 type = 'A';
392 start = *enumeration_arg - 'A' + 1;
394 else
396 type = 'a';
397 start = *enumeration_arg - 'a' + 1;
400 add_html_block_elt_args ("<ol type=%c start=%d>\n", type, start);
403 /* Conditionally parse based on the current command name. */
404 void
405 command_name_condition (void)
407 char *discarder = xmalloc (8 + strlen (command));
409 sprintf (discarder, "\n%cend %s", COMMAND_PREFIX, command);
410 discard_until (discarder);
411 discard_until ("\n");
413 free (discarder);
416 /* This is where the work for all the "insertion" style
417 commands is done. A huge switch statement handles the
418 various setups, and generic code is on both sides. */
419 void
420 begin_insertion (enum insertion_type type)
422 int no_discard = 0;
424 if (defun_insertion (type))
426 push_insertion (type, xstrdup (""));
427 no_discard++;
429 else
431 push_insertion (type, get_item_function ());
434 switch (type)
436 case menu:
437 if (!no_headers)
438 close_paragraph ();
440 filling_enabled = no_indent = 0;
441 inhibit_paragraph_indentation = 1;
443 if (html)
445 had_menu_commentary = 1;
447 else if (!no_headers && !xml)
448 add_word ("* Menu:\n");
450 if (xml)
451 xml_insert_element (MENU, START);
452 else
453 in_fixed_width_font++;
455 next_menu_item_number = 1;
456 in_menu++;
457 no_discard++;
458 break;
460 case detailmenu:
461 if (!in_menu)
463 if (!no_headers)
464 close_paragraph ();
466 filling_enabled = no_indent = 0;
467 inhibit_paragraph_indentation = 1;
469 no_discard++;
472 if (xml)
474 xml_insert_element (DETAILMENU, START);
475 skip_whitespace_and_newlines();
477 else
478 in_fixed_width_font++;
480 in_detailmenu++;
481 break;
483 case direntry:
484 close_single_paragraph ();
485 filling_enabled = no_indent = 0;
486 inhibit_paragraph_indentation = 1;
487 insert_string ("START-INFO-DIR-ENTRY\n");
488 break;
490 case documentdescription:
492 char *desc;
493 int start_of_end;
494 int save_fixed_width;
496 discard_until ("\n"); /* ignore the @documentdescription line */
497 start_of_end = get_until ("\n@end documentdescription", &desc);
498 save_fixed_width = in_fixed_width_font;
500 in_fixed_width_font = 0;
501 document_description = expansion (desc, 0);
502 free (desc);
504 in_fixed_width_font = save_fixed_width;
505 input_text_offset = start_of_end; /* go back to the @end to match */
507 break;
509 case copying:
510 /* Save the copying text away for @insertcopying,
511 typically used on the back of the @titlepage (for TeX) and
512 the Top node (for info/html). */
513 if (input_text[input_text_offset] != '\n')
514 discard_until ("\n"); /* ignore remainder of @copying line */
516 input_text_offset = get_until ("\n@end copying", &copying_text);
517 canon_white (copying_text);
519 /* For info, output the copying text right away, so it will end up
520 in the header of the Info file, before the first node, and thus
521 get copied automatically to all the split files. For xml, also
522 output it right away since xml output is never split.
523 For html, we output it specifically in html_output_head.
524 For plain text, there's no way to hide it, so the author must
525 use @insertcopying in the desired location. */
526 if (docbook)
528 if (!xml_in_bookinfo)
530 xml_insert_element (BOOKINFO, START);
531 xml_in_bookinfo = 1;
533 xml_insert_element (LEGALNOTICE, START);
536 if (!html && !no_headers)
537 cm_insert_copying ();
539 if (docbook)
540 xml_insert_element (LEGALNOTICE, END);
542 break;
544 case quotation:
545 /* @quotation does filling (@display doesn't). */
546 if (html)
547 add_html_block_elt ("<blockquote>\n");
548 else
550 /* with close_single_paragraph, we get no blank line above
551 within @copying. */
552 close_paragraph ();
553 last_char_was_newline = no_indent = 0;
554 indented_fill = filling_enabled = 1;
555 inhibit_paragraph_indentation = 1;
557 current_indent += default_indentation_increment;
558 if (xml)
559 xml_insert_quotation (insertion_stack->item_function, START);
560 else if (strlen(insertion_stack->item_function))
561 execute_string ("@b{%s:} ", insertion_stack->item_function);
562 break;
564 case example:
565 case smallexample:
566 case lisp:
567 case smalllisp:
568 in_fixed_width_font++;
569 /* fall through */
571 /* Like @example but no fixed width font. */
572 case display:
573 case smalldisplay:
574 /* Like @display but without indentation. */
575 case smallformat:
576 case format:
577 close_single_paragraph ();
578 inhibit_paragraph_indentation = 1;
579 filling_enabled = 0;
580 last_char_was_newline = 0;
582 if (html)
583 /* Kludge alert: if <pre> is followed by a newline, IE3,
584 mozilla, maybe others render an extra blank line before the
585 pre-formatted block. So don't output a newline. */
586 add_html_block_elt_args ("<pre class=\"%s\">", command);
588 if (type != format && type != smallformat)
590 current_indent += example_indentation_increment;
591 if (html)
593 /* Since we didn't put \n after <pre>, we need to insert
594 the indentation by hand. */
595 int i;
596 for (i = current_indent; i > 0; i--)
597 add_char (' ');
600 break;
602 case multitable:
603 do_multitable ();
604 break;
606 case table:
607 case ftable:
608 case vtable:
609 case itemize:
610 close_single_paragraph ();
611 current_indent += default_indentation_increment;
612 filling_enabled = indented_fill = 1;
613 #if defined (INDENT_PARAGRAPHS_IN_TABLE)
614 inhibit_paragraph_indentation = 0;
615 #else
616 inhibit_paragraph_indentation = 1;
617 #endif /* !INDENT_PARAGRAPHS_IN_TABLE */
619 /* Make things work for losers who forget the itemize syntax. */
620 if (type == itemize)
622 if (!(*insertion_stack->item_function))
624 free (insertion_stack->item_function);
625 insertion_stack->item_function = xstrdup ("@bullet");
629 if (!*insertion_stack->item_function)
631 line_error (_("%s requires an argument: the formatter for %citem"),
632 insertion_type_pname (type), COMMAND_PREFIX);
635 if (html)
637 if (type == itemize)
639 add_html_block_elt ("<ul>\n");
640 in_paragraph = 0;
642 else
643 { /* We are just starting, so this <dl>
644 has no <dt> children yet. */
645 html_deflist_has_term = 0;
646 add_html_block_elt ("<dl>\n");
649 if (xml)
650 xml_begin_table (type, insertion_stack->item_function);
652 while (input_text[input_text_offset] == '\n'
653 && input_text[input_text_offset+1] == '\n')
655 line_number++;
656 input_text_offset++;
659 break;
661 case enumerate:
662 close_single_paragraph ();
663 no_indent = 0;
664 #if defined (INDENT_PARAGRAPHS_IN_TABLE)
665 inhibit_paragraph_indentation = 0;
666 #else
667 inhibit_paragraph_indentation = 1;
668 #endif /* !INDENT_PARAGRAPHS_IN_TABLE */
670 current_indent += default_indentation_increment;
671 filling_enabled = indented_fill = 1;
673 if (html)
675 enum_html ();
676 in_paragraph = 0;
679 if (xml)
680 xml_begin_enumerate (enumeration_arg);
682 if (isdigit (*enumeration_arg))
683 start_enumerating (atoi (enumeration_arg), ENUM_DIGITS);
684 else
685 start_enumerating (*enumeration_arg, ENUM_ALPHA);
686 break;
688 /* @group produces no output in info. */
689 case group:
690 /* Only close the paragraph if we are not inside of an
691 @example-like environment. */
692 if (xml)
693 xml_insert_element (GROUP, START);
694 else if (!insertion_stack->next
695 || (insertion_stack->next->insertion != display
696 && insertion_stack->next->insertion != smalldisplay
697 && insertion_stack->next->insertion != example
698 && insertion_stack->next->insertion != smallexample
699 && insertion_stack->next->insertion != lisp
700 && insertion_stack->next->insertion != smalllisp
701 && insertion_stack->next->insertion != format
702 && insertion_stack->next->insertion != smallformat
703 && insertion_stack->next->insertion != flushleft
704 && insertion_stack->next->insertion != flushright))
705 close_single_paragraph ();
706 break;
708 case cartouche:
709 if (html)
710 add_html_block_elt ("<p><table class=\"cartouche\" summary=\"cartouche\" border=\"1\"><tr><td>\n");
711 if (in_menu)
712 no_discard++;
713 break;
715 case floatenv:
716 /* Cannot nest floats, so complain. */
717 if (float_active)
719 line_error (_("%cfloat environments cannot be nested"), COMMAND_PREFIX);
720 pop_insertion ();
721 break;
724 float_active++;
726 { /* Collect data about this float. */
727 /* Example: @float [FLOATTYPE][,XREFLABEL][,POSITION] */
728 char floattype[200] = "";
729 char xreflabel[200] = "";
730 char position[200] = "";
731 char *text;
732 char *caption;
733 char *shortcaption;
734 int start_of_end;
735 int save_line_number = line_number;
736 int save_input_text_offset = input_text_offset;
737 int i;
739 if (strlen (insertion_stack->item_function) > 0)
741 int i = 0, t = 0, c = 0;
742 while (insertion_stack->item_function[i])
744 if (insertion_stack->item_function[i] == ',')
746 switch (t)
748 case 0:
749 floattype[c] = '\0';
750 break;
751 case 1:
752 xreflabel[c] = '\0';
753 break;
754 case 2:
755 position[c] = '\0';
756 break;
758 c = 0;
759 t++;
760 i++;
761 continue;
764 switch (t)
766 case 0:
767 floattype[c] = insertion_stack->item_function[i];
768 break;
769 case 1:
770 xreflabel[c] = insertion_stack->item_function[i];
771 break;
772 case 2:
773 position[c] = insertion_stack->item_function[i];
774 break;
776 c++;
777 i++;
781 skip_whitespace_and_newlines ();
783 start_of_end = get_until ("\n@end float", &text);
785 /* Get also the @caption. */
786 i = search_forward_until_pos ("\n@caption{",
787 save_input_text_offset, start_of_end);
788 if (i > -1)
790 input_text_offset = i + sizeof ("\n@caption{") - 1;
791 get_until_in_braces ("\n@end float", &caption);
792 input_text_offset = save_input_text_offset;
794 else
795 caption = "";
797 /* ... and the @shortcaption. */
798 i = search_forward_until_pos ("\n@shortcaption{",
799 save_input_text_offset, start_of_end);
800 if (i > -1)
802 input_text_offset = i + sizeof ("\n@shortcaption{") - 1;
803 get_until_in_braces ("\n@end float", &shortcaption);
804 input_text_offset = save_input_text_offset;
806 else
807 shortcaption = "";
809 canon_white (xreflabel);
810 canon_white (floattype);
811 canon_white (position);
812 canon_white (caption);
813 canon_white (shortcaption);
815 add_new_float (xstrdup (xreflabel),
816 xstrdup (caption), xstrdup (shortcaption),
817 xstrdup (floattype), xstrdup (position));
819 /* Move to the start of the @float so the contents get processed as
820 usual. */
821 input_text_offset = save_input_text_offset;
822 line_number = save_line_number;
825 if (html)
826 add_html_block_elt ("<div class=\"float\">\n");
827 else if (docbook)
828 xml_insert_element (FLOAT, START);
829 else if (xml)
831 xml_insert_element_with_attribute (FLOAT, START,
832 "name=\"%s\"", current_float_id ());
834 xml_insert_element (FLOATTYPE, START);
835 execute_string ("%s", current_float_type ());
836 xml_insert_element (FLOATTYPE, END);
838 xml_insert_element (FLOATPOS, START);
839 execute_string ("%s", current_float_position ());
840 xml_insert_element (FLOATPOS, END);
842 else
843 { /* Info */
844 close_single_paragraph ();
845 inhibit_paragraph_indentation = 1;
848 /* Anchor now. Note that XML documents get their
849 anchors with <float name="anchor"> tag. */
850 if ((!xml || docbook) && strlen (current_float_id ()) > 0)
851 execute_string ("@anchor{%s}", current_float_id ());
853 break;
855 /* Insertions that are no-ops in info, but do something in TeX. */
856 case ifclear:
857 case ifdocbook:
858 case ifhtml:
859 case ifinfo:
860 case ifnotdocbook:
861 case ifnothtml:
862 case ifnotinfo:
863 case ifnotplaintext:
864 case ifnottex:
865 case ifnotxml:
866 case ifplaintext:
867 case ifset:
868 case iftex:
869 case ifxml:
870 case rawtex:
871 if (in_menu)
872 no_discard++;
873 break;
875 case rawdocbook:
876 case rawhtml:
877 case rawxml:
878 raw_output_block++;
880 if (raw_output_block > 0)
882 xml_no_para = 1;
883 escape_html = 0;
884 xml_keep_space++;
888 /* Some deuglification for improved readability. */
889 extern int xml_in_para;
890 if (xml && !xml_in_para && xml_indentation_increment > 0)
891 add_char ('\n');
894 break;
896 case defcv:
897 case deffn:
898 case defivar:
899 case defmac:
900 case defmethod:
901 case defop:
902 case defopt:
903 case defspec:
904 case deftp:
905 case deftypecv:
906 case deftypefn:
907 case deftypefun:
908 case deftypeivar:
909 case deftypemethod:
910 case deftypeop:
911 case deftypevar:
912 case deftypevr:
913 case defun:
914 case defvar:
915 case defvr:
916 inhibit_paragraph_indentation = 1;
917 filling_enabled = indented_fill = 1;
918 current_indent += default_indentation_increment;
919 no_indent = 0;
920 if (xml)
921 xml_begin_definition ();
922 break;
924 case flushleft:
925 close_single_paragraph ();
926 inhibit_paragraph_indentation = 1;
927 filling_enabled = indented_fill = no_indent = 0;
928 if (html)
929 add_html_block_elt ("<div align=\"left\">");
930 break;
932 case flushright:
933 close_single_paragraph ();
934 filling_enabled = indented_fill = no_indent = 0;
935 inhibit_paragraph_indentation = 1;
936 force_flush_right++;
937 if (html)
938 add_html_block_elt ("<div align=\"right\">");
939 break;
941 case titlepage:
942 xml_insert_element (TITLEPAGE, START);
943 break;
945 default:
946 line_error ("begin_insertion internal error: type=%d", type);
949 if (!no_discard)
950 discard_until ("\n");
953 /* Try to end the insertion with the specified TYPE. With a value of
954 `bad_type', TYPE gets translated to match the value currently on top
955 of the stack. Otherwise, if TYPE doesn't match the top of the
956 insertion stack, give error. */
957 static void
958 end_insertion (int type)
960 int temp_type;
962 if (!insertion_level)
963 return;
965 temp_type = current_insertion_type ();
967 if (type == bad_type)
968 type = temp_type;
970 if (type != temp_type)
972 line_error
973 (_("`@end' expected `%s', but saw `%s'"),
974 insertion_type_pname (temp_type), insertion_type_pname (type));
975 return;
978 pop_insertion ();
980 if (xml)
982 switch (type)
984 case ifinfo:
985 case documentdescription:
986 break;
987 case quotation:
988 xml_insert_quotation ("", END);
989 break;
990 case example:
991 xml_insert_element (EXAMPLE, END);
992 if (docbook && current_insertion_type () == floatenv)
993 xml_insert_element (FLOATEXAMPLE, END);
994 break;
995 case smallexample:
996 xml_insert_element (SMALLEXAMPLE, END);
997 if (docbook && current_insertion_type () == floatenv)
998 xml_insert_element (FLOATEXAMPLE, END);
999 break;
1000 case lisp:
1001 xml_insert_element (LISP, END);
1002 if (docbook && current_insertion_type () == floatenv)
1003 xml_insert_element (FLOATEXAMPLE, END);
1004 break;
1005 case smalllisp:
1006 xml_insert_element (SMALLLISP, END);
1007 if (docbook && current_insertion_type () == floatenv)
1008 xml_insert_element (FLOATEXAMPLE, END);
1009 break;
1010 case cartouche:
1011 xml_insert_element (CARTOUCHE, END);
1012 break;
1013 case format:
1014 if (docbook && xml_in_bookinfo && xml_in_abstract)
1016 xml_insert_element (ABSTRACT, END);
1017 xml_in_abstract = 0;
1019 else
1020 xml_insert_element (FORMAT, END);
1021 break;
1022 case smallformat:
1023 xml_insert_element (SMALLFORMAT, END);
1024 break;
1025 case display:
1026 xml_insert_element (DISPLAY, END);
1027 break;
1028 case smalldisplay:
1029 xml_insert_element (SMALLDISPLAY, END);
1030 break;
1031 case table:
1032 case ftable:
1033 case vtable:
1034 case itemize:
1035 xml_end_table (type);
1036 break;
1037 case enumerate:
1038 xml_end_enumerate ();
1039 break;
1040 case group:
1041 xml_insert_element (GROUP, END);
1042 break;
1043 case titlepage:
1044 xml_insert_element (TITLEPAGE, END);
1045 break;
1048 switch (type)
1050 /* Insertions which have no effect on paragraph formatting. */
1051 case copying:
1052 line_number--;
1053 break;
1055 case ifclear:
1056 case ifdocbook:
1057 case ifinfo:
1058 case ifhtml:
1059 case ifnotdocbook:
1060 case ifnothtml:
1061 case ifnotinfo:
1062 case ifnotplaintext:
1063 case ifnottex:
1064 case ifnotxml:
1065 case ifplaintext:
1066 case ifset:
1067 case iftex:
1068 case ifxml:
1069 case rawtex:
1070 case titlepage:
1071 break;
1073 case rawdocbook:
1074 case rawhtml:
1075 case rawxml:
1076 raw_output_block--;
1078 if (raw_output_block <= 0)
1080 xml_no_para = 0;
1081 escape_html = 1;
1082 xml_keep_space--;
1085 if ((xml || html) && output_paragraph[output_paragraph_offset-1] == '\n')
1086 output_paragraph_offset--;
1087 break;
1089 case detailmenu:
1090 if (xml)
1091 xml_insert_element (DETAILMENU, END);
1093 in_detailmenu--; /* No longer hacking menus. */
1094 if (!in_menu)
1096 if (!no_headers)
1097 close_insertion_paragraph ();
1099 break;
1101 case direntry: /* Eaten if html. */
1102 insert_string ("END-INFO-DIR-ENTRY\n\n");
1103 close_insertion_paragraph ();
1104 break;
1106 case documentdescription:
1107 if (xml)
1108 insert_string (document_description);
1109 xml_insert_element (DOCUMENTDESCRIPTION, END);
1110 break;
1112 case menu:
1113 in_menu--; /* No longer hacking menus. */
1114 if (html && !no_headers)
1115 add_html_block_elt ("</ul>\n");
1116 else if (!no_headers && !xml)
1117 close_insertion_paragraph ();
1118 break;
1120 case multitable:
1121 end_multitable ();
1122 break;
1124 case enumerate:
1125 stop_enumerating ();
1126 close_insertion_paragraph ();
1127 current_indent -= default_indentation_increment;
1128 if (html)
1129 add_html_block_elt ("</ol>\n");
1130 break;
1132 case flushleft:
1133 if (html)
1134 add_html_block_elt ("</div>\n");
1135 close_insertion_paragraph ();
1136 break;
1138 case cartouche:
1139 if (html)
1140 add_html_block_elt ("</td></tr></table>\n");
1141 close_insertion_paragraph ();
1142 break;
1144 case group:
1145 if (!xml || docbook)
1146 close_insertion_paragraph ();
1147 break;
1149 case floatenv:
1150 if (xml)
1151 xml_insert_element (FLOAT, END);
1152 else
1154 if (html)
1155 add_html_block_elt ("<p><strong class=\"float-caption\">");
1156 else
1157 close_paragraph ();
1159 no_indent = 1;
1161 /* Legend:
1162 1) @float Foo,lbl & no caption: Foo 1.1
1163 2) @float Foo & no caption: Foo
1164 3) @float ,lbl & no caption: 1.1
1165 4) @float & no caption: */
1167 if (!xml && !html)
1168 indent (current_indent);
1170 if (strlen (current_float_type ()))
1171 execute_string ("%s", current_float_type ());
1173 if (strlen (current_float_id ()) > 0)
1175 if (strlen (current_float_type ()) > 0)
1176 add_char (' ');
1178 add_word (current_float_number ());
1181 if (strlen (current_float_title ()) > 0)
1183 if (strlen (current_float_type ()) > 0
1184 || strlen (current_float_id ()) > 0)
1185 insert_string (": ");
1187 execute_string ("%s", current_float_title ());
1190 /* Indent the following paragraph. */
1191 inhibit_paragraph_indentation = 0;
1193 if (html)
1194 add_word ("</strong></p></div>\n");
1195 else
1196 close_paragraph ();
1198 float_active--;
1199 break;
1201 case format:
1202 case smallformat:
1203 case display:
1204 case smalldisplay:
1205 case example:
1206 case smallexample:
1207 case lisp:
1208 case smalllisp:
1209 case quotation:
1210 /* @format and @smallformat are the only fixed_width insertion
1211 without a change in indentation. */
1212 if (type != format && type != smallformat && type != quotation)
1213 current_indent -= example_indentation_increment;
1214 else if (type == quotation)
1215 current_indent -= default_indentation_increment;
1217 if (html)
1218 { /* The complex code in close_paragraph that kills whitespace
1219 does not function here, since we've inserted non-whitespace
1220 (the </whatever>) before it. The indentation already got
1221 inserted at the end of the last example line, so we have to
1222 delete it, or browsers wind up showing an extra blank line. */
1223 kill_self_indent (default_indentation_increment);
1224 add_html_block_elt (type == quotation
1225 ? "</blockquote>\n" : "</pre>\n");
1228 /* The ending of one of these insertions always marks the
1229 start of a new paragraph, except for the XML output. */
1230 if (!xml || docbook)
1231 close_insertion_paragraph ();
1233 /* </pre> closes paragraph without messing with </p>. */
1234 if (html && type != quotation)
1235 paragraph_is_open = 0;
1236 break;
1238 case table:
1239 case ftable:
1240 case vtable:
1241 current_indent -= default_indentation_increment;
1242 if (html)
1243 add_html_block_elt ("</dl>\n");
1244 close_insertion_paragraph ();
1245 break;
1247 case itemize:
1248 current_indent -= default_indentation_increment;
1249 if (html)
1250 add_html_block_elt ("</ul>\n");
1251 close_insertion_paragraph ();
1252 break;
1254 case flushright:
1255 force_flush_right--;
1256 if (html)
1257 add_html_block_elt ("</div>\n");
1258 close_insertion_paragraph ();
1259 break;
1261 /* Handle the @defun insertions with this default clause. */
1262 default:
1264 int base_type;
1266 if (type < defcv || type > defvr)
1267 line_error ("end_insertion internal error: type=%d", type);
1269 base_type = get_base_type (type);
1270 switch (base_type)
1272 case deffn:
1273 case defvr:
1274 case deftp:
1275 case deftypecv:
1276 case deftypefn:
1277 case deftypevr:
1278 case defcv:
1279 case defop:
1280 case deftypemethod:
1281 case deftypeop:
1282 case deftypeivar:
1283 if (html)
1285 if (paragraph_is_open)
1286 add_html_block_elt ("</p>");
1287 /* close the div and blockquote which has been opened in defun.c */
1288 if (!rollback_empty_tag ("blockquote"))
1289 add_html_block_elt ("</blockquote>");
1290 add_html_block_elt ("</div>\n");
1292 if (xml)
1293 xml_end_definition ();
1294 break;
1295 } /* switch (base_type)... */
1297 current_indent -= default_indentation_increment;
1298 close_insertion_paragraph ();
1300 break;
1304 if (current_indent < 0)
1305 line_error ("end_insertion internal error: current indent=%d",
1306 current_indent);
1309 /* Insertions cannot cross certain boundaries, such as node beginnings. In
1310 code that creates such boundaries, you should call `discard_insertions'
1311 before doing anything else. It prints the errors for you, and cleans up
1312 the insertion stack.
1314 With nonzero SPECIALS_OK argument, allows unmatched
1315 @if... conditionals, otherwise not. This is because conditionals can
1316 cross node boundaries. Always happens with the @top node, for example. */
1317 void
1318 discard_insertions (int specials_ok)
1320 int real_line_number = line_number;
1321 while (insertion_stack)
1323 if (specials_ok
1324 && ((ifclear <= insertion_stack->insertion
1325 && insertion_stack->insertion <= iftex)
1326 || insertion_stack->insertion == rawdocbook
1327 || insertion_stack->insertion == rawhtml
1328 || insertion_stack->insertion == rawxml
1329 || insertion_stack->insertion == rawtex))
1330 break;
1331 else
1333 const char *offender = insertion_type_pname (insertion_stack->insertion);
1335 file_line_error (insertion_stack->filename,
1336 insertion_stack->line_number,
1337 _("No matching `%cend %s'"), COMMAND_PREFIX,
1338 offender);
1339 pop_insertion ();
1342 line_number = real_line_number;
1345 /* Insertion (environment) commands. */
1347 void
1348 cm_quotation (void)
1350 /* We start the blockquote element in the insertion. */
1351 begin_insertion (quotation);
1354 void
1355 cm_example (void)
1357 if (docbook && current_insertion_type () == floatenv)
1358 xml_begin_docbook_float (FLOATEXAMPLE);
1360 if (xml)
1362 /* Rollback previous newlines. These occur between
1363 </para> and <example>. */
1364 if (output_paragraph[output_paragraph_offset-1] == '\n')
1365 output_paragraph_offset--;
1367 xml_insert_element (EXAMPLE, START);
1369 /* Make sure example text is starting on a new line
1370 for improved readability. */
1371 if (docbook)
1372 add_char ('\n');
1375 begin_insertion (example);
1378 void
1379 cm_smallexample (void)
1381 if (docbook && current_insertion_type () == floatenv)
1382 xml_begin_docbook_float (FLOATEXAMPLE);
1384 if (xml)
1386 /* See cm_example comments about newlines. */
1387 if (output_paragraph[output_paragraph_offset-1] == '\n')
1388 output_paragraph_offset--;
1389 xml_insert_element (SMALLEXAMPLE, START);
1390 if (docbook)
1391 add_char ('\n');
1394 begin_insertion (smallexample);
1397 void
1398 cm_lisp (void)
1400 if (docbook && current_insertion_type () == floatenv)
1401 xml_begin_docbook_float (FLOATEXAMPLE);
1403 if (xml)
1405 /* See cm_example comments about newlines. */
1406 if (output_paragraph[output_paragraph_offset-1] == '\n')
1407 output_paragraph_offset--;
1408 xml_insert_element (LISP, START);
1409 if (docbook)
1410 add_char ('\n');
1413 begin_insertion (lisp);
1416 void
1417 cm_smalllisp (void)
1419 if (docbook && current_insertion_type () == floatenv)
1420 xml_begin_docbook_float (FLOATEXAMPLE);
1422 if (xml)
1424 /* See cm_example comments about newlines. */
1425 if (output_paragraph[output_paragraph_offset-1] == '\n')
1426 output_paragraph_offset--;
1427 xml_insert_element (SMALLLISP, START);
1428 if (docbook)
1429 add_char ('\n');
1432 begin_insertion (smalllisp);
1435 void
1436 cm_cartouche (void)
1438 if (docbook && current_insertion_type () == floatenv)
1439 xml_begin_docbook_float (CARTOUCHE);
1441 if (xml)
1442 xml_insert_element (CARTOUCHE, START);
1443 begin_insertion (cartouche);
1446 void
1447 cm_copying (void)
1449 begin_insertion (copying);
1452 /* Not an insertion, despite the name, but it goes with cm_copying. */
1453 void
1454 cm_insert_copying (void)
1456 if (!copying_text)
1458 warning ("@copying not used before %s", command);
1459 return;
1462 execute_string ("%s", copying_text);
1464 if (!xml && !html)
1466 add_word ("\n\n");
1467 /* Update output_position so that the node positions in the tag
1468 tables will take account of the copying text. */
1469 flush_output ();
1473 void
1474 cm_format (void)
1476 if (xml)
1478 if (docbook && xml_in_bookinfo)
1480 xml_insert_element (ABSTRACT, START);
1481 xml_in_abstract = 1;
1483 else
1485 /* See cm_example comments about newlines. */
1486 if (output_paragraph[output_paragraph_offset-1] == '\n')
1487 output_paragraph_offset--;
1488 xml_insert_element (FORMAT, START);
1489 if (docbook)
1490 add_char ('\n');
1493 begin_insertion (format);
1496 void
1497 cm_smallformat (void)
1499 if (xml)
1501 /* See cm_example comments about newlines. */
1502 if (output_paragraph[output_paragraph_offset-1] == '\n')
1503 output_paragraph_offset--;
1504 xml_insert_element (SMALLFORMAT, START);
1505 if (docbook)
1506 add_char ('\n');
1509 begin_insertion (smallformat);
1512 void
1513 cm_display (void)
1515 if (xml)
1517 /* See cm_example comments about newlines. */
1518 if (output_paragraph[output_paragraph_offset-1] == '\n')
1519 output_paragraph_offset--;
1520 xml_insert_element (DISPLAY, START);
1521 if (docbook)
1522 add_char ('\n');
1525 begin_insertion (display);
1528 void
1529 cm_smalldisplay (void)
1531 if (xml)
1533 /* See cm_example comments about newlines. */
1534 if (output_paragraph[output_paragraph_offset-1] == '\n')
1535 output_paragraph_offset--;
1536 xml_insert_element (SMALLDISPLAY, START);
1537 if (docbook)
1538 add_char ('\n');
1541 begin_insertion (smalldisplay);
1544 void
1545 cm_direntry (void)
1547 if (html || xml || no_headers)
1548 command_name_condition ();
1549 else
1550 begin_insertion (direntry);
1553 void
1554 cm_documentdescription (void)
1556 if (html)
1557 begin_insertion (documentdescription);
1559 else if (xml)
1561 xml_insert_element (DOCUMENTDESCRIPTION, START);
1562 begin_insertion (documentdescription);
1565 else
1566 command_name_condition ();
1570 void
1571 cm_itemize (void)
1573 begin_insertion (itemize);
1576 /* Start an enumeration insertion of type TYPE. If the user supplied
1577 no argument on the line, then use DEFAULT_STRING as the initial string. */
1578 static void
1579 do_enumeration (int type, char *default_string)
1581 get_until_in_line (0, ".", &enumeration_arg);
1582 canon_white (enumeration_arg);
1584 if (!*enumeration_arg)
1586 free (enumeration_arg);
1587 enumeration_arg = xstrdup (default_string);
1590 if (!isdigit (*enumeration_arg) && !isletter (*enumeration_arg))
1592 warning (_("%s requires letter or digit"), insertion_type_pname (type));
1594 switch (type)
1596 case enumerate:
1597 default_string = "1";
1598 break;
1600 enumeration_arg = xstrdup (default_string);
1602 begin_insertion (type);
1605 void
1606 cm_enumerate (void)
1608 do_enumeration (enumerate, "1");
1611 /* Handle verbatim environment:
1612 find_end_verbatim == 0: process until end of file
1613 find_end_verbatim != 0: process until 'COMMAND_PREFIXend verbatim'
1614 or end of file
1616 We cannot simply copy input stream onto output stream; as the
1617 verbatim environment may be encapsulated in an @example environment,
1618 for example. */
1619 void
1620 handle_verbatim_environment (int find_end_verbatim)
1622 int character;
1623 int seen_end = 0;
1624 int save_filling_enabled = filling_enabled;
1625 int save_inhibit_paragraph_indentation = inhibit_paragraph_indentation;
1626 int save_escape_html = escape_html;
1628 if (!insertion_stack)
1629 close_single_paragraph (); /* no blank lines if not at outer level */
1630 inhibit_paragraph_indentation = 1;
1631 filling_enabled = 0;
1632 in_fixed_width_font++;
1633 last_char_was_newline = 0;
1635 /* No indentation: this is verbatim after all
1636 If you want indent, enclose @verbatim in @example
1637 current_indent += default_indentation_increment;
1640 if (html)
1641 { /* If inside @example, we'll be preceded by the indentation
1642 already. Browsers will ignore those spaces because we're about
1643 to start another <pre> (don't ask me). So, wipe them out for
1644 cleanliness, and re-insert. */
1645 int i;
1646 kill_self_indent (default_indentation_increment);
1647 add_html_block_elt ("<pre class=\"verbatim\">");
1648 for (i = current_indent; i > 0; i--)
1649 add_char (' ');
1651 else if (xml)
1653 xml_insert_element (VERBATIM, START);
1654 escape_html = 0;
1655 add_word ("<![CDATA[");
1658 while (input_text_offset < input_text_length)
1660 character = curchar ();
1662 if (character == '\n')
1663 line_number++;
1665 /* Assume no newlines in END_VERBATIM. */
1666 else if (find_end_verbatim && (character == COMMAND_PREFIX) /* @ */
1667 && (input_text_length - input_text_offset > sizeof (END_VERBATIM))
1668 && !strncmp (&input_text[input_text_offset+1], END_VERBATIM,
1669 sizeof (END_VERBATIM)-1))
1671 input_text_offset += sizeof (END_VERBATIM);
1672 seen_end = 1;
1673 break;
1676 if (html && character == '&' && escape_html)
1677 add_word ("&amp;");
1678 else if (html && character == '<' && escape_html)
1679 add_word ("&lt;");
1680 else
1681 add_char (character);
1683 input_text_offset++;
1686 if (find_end_verbatim && !seen_end)
1687 warning (_("end of file inside verbatim block"));
1689 if (html)
1690 { /* See comments in example case above. */
1691 kill_self_indent (default_indentation_increment);
1692 add_word ("</pre>");
1694 else if (xml)
1696 add_word ("]]>");
1697 xml_insert_element (VERBATIM, END);
1698 escape_html = save_escape_html;
1701 in_fixed_width_font--;
1702 filling_enabled = save_filling_enabled;
1703 inhibit_paragraph_indentation = save_inhibit_paragraph_indentation;
1706 void
1707 cm_verbatim (void)
1709 handle_verbatim_environment (1);
1712 void
1713 cm_table (void)
1715 begin_insertion (table);
1718 void
1719 cm_multitable (void)
1721 begin_insertion (multitable); /* @@ */
1724 void
1725 cm_ftable (void)
1727 begin_insertion (ftable);
1730 void
1731 cm_vtable (void)
1733 begin_insertion (vtable);
1736 void
1737 cm_group (void)
1739 begin_insertion (group);
1742 /* Insert raw HTML (no escaping of `<' etc.). */
1743 void
1744 cm_html (int arg)
1746 if (process_html)
1747 begin_insertion (rawhtml);
1748 else
1749 command_name_condition ();
1752 void
1753 cm_xml (int arg)
1755 if (process_xml)
1756 begin_insertion (rawxml);
1757 else
1758 command_name_condition ();
1761 void
1762 cm_docbook (int arg)
1764 if (process_docbook)
1765 begin_insertion (rawdocbook);
1766 else
1767 command_name_condition ();
1770 void
1771 cm_ifdocbook (void)
1773 if (process_docbook)
1774 begin_insertion (ifdocbook);
1775 else
1776 command_name_condition ();
1779 void
1780 cm_ifnotdocbook (void)
1782 if (!process_docbook)
1783 begin_insertion (ifnotdocbook);
1784 else
1785 command_name_condition ();
1788 void
1789 cm_ifhtml (void)
1791 if (process_html)
1792 begin_insertion (ifhtml);
1793 else
1794 command_name_condition ();
1797 void
1798 cm_ifnothtml (void)
1800 if (!process_html)
1801 begin_insertion (ifnothtml);
1802 else
1803 command_name_condition ();
1807 void
1808 cm_ifinfo (void)
1810 if (process_info)
1811 begin_insertion (ifinfo);
1812 else
1813 command_name_condition ();
1816 void
1817 cm_ifnotinfo (void)
1819 if (!process_info)
1820 begin_insertion (ifnotinfo);
1821 else
1822 command_name_condition ();
1826 void
1827 cm_ifplaintext (void)
1829 if (process_plaintext)
1830 begin_insertion (ifplaintext);
1831 else
1832 command_name_condition ();
1835 void
1836 cm_ifnotplaintext (void)
1838 if (!process_plaintext)
1839 begin_insertion (ifnotplaintext);
1840 else
1841 command_name_condition ();
1845 void
1846 cm_tex (void)
1848 if (process_tex)
1849 begin_insertion (rawtex);
1850 else
1851 command_name_condition ();
1854 void
1855 cm_iftex (void)
1857 if (process_tex)
1858 begin_insertion (iftex);
1859 else
1860 command_name_condition ();
1863 void
1864 cm_ifnottex (void)
1866 if (!process_tex)
1867 begin_insertion (ifnottex);
1868 else
1869 command_name_condition ();
1872 void
1873 cm_ifxml (void)
1875 if (process_xml)
1876 begin_insertion (ifxml);
1877 else
1878 command_name_condition ();
1881 void
1882 cm_ifnotxml (void)
1884 if (!process_xml)
1885 begin_insertion (ifnotxml);
1886 else
1887 command_name_condition ();
1891 /* Generic xrefable block with a caption. */
1892 void
1893 cm_float (void)
1895 begin_insertion (floatenv);
1898 void
1899 cm_caption (int arg)
1901 char *temp;
1903 /* This is a no_op command for most formats, as we handle it during @float
1904 insertion. For XML though, we handle it here to keep document structure
1905 as close as possible, to the Texinfo source. */
1907 /* Everything is already handled at START. */
1908 if (arg == END)
1909 return;
1911 /* Check if it's mislocated. */
1912 if (current_insertion_type () != floatenv)
1913 line_error (_("@%s not meaningful outside `@float' environment"), command);
1915 get_until_in_braces ("\n@end float", &temp);
1917 if (xml)
1919 int elt = STREQ (command, "shortcaption") ? SHORTCAPTION : CAPTION;
1920 xml_insert_element (elt, START);
1921 if (!docbook)
1922 execute_string ("%s", temp);
1923 xml_insert_element (elt, END);
1926 free (temp);
1929 /* Begin an insertion where the lines are not filled or indented. */
1930 void
1931 cm_flushleft (void)
1933 begin_insertion (flushleft);
1936 /* Begin an insertion where the lines are not filled, and each line is
1937 forced to the right-hand side of the page. */
1938 void
1939 cm_flushright (void)
1941 begin_insertion (flushright);
1944 void
1945 cm_menu (void)
1947 if (current_node == NULL && !macro_expansion_output_stream)
1949 warning (_("@menu seen before first @node, creating `Top' node"));
1950 warning (_("perhaps your @top node should be wrapped in @ifnottex rather than @ifinfo?"));
1951 /* Include @top command so we can construct the implicit node tree. */
1952 execute_string ("@node top\n@top Top\n");
1954 begin_insertion (menu);
1957 void
1958 cm_detailmenu (void)
1960 if (current_node == NULL && !macro_expansion_output_stream)
1961 { /* Problems anyway, @detailmenu should always be inside @menu. */
1962 warning (_("@detailmenu seen before first node, creating `Top' node"));
1963 execute_string ("@node top\n@top Top\n");
1965 begin_insertion (detailmenu);
1968 /* Title page commands. */
1970 void
1971 cm_titlepage (void)
1973 titlepage_cmd_present = 1;
1974 if (xml && !docbook)
1975 begin_insertion (titlepage);
1976 else
1977 command_name_condition ();
1980 void
1981 cm_author (void)
1983 char *rest;
1984 get_rest_of_line (1, &rest);
1986 if (is_in_insertion_of_type (quotation))
1988 if (html)
1989 add_word_args ("&mdash; %s", rest);
1990 else if (docbook)
1992 /* FIXME Ideally, we should use an attribution element,
1993 but they are supposed to be at the start of quotation
1994 blocks. So to avoid looking ahead mess, let's just
1995 use mdash like HTML for now. */
1996 xml_insert_entity ("mdash");
1997 add_word (rest);
1999 else if (xml)
2001 xml_insert_element (AUTHOR, START);
2002 add_word (rest);
2003 xml_insert_element (AUTHOR, END);
2005 else
2006 add_word_args ("-- %s", rest);
2008 else if (is_in_insertion_of_type (titlepage))
2010 if (xml && !docbook)
2012 xml_insert_element (AUTHOR, START);
2013 add_word (rest);
2014 xml_insert_element (AUTHOR, END);
2017 else
2018 line_error (_("@%s not meaningful outside `@titlepage' and `@quotation' environments"),
2019 command);
2021 free (rest);
2024 void
2025 cm_titlepage_cmds (void)
2027 char *rest;
2029 get_rest_of_line (1, &rest);
2031 if (!is_in_insertion_of_type (titlepage))
2032 line_error (_("@%s not meaningful outside `@titlepage' environment"),
2033 command);
2035 if (xml && !docbook)
2037 int elt = 0;
2039 if (STREQ (command, "title"))
2040 elt = BOOKTITLE;
2041 else if (STREQ (command, "subtitle"))
2042 elt = BOOKSUBTITLE;
2044 xml_insert_element (elt, START);
2045 add_word (rest);
2046 xml_insert_element (elt, END);
2049 free (rest);
2052 /* End existing insertion block. */
2053 void
2054 cm_end (void)
2056 char *temp;
2057 int type;
2059 get_rest_of_line (0, &temp);
2061 if (!insertion_level)
2063 line_error (_("Unmatched `%c%s'"), COMMAND_PREFIX, command);
2064 return;
2067 if (temp[0] == 0)
2068 line_error (_("`%c%s' needs something after it"), COMMAND_PREFIX, command);
2070 type = find_type_from_name (temp);
2072 if (type == bad_type)
2074 line_error (_("Bad argument `%s' to `@%s', using `%s'"),
2075 temp, command, insertion_type_pname (current_insertion_type ()));
2077 if (xml && type == menu) /* fixme */
2079 xml_end_menu ();
2081 end_insertion (type);
2082 free (temp);
2085 /* @itemx, @item. */
2087 static int itemx_flag = 0;
2089 /* Return whether CMD takes a brace-delimited {arg}. */
2091 command_needs_braces (char *cmd)
2093 int i;
2094 for (i = 0; command_table[i].name; i++)
2096 if (STREQ (command_table[i].name, cmd))
2097 return command_table[i].argument_in_braces == BRACE_ARGS;
2100 return 0; /* macro or alias */
2104 void
2105 cm_item (void)
2107 char *rest_of_line, *item_func;
2109 /* Can only hack "@item" while inside of an insertion. */
2110 if (insertion_level)
2112 INSERTION_ELT *stack = insertion_stack;
2113 int original_input_text_offset;
2115 skip_whitespace ();
2116 original_input_text_offset = input_text_offset;
2118 get_rest_of_line (0, &rest_of_line);
2119 item_func = current_item_function ();
2121 /* Do the right thing depending on which insertion function is active. */
2122 switch_top:
2123 switch (stack->insertion)
2125 case multitable:
2126 multitable_item ();
2127 /* Support text directly after the @item. */
2128 if (*rest_of_line)
2130 line_number--;
2131 input_text_offset = original_input_text_offset;
2133 break;
2135 case ifclear:
2136 case ifhtml:
2137 case ifinfo:
2138 case ifnothtml:
2139 case ifnotinfo:
2140 case ifnotplaintext:
2141 case ifnottex:
2142 case ifnotxml:
2143 case ifplaintext:
2144 case ifset:
2145 case iftex:
2146 case ifxml:
2147 case rawdocbook:
2148 case rawhtml:
2149 case rawxml:
2150 case rawtex:
2151 case tex:
2152 case cartouche:
2153 stack = stack->next;
2154 if (!stack)
2155 goto no_insertion;
2156 else
2157 goto switch_top;
2158 break;
2160 case menu:
2161 case quotation:
2162 case example:
2163 case smallexample:
2164 case lisp:
2165 case smalllisp:
2166 case format:
2167 case smallformat:
2168 case display:
2169 case smalldisplay:
2170 case group:
2171 line_error (_("@%s not meaningful inside `@%s' block"),
2172 command,
2173 insertion_type_pname (current_insertion_type ()));
2174 break;
2176 case itemize:
2177 case enumerate:
2178 if (itemx_flag)
2180 line_error (_("@itemx not meaningful inside `%s' block"),
2181 insertion_type_pname (current_insertion_type ()));
2183 else
2185 if (html)
2186 add_html_block_elt ("<li>");
2187 else if (xml)
2188 xml_begin_item ();
2189 else
2191 start_paragraph ();
2192 kill_self_indent (-1);
2193 filling_enabled = indented_fill = 1;
2195 if (current_item_function ())
2197 output_column = current_indent - 2;
2198 indent (output_column);
2200 /* The item marker can be given with or without
2201 braces -- @bullet and @bullet{} are both ok.
2202 Or it might be something that doesn't take
2203 braces at all, such as "o" or "#" or "@ ".
2204 Thus, only supply braces if the item marker is
2205 a command, they haven't supplied braces
2206 themselves, and we know it needs them. */
2207 if (item_func && *item_func)
2209 if (*item_func == COMMAND_PREFIX
2210 && item_func[strlen (item_func) - 1] != '}'
2211 && command_needs_braces (item_func + 1))
2212 execute_string ("%s{}", item_func);
2213 else
2214 execute_string ("%s", item_func);
2216 insert (' ');
2217 output_column++;
2219 else
2220 enumerate_item ();
2222 /* Special hack. This makes `close_paragraph' a no-op until
2223 `start_paragraph' has been called. */
2224 must_start_paragraph = 1;
2227 /* Handle text directly after the @item. */
2228 if (*rest_of_line)
2230 line_number--;
2231 input_text_offset = original_input_text_offset;
2234 break;
2236 case table:
2237 case ftable:
2238 case vtable:
2239 if (html)
2240 { /* If nothing has been output since the last <dd>,
2241 remove the empty <dd> element. Some browsers render
2242 an extra empty line for <dd><dt>, which makes @itemx
2243 conversion look ugly. */
2244 rollback_empty_tag ("dd");
2246 /* Force the browser to render one blank line before
2247 each new @item in a table. But don't do that if
2248 this is the first <dt> after the <dl>, or if we are
2249 converting @itemx.
2251 Note that there are some browsers which ignore <br>
2252 in this context, but I cannot find any way to force
2253 them all render exactly one blank line. */
2254 if (!itemx_flag && html_deflist_has_term)
2255 add_html_block_elt ("<br>");
2257 /* We are about to insert a <dt>, so this <dl> has a term.
2258 Feel free to insert a <br> next time. :) */
2259 html_deflist_has_term = 1;
2261 add_html_block_elt ("<dt>");
2262 if (item_func && *item_func)
2263 execute_string ("%s{%s}", item_func, rest_of_line);
2264 else
2265 execute_string ("%s", rest_of_line);
2267 if (current_insertion_type () == ftable)
2268 execute_string ("%cfindex %s\n", COMMAND_PREFIX, rest_of_line);
2270 if (current_insertion_type () == vtable)
2271 execute_string ("%cvindex %s\n", COMMAND_PREFIX, rest_of_line);
2273 add_html_block_elt ("<dd>");
2275 else if (xml) /* && docbook)*/ /* 05-08 */
2277 xml_begin_table_item ();
2279 if (!docbook && current_insertion_type () == ftable)
2280 execute_string ("%cfindex %s\n", COMMAND_PREFIX, rest_of_line);
2282 if (!docbook && current_insertion_type () == vtable)
2283 execute_string ("%cvindex %s\n", COMMAND_PREFIX, rest_of_line);
2285 if (item_func && *item_func)
2286 execute_string ("%s{%s}", item_func, rest_of_line);
2287 else
2288 execute_string ("%s", rest_of_line);
2289 xml_continue_table_item ();
2291 else
2293 /* We need this to determine if we have two @item's in a row
2294 (see test just below). */
2295 static int last_item_output_position = 0;
2297 /* Get rid of extra characters. */
2298 kill_self_indent (-1);
2300 /* If we have one @item followed directly by another @item,
2301 we need to insert a blank line. This is not true for
2302 @itemx, though. */
2303 if (!itemx_flag && last_item_output_position == output_position)
2304 insert ('\n');
2306 /* `close_paragraph' almost does what we want. The problem
2307 is when paragraph_is_open, and last_char_was_newline, and
2308 the last newline has been turned into a space, because
2309 filling_enabled. I handle it here. */
2310 if (last_char_was_newline && filling_enabled &&
2311 paragraph_is_open)
2312 insert ('\n');
2313 close_paragraph ();
2315 #if defined (INDENT_PARAGRAPHS_IN_TABLE)
2316 /* Indent on a new line, but back up one indentation level. */
2318 int save = inhibit_paragraph_indentation;
2319 inhibit_paragraph_indentation = 1;
2320 /* At this point, inserting any non-whitespace character will
2321 force the existing indentation to be output. */
2322 add_char ('i');
2323 inhibit_paragraph_indentation = save;
2325 #else /* !INDENT_PARAGRAPHS_IN_TABLE */
2326 add_char ('i');
2327 #endif /* !INDENT_PARAGRAPHS_IN_TABLE */
2329 output_paragraph_offset--;
2330 kill_self_indent (default_indentation_increment + 1);
2332 /* Add item's argument to the line. */
2333 filling_enabled = 0;
2334 if (item_func && *item_func)
2335 execute_string ("%s{%s}", item_func, rest_of_line);
2336 else
2337 execute_string ("%s", rest_of_line);
2339 if (current_insertion_type () == ftable)
2340 execute_string ("%cfindex %s\n", COMMAND_PREFIX, rest_of_line);
2341 else if (current_insertion_type () == vtable)
2342 execute_string ("%cvindex %s\n", COMMAND_PREFIX, rest_of_line);
2344 /* Start a new line, and let start_paragraph ()
2345 do the indenting of it for you. */
2346 close_single_paragraph ();
2347 indented_fill = filling_enabled = 1;
2348 last_item_output_position = output_position;
2351 free (rest_of_line);
2353 else
2355 no_insertion:
2356 line_error (_("%c%s found outside of an insertion block"),
2357 COMMAND_PREFIX, command);
2361 void
2362 cm_itemx (void)
2364 itemx_flag++;
2365 cm_item ();
2366 itemx_flag--;
2369 int headitem_flag = 0;
2371 void
2372 cm_headitem (void)
2374 headitem_flag = 1;
2375 cm_item ();