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
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)
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. */
26 #include "insertion.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. */
65 /* Set to 1 if <p> is written in normal context.
66 Used for menu and itemize. */
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;
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. */
99 current_item_function (void)
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. */
108 switch (elt
->insertion
)
110 /* This list should match the one in cm_item. */
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. */
146 get_item_function (void)
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");
160 line_error (_("@item not allowed in argument to @itemize"));
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. */
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;
198 /* Pop the value on top of the insertion stack into the
203 INSERTION_ELT
*temp
= insertion_stack
;
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
;
219 /* Return a pointer to the print name of this
222 insertion_type_pname (enum insertion_type type
)
224 if ((int) type
< (int) bad_type
)
226 if (type
== rawdocbook
)
228 else if (type
== rawhtml
)
230 else if (type
== rawxml
)
232 else if (type
== rawtex
)
235 return insertion_type_names
[(int) type
];
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. */
244 find_type_from_name (char *name
)
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"))
253 if (index
== rawhtml
&& STREQ (name
, "html"))
255 if (index
== rawxml
&& STREQ (name
, "xml"))
257 if (index
== rawtex
&& STREQ (name
, "tex"))
264 /* Simple function to query insertion_stack to see if we are inside a given
267 is_in_insertion_of_type (int type
)
269 INSERTION_ELT
*temp
= insertion_stack
;
271 if (!insertion_level
)
276 if (temp
->insertion
== type
)
286 defun_insertion (enum insertion_type type
)
293 || (type
== defmethod
)
298 || (type
== deftypecv
)
299 || (type
== deftypefn
)
300 || (type
== deftypefun
)
301 || (type
== deftypeivar
)
302 || (type
== deftypemethod
)
303 || (type
== deftypeop
)
304 || (type
== deftypevar
)
305 || (type
== deftypevr
)
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
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
;
330 start_enumerating (int at
, int type
)
332 if ((enumstack_offset
+ 1) == max_stack_depth
)
334 line_error (_("Enumeration stack overflow"));
337 enumstack
[enumstack_offset
].enumtype
= current_enumtype
;
338 enumstack
[enumstack_offset
].enumval
= current_enumval
;
340 current_enumval
= at
;
341 current_enumtype
= type
;
345 stop_enumerating (void)
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. */
357 enumerate_item (void)
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
);
371 sprintf (temp
, "%d. ", current_enumval
);
373 indent (output_column
+= (current_indent
- strlen (temp
)));
384 if (isdigit (*enumeration_arg
))
387 start
= atoi (enumeration_arg
);
389 else if (isupper (*enumeration_arg
))
392 start
= *enumeration_arg
- 'A' + 1;
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. */
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");
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. */
420 begin_insertion (enum insertion_type type
)
424 if (defun_insertion (type
))
426 push_insertion (type
, xstrdup (""));
431 push_insertion (type
, get_item_function ());
440 filling_enabled
= no_indent
= 0;
441 inhibit_paragraph_indentation
= 1;
445 had_menu_commentary
= 1;
447 else if (!no_headers
&& !xml
)
448 add_word ("* Menu:\n");
451 xml_insert_element (MENU
, START
);
453 in_fixed_width_font
++;
455 next_menu_item_number
= 1;
466 filling_enabled
= no_indent
= 0;
467 inhibit_paragraph_indentation
= 1;
474 xml_insert_element (DETAILMENU
, START
);
475 skip_whitespace_and_newlines();
478 in_fixed_width_font
++;
484 close_single_paragraph ();
485 filling_enabled
= no_indent
= 0;
486 inhibit_paragraph_indentation
= 1;
487 insert_string ("START-INFO-DIR-ENTRY\n");
490 case documentdescription
:
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);
504 in_fixed_width_font
= save_fixed_width
;
505 input_text_offset
= start_of_end
; /* go back to the @end to match */
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", ©ing_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. */
528 if (!xml_in_bookinfo
)
530 xml_insert_element (BOOKINFO
, START
);
533 xml_insert_element (LEGALNOTICE
, START
);
536 if (!html
&& !no_headers
)
537 cm_insert_copying ();
540 xml_insert_element (LEGALNOTICE
, END
);
545 /* @quotation does filling (@display doesn't). */
547 add_html_block_elt ("<blockquote>\n");
550 /* with close_single_paragraph, we get no blank line above
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
;
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
);
568 in_fixed_width_font
++;
571 /* Like @example but no fixed width font. */
574 /* Like @display but without indentation. */
577 close_single_paragraph ();
578 inhibit_paragraph_indentation
= 1;
580 last_char_was_newline
= 0;
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
;
593 /* Since we didn't put \n after <pre>, we need to insert
594 the indentation by hand. */
596 for (i
= current_indent
; i
> 0; i
--)
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;
616 inhibit_paragraph_indentation
= 1;
617 #endif /* !INDENT_PARAGRAPHS_IN_TABLE */
619 /* Make things work for losers who forget the itemize syntax. */
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
);
639 add_html_block_elt ("<ul>\n");
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");
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')
662 close_single_paragraph ();
664 #if defined (INDENT_PARAGRAPHS_IN_TABLE)
665 inhibit_paragraph_indentation
= 0;
667 inhibit_paragraph_indentation
= 1;
668 #endif /* !INDENT_PARAGRAPHS_IN_TABLE */
670 current_indent
+= default_indentation_increment
;
671 filling_enabled
= indented_fill
= 1;
680 xml_begin_enumerate (enumeration_arg
);
682 if (isdigit (*enumeration_arg
))
683 start_enumerating (atoi (enumeration_arg
), ENUM_DIGITS
);
685 start_enumerating (*enumeration_arg
, ENUM_ALPHA
);
688 /* @group produces no output in info. */
690 /* Only close the paragraph if we are not inside of an
691 @example-like environment. */
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 ();
710 add_html_block_elt ("<p><table class=\"cartouche\" summary=\"cartouche\" border=\"1\"><tr><td>\n");
716 /* Cannot nest floats, so complain. */
719 line_error (_("%cfloat environments cannot be nested"), COMMAND_PREFIX
);
726 { /* Collect data about this float. */
727 /* Example: @float [FLOATTYPE][,XREFLABEL][,POSITION] */
728 char floattype
[200] = "";
729 char xreflabel
[200] = "";
730 char position
[200] = "";
735 int save_line_number
= line_number
;
736 int save_input_text_offset
= input_text_offset
;
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
] == ',')
767 floattype
[c
] = insertion_stack
->item_function
[i
];
770 xreflabel
[c
] = insertion_stack
->item_function
[i
];
773 position
[c
] = insertion_stack
->item_function
[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
);
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
;
797 /* ... and the @shortcaption. */
798 i
= search_forward_until_pos ("\n@shortcaption{",
799 save_input_text_offset
, start_of_end
);
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
;
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
821 input_text_offset
= save_input_text_offset
;
822 line_number
= save_line_number
;
826 add_html_block_elt ("<div class=\"float\">\n");
828 xml_insert_element (FLOAT
, START
);
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
);
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 ());
855 /* Insertions that are no-ops in info, but do something in TeX. */
880 if (raw_output_block
> 0)
888 /* Some deuglification for improved readability. */
889 extern int xml_in_para
;
890 if (xml
&& !xml_in_para
&& xml_indentation_increment
> 0)
916 inhibit_paragraph_indentation
= 1;
917 filling_enabled
= indented_fill
= 1;
918 current_indent
+= default_indentation_increment
;
921 xml_begin_definition ();
925 close_single_paragraph ();
926 inhibit_paragraph_indentation
= 1;
927 filling_enabled
= indented_fill
= no_indent
= 0;
929 add_html_block_elt ("<div align=\"left\">");
933 close_single_paragraph ();
934 filling_enabled
= indented_fill
= no_indent
= 0;
935 inhibit_paragraph_indentation
= 1;
938 add_html_block_elt ("<div align=\"right\">");
942 xml_insert_element (TITLEPAGE
, START
);
946 line_error ("begin_insertion internal error: type=%d", type
);
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. */
958 end_insertion (int type
)
962 if (!insertion_level
)
965 temp_type
= current_insertion_type ();
967 if (type
== bad_type
)
970 if (type
!= temp_type
)
973 (_("`@end' expected `%s', but saw `%s'"),
974 insertion_type_pname (temp_type
), insertion_type_pname (type
));
985 case documentdescription
:
988 xml_insert_quotation ("", END
);
991 xml_insert_element (EXAMPLE
, END
);
992 if (docbook
&& current_insertion_type () == floatenv
)
993 xml_insert_element (FLOATEXAMPLE
, END
);
996 xml_insert_element (SMALLEXAMPLE
, END
);
997 if (docbook
&& current_insertion_type () == floatenv
)
998 xml_insert_element (FLOATEXAMPLE
, END
);
1001 xml_insert_element (LISP
, END
);
1002 if (docbook
&& current_insertion_type () == floatenv
)
1003 xml_insert_element (FLOATEXAMPLE
, END
);
1006 xml_insert_element (SMALLLISP
, END
);
1007 if (docbook
&& current_insertion_type () == floatenv
)
1008 xml_insert_element (FLOATEXAMPLE
, END
);
1011 xml_insert_element (CARTOUCHE
, END
);
1014 if (docbook
&& xml_in_bookinfo
&& xml_in_abstract
)
1016 xml_insert_element (ABSTRACT
, END
);
1017 xml_in_abstract
= 0;
1020 xml_insert_element (FORMAT
, END
);
1023 xml_insert_element (SMALLFORMAT
, END
);
1026 xml_insert_element (DISPLAY
, END
);
1029 xml_insert_element (SMALLDISPLAY
, END
);
1035 xml_end_table (type
);
1038 xml_end_enumerate ();
1041 xml_insert_element (GROUP
, END
);
1044 xml_insert_element (TITLEPAGE
, END
);
1050 /* Insertions which have no effect on paragraph formatting. */
1062 case ifnotplaintext
:
1078 if (raw_output_block
<= 0)
1085 if ((xml
|| html
) && output_paragraph
[output_paragraph_offset
-1] == '\n')
1086 output_paragraph_offset
--;
1091 xml_insert_element (DETAILMENU
, END
);
1093 in_detailmenu
--; /* No longer hacking menus. */
1097 close_insertion_paragraph ();
1101 case direntry
: /* Eaten if html. */
1102 insert_string ("END-INFO-DIR-ENTRY\n\n");
1103 close_insertion_paragraph ();
1106 case documentdescription
:
1108 insert_string (document_description
);
1109 xml_insert_element (DOCUMENTDESCRIPTION
, END
);
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 ();
1125 stop_enumerating ();
1126 close_insertion_paragraph ();
1127 current_indent
-= default_indentation_increment
;
1129 add_html_block_elt ("</ol>\n");
1134 add_html_block_elt ("</div>\n");
1135 close_insertion_paragraph ();
1140 add_html_block_elt ("</td></tr></table>\n");
1141 close_insertion_paragraph ();
1145 if (!xml
|| docbook
)
1146 close_insertion_paragraph ();
1151 xml_insert_element (FLOAT
, END
);
1155 add_html_block_elt ("<p><strong class=\"float-caption\">");
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: */
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)
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;
1194 add_word ("</strong></p></div>\n");
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
;
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;
1241 current_indent
-= default_indentation_increment
;
1243 add_html_block_elt ("</dl>\n");
1244 close_insertion_paragraph ();
1248 current_indent
-= default_indentation_increment
;
1250 add_html_block_elt ("</ul>\n");
1251 close_insertion_paragraph ();
1255 force_flush_right
--;
1257 add_html_block_elt ("</div>\n");
1258 close_insertion_paragraph ();
1261 /* Handle the @defun insertions with this default clause. */
1266 if (type
< defcv
|| type
> defvr
)
1267 line_error ("end_insertion internal error: type=%d", type
);
1269 base_type
= get_base_type (type
);
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");
1293 xml_end_definition ();
1295 } /* switch (base_type)... */
1297 current_indent
-= default_indentation_increment
;
1298 close_insertion_paragraph ();
1304 if (current_indent
< 0)
1305 line_error ("end_insertion internal error: current indent=%d",
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. */
1318 discard_insertions (int specials_ok
)
1320 int real_line_number
= line_number
;
1321 while (insertion_stack
)
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
))
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
,
1342 line_number
= real_line_number
;
1345 /* Insertion (environment) commands. */
1350 /* We start the blockquote element in the insertion. */
1351 begin_insertion (quotation
);
1357 if (docbook
&& current_insertion_type () == floatenv
)
1358 xml_begin_docbook_float (FLOATEXAMPLE
);
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. */
1375 begin_insertion (example
);
1379 cm_smallexample (void)
1381 if (docbook
&& current_insertion_type () == floatenv
)
1382 xml_begin_docbook_float (FLOATEXAMPLE
);
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
);
1394 begin_insertion (smallexample
);
1400 if (docbook
&& current_insertion_type () == floatenv
)
1401 xml_begin_docbook_float (FLOATEXAMPLE
);
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
);
1413 begin_insertion (lisp
);
1419 if (docbook
&& current_insertion_type () == floatenv
)
1420 xml_begin_docbook_float (FLOATEXAMPLE
);
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
);
1432 begin_insertion (smalllisp
);
1438 if (docbook
&& current_insertion_type () == floatenv
)
1439 xml_begin_docbook_float (CARTOUCHE
);
1442 xml_insert_element (CARTOUCHE
, START
);
1443 begin_insertion (cartouche
);
1449 begin_insertion (copying
);
1452 /* Not an insertion, despite the name, but it goes with cm_copying. */
1454 cm_insert_copying (void)
1458 warning ("@copying not used before %s", command
);
1462 execute_string ("%s", copying_text
);
1467 /* Update output_position so that the node positions in the tag
1468 tables will take account of the copying text. */
1478 if (docbook
&& xml_in_bookinfo
)
1480 xml_insert_element (ABSTRACT
, START
);
1481 xml_in_abstract
= 1;
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
);
1493 begin_insertion (format
);
1497 cm_smallformat (void)
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
);
1509 begin_insertion (smallformat
);
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
);
1525 begin_insertion (display
);
1529 cm_smalldisplay (void)
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
);
1541 begin_insertion (smalldisplay
);
1547 if (html
|| xml
|| no_headers
)
1548 command_name_condition ();
1550 begin_insertion (direntry
);
1554 cm_documentdescription (void)
1557 begin_insertion (documentdescription
);
1561 xml_insert_element (DOCUMENTDESCRIPTION
, START
);
1562 begin_insertion (documentdescription
);
1566 command_name_condition ();
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. */
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
));
1597 default_string
= "1";
1600 enumeration_arg
= xstrdup (default_string
);
1602 begin_insertion (type
);
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'
1616 We cannot simply copy input stream onto output stream; as the
1617 verbatim environment may be encapsulated in an @example environment,
1620 handle_verbatim_environment (int find_end_verbatim
)
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;
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. */
1646 kill_self_indent (default_indentation_increment
);
1647 add_html_block_elt ("<pre class=\"verbatim\">");
1648 for (i
= current_indent
; i
> 0; i
--)
1653 xml_insert_element (VERBATIM
, START
);
1655 add_word ("<![CDATA[");
1658 while (input_text_offset
< input_text_length
)
1660 character
= curchar ();
1662 if (character
== '\n')
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
);
1676 if (html
&& character
== '&' && escape_html
)
1678 else if (html
&& character
== '<' && escape_html
)
1681 add_char (character
);
1683 input_text_offset
++;
1686 if (find_end_verbatim
&& !seen_end
)
1687 warning (_("end of file inside verbatim block"));
1690 { /* See comments in example case above. */
1691 kill_self_indent (default_indentation_increment
);
1692 add_word ("</pre>");
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
;
1709 handle_verbatim_environment (1);
1715 begin_insertion (table
);
1719 cm_multitable (void)
1721 begin_insertion (multitable
); /* @@ */
1727 begin_insertion (ftable
);
1733 begin_insertion (vtable
);
1739 begin_insertion (group
);
1742 /* Insert raw HTML (no escaping of `<' etc.). */
1747 begin_insertion (rawhtml
);
1749 command_name_condition ();
1756 begin_insertion (rawxml
);
1758 command_name_condition ();
1762 cm_docbook (int arg
)
1764 if (process_docbook
)
1765 begin_insertion (rawdocbook
);
1767 command_name_condition ();
1773 if (process_docbook
)
1774 begin_insertion (ifdocbook
);
1776 command_name_condition ();
1780 cm_ifnotdocbook (void)
1782 if (!process_docbook
)
1783 begin_insertion (ifnotdocbook
);
1785 command_name_condition ();
1792 begin_insertion (ifhtml
);
1794 command_name_condition ();
1801 begin_insertion (ifnothtml
);
1803 command_name_condition ();
1811 begin_insertion (ifinfo
);
1813 command_name_condition ();
1820 begin_insertion (ifnotinfo
);
1822 command_name_condition ();
1827 cm_ifplaintext (void)
1829 if (process_plaintext
)
1830 begin_insertion (ifplaintext
);
1832 command_name_condition ();
1836 cm_ifnotplaintext (void)
1838 if (!process_plaintext
)
1839 begin_insertion (ifnotplaintext
);
1841 command_name_condition ();
1849 begin_insertion (rawtex
);
1851 command_name_condition ();
1858 begin_insertion (iftex
);
1860 command_name_condition ();
1867 begin_insertion (ifnottex
);
1869 command_name_condition ();
1876 begin_insertion (ifxml
);
1878 command_name_condition ();
1885 begin_insertion (ifnotxml
);
1887 command_name_condition ();
1891 /* Generic xrefable block with a caption. */
1895 begin_insertion (floatenv
);
1899 cm_caption (int arg
)
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. */
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
);
1919 int elt
= STREQ (command
, "shortcaption") ? SHORTCAPTION
: CAPTION
;
1920 xml_insert_element (elt
, START
);
1922 execute_string ("%s", temp
);
1923 xml_insert_element (elt
, END
);
1929 /* Begin an insertion where the lines are not filled or indented. */
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. */
1939 cm_flushright (void)
1941 begin_insertion (flushright
);
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
);
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. */
1973 titlepage_cmd_present
= 1;
1974 if (xml
&& !docbook
)
1975 begin_insertion (titlepage
);
1977 command_name_condition ();
1984 get_rest_of_line (1, &rest
);
1986 if (is_in_insertion_of_type (quotation
))
1989 add_word_args ("— %s", rest
);
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");
2001 xml_insert_element (AUTHOR
, START
);
2003 xml_insert_element (AUTHOR
, END
);
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
);
2014 xml_insert_element (AUTHOR
, END
);
2018 line_error (_("@%s not meaningful outside `@titlepage' and `@quotation' environments"),
2025 cm_titlepage_cmds (void)
2029 get_rest_of_line (1, &rest
);
2031 if (!is_in_insertion_of_type (titlepage
))
2032 line_error (_("@%s not meaningful outside `@titlepage' environment"),
2035 if (xml
&& !docbook
)
2039 if (STREQ (command
, "title"))
2041 else if (STREQ (command
, "subtitle"))
2044 xml_insert_element (elt
, START
);
2046 xml_insert_element (elt
, END
);
2052 /* End existing insertion block. */
2059 get_rest_of_line (0, &temp
);
2061 if (!insertion_level
)
2063 line_error (_("Unmatched `%c%s'"), COMMAND_PREFIX
, command
);
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 */
2081 end_insertion (type
);
2085 /* @itemx, @item. */
2087 static int itemx_flag
= 0;
2089 /* Return whether CMD takes a brace-delimited {arg}. */
2091 command_needs_braces (char *cmd
)
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 */
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
;
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. */
2123 switch (stack
->insertion
)
2127 /* Support text directly after the @item. */
2131 input_text_offset
= original_input_text_offset
;
2140 case ifnotplaintext
:
2153 stack
= stack
->next
;
2171 line_error (_("@%s not meaningful inside `@%s' block"),
2173 insertion_type_pname (current_insertion_type ()));
2180 line_error (_("@itemx not meaningful inside `%s' block"),
2181 insertion_type_pname (current_insertion_type ()));
2186 add_html_block_elt ("<li>");
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
);
2214 execute_string ("%s", item_func
);
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. */
2231 input_text_offset
= original_input_text_offset
;
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
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
);
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
);
2288 execute_string ("%s", rest_of_line
);
2289 xml_continue_table_item ();
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
2303 if (!itemx_flag
&& last_item_output_position
== output_position
)
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
&&
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. */
2323 inhibit_paragraph_indentation
= save
;
2325 #else /* !INDENT_PARAGRAPHS_IN_TABLE */
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
);
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
);
2356 line_error (_("%c%s found outside of an insertion block"),
2357 COMMAND_PREFIX
, command
);
2369 int headitem_flag
= 0;