1 /* makeinfo -- convert Texinfo source into other formats.
2 $Id: makeinfo.c,v 1.74 2004/12/19 17:15:42 karl Exp $
4 Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
5 2000, 2001, 2002, 2003, 2004 Free Software 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)
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
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 Original author of makeinfo: Brian Fox (bfox@ai.mit.edu). */
26 #define COMPILING_MAKEINFO
34 #include "insertion.h"
38 #include "sectioning.h"
42 /* You can change some of the behavior of Makeinfo by changing the
45 /* Define INDENT_PARAGRAPHS_IN_TABLE if you want the paragraphs which
46 appear within an @table, @ftable, or @itemize environment to have
47 standard paragraph indentation. Without this, such paragraphs have
48 no starting indentation. */
49 /* #define INDENT_PARAGRAPHS_IN_TABLE */
51 /* Define PARAGRAPH_START_INDENT to be the amount of indentation that
52 the first lines of paragraphs receive by default, where no other
53 value has been specified. Users can change this value on the command
54 line, with the --paragraph-indent option, or within the texinfo file,
55 with the @paragraphindent command. */
56 #define PARAGRAPH_START_INDENT 3
58 /* Define DEFAULT_PARAGRAPH_SPACING as the number of blank lines that you
59 wish to appear between paragraphs. A value of 1 creates a single blank
60 line between paragraphs. Paragraphs are defined by 2 or more consecutive
61 newlines in the input file (i.e., one or more blank lines). */
62 #define DEFAULT_PARAGRAPH_SPACING 1
64 /* Global variables. */
66 /* The output file name. */
67 char *output_filename
= NULL
;
69 /* Name of the output file that the user elected to pass on the command line.
70 Such a name overrides any name found with the @setfilename command. */
71 char *command_output_filename
= NULL
;
72 static char *save_command_output_filename
= NULL
;
74 #define INITIAL_PARAGRAPH_SPACE 5000
75 int paragraph_buffer_len
= INITIAL_PARAGRAPH_SPACE
;
77 /* The amount of indentation to add at the starts of paragraphs.
78 0 means don't change existing indentation at paragraph starts.
79 > 0 is amount to indent new paragraphs by.
80 < 0 means indent to column zero by removing indentation if necessary.
82 This is normally zero, but some people prefer paragraph starts to be
83 somewhat more indented than paragraph bodies. A pretty value for
85 int paragraph_start_indent
= PARAGRAPH_START_INDENT
;
87 /* Indentation that is pending insertion. We have this for hacking lines
88 which look blank, but contain whitespace. We want to treat those as
90 int pending_indent
= 0;
92 /* The index in our internal command table of the currently
96 /* A search string which is used to find the first @setfilename. */
97 char setfilename_search
[] =
99 's', 'e', 't', 'f', 'i', 'l', 'e', 'n', 'a', 'm', 'e', 0 };
101 /* Values for calling handle_variable_internal (). */
107 /* Flags controlling the operation of the program. */
109 /* Default is to remove output if there were errors. */
112 /* Default is to notify users of bad choices. */
113 int print_warnings
= 1;
115 /* Number of errors that we tolerate on a given fileset. */
116 int max_error_level
= 100;
118 /* The actual last inserted character. Note that this may be something
119 other than NEWLINE even if last_char_was_newline is 1. */
120 int last_inserted_character
= 0;
122 /* Nonzero means that a newline character has already been
123 inserted, so close_paragraph () should insert one less. */
124 int line_already_broken
= 0;
126 /* When nonzero we have finished an insertion (see end_insertion ()) and we
127 want to ignore false continued paragraph closings. */
128 int insertion_paragraph_closed
= 0;
130 /* Nonzero means attempt to make all of the lines have fill_column width. */
131 int do_justification
= 0;
133 /* Nonzero means don't replace whitespace with in HTML mode. */
136 /* Nonzero means we are inserting a block level HTML element that must not be
137 enclosed in a <p>, such as <ul>, <ol> and <h?>. */
138 int in_html_block_level_elt
= 0;
140 /* True when expanding a macro definition. */
141 static int executing_macro
= 0;
143 /* True when we are inside a <li> block of a menu. */
144 static int in_menu_item
= 0;
146 typedef struct brace_element
148 struct brace_element
*next
;
149 COMMAND_FUNCTION
*proc
;
152 int in_fixed_width_font
;
155 BRACE_ELEMENT
*brace_stack
= NULL
;
157 static void convert_from_file (char *name
);
158 static void convert_from_loaded_file (char *name
);
159 static void convert_from_stream (FILE *stream
, char *name
);
160 static void do_flush_right_indentation (void);
161 static void handle_variable (int action
);
162 static void handle_variable_internal (int action
, char *name
);
163 static void init_brace_stack (void);
164 static void init_internals (void);
165 static void pop_and_call_brace (void);
166 static void remember_brace (COMMAND_FUNCTION (*proc
));
167 static int end_of_sentence_p (void);
169 void maybe_update_execution_strings (char **text
, unsigned int new_len
);
171 /* Error handling. */
173 /* Number of errors encountered. */
174 int errors_printed
= 0;
176 /* Remember that an error has been printed. If more than
177 max_error_level have been printed, then exit the program. */
179 remember_error (void)
182 if (max_error_level
&& (errors_printed
> max_error_level
))
184 fprintf (stderr
, _("Too many errors! Gave up.\n"));
186 if (errors_printed
- max_error_level
< 2)
192 /* Print the last error gotten from the file system. */
194 fs_error (char *filename
)
201 /* Print an error message, and return false. */
203 #if defined (VA_FPRINTF) && __STDC__
204 error (const char *format
, ...)
206 error (format
, va_alist
)
217 VA_START (ap
, format
);
219 VA_FPRINTF (stderr
, format
, ap
);
221 fprintf (stderr
, format
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
);
222 #endif /* not VA_FPRINTF */
228 /* Just like error (), but print the input file and line number as well. */
230 #if defined (VA_FPRINTF) && __STDC__
231 file_line_error (char *infile
, int lno
, const char *format
, ...)
233 file_line_error (infile
, lno
, format
, va_alist
)
245 fprintf (stderr
, "%s:%d: ", infile
, lno
);
247 VA_START (ap
, format
);
249 VA_FPRINTF (stderr
, format
, ap
);
251 fprintf (stderr
, format
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
);
252 #endif /* not VA_FPRINTF */
255 fprintf (stderr
, ".\n");
258 /* Just like file_line_error (), but take the input file and the line
259 number from global variables. */
261 #if defined (VA_FPRINTF) && __STDC__
262 line_error (const char *format
, ...)
264 line_error (format
, va_alist
)
274 fprintf (stderr
, "%s:%d: ", input_filename
, line_number
);
276 VA_START (ap
, format
);
278 VA_FPRINTF (stderr
, format
, ap
);
280 fprintf (stderr
, format
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
);
281 #endif /* not VA_FPRINTF */
284 fprintf (stderr
, ".\n");
288 #if defined (VA_FPRINTF) && __STDC__
289 warning (const char *format
, ...)
291 warning (format
, va_alist
)
302 fprintf (stderr
, _("%s:%d: warning: "), input_filename
, line_number
);
304 VA_START (ap
, format
);
306 VA_FPRINTF (stderr
, format
, ap
);
308 fprintf (stderr
, format
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
);
309 #endif /* not VA_FPRINTF */
312 fprintf (stderr
, ".\n");
317 /* The other side of a malformed expression. */
319 misplaced_brace (void)
321 line_error (_("Misplaced %c"), '}');
326 /* Display the version info of this invocation of Makeinfo. */
328 print_version_info (void)
330 printf ("makeinfo (GNU %s) %s\n", PACKAGE
, VERSION
);
333 /* If EXIT_VALUE is zero, print the full usage message to stdout.
334 Otherwise, just say to use --help for more info.
335 Then exit with EXIT_VALUE. */
337 usage (int exit_value
)
340 fprintf (stderr
, _("Try `%s --help' for more information.\n"), progname
);
343 printf (_("Usage: %s [OPTION]... TEXINFO-FILE...\n"), progname
);
347 Translate Texinfo source documentation to various other formats, by default\n\
348 Info files suitable for reading online with Emacs or standalone GNU Info.\n"));
352 --error-limit=NUM quit after NUM errors (default %d).\n\
353 --force preserve output even if errors.\n\
354 --help display this help and exit.\n\
355 --no-validate suppress node cross-reference validation.\n\
356 --no-warn suppress warnings (but not errors).\n\
357 --reference-limit=NUM warn about at most NUM references (default %d).\n\
358 -v, --verbose explain what is being done.\n\
359 --version display version information and exit.\n"),
360 max_error_level
, reference_warning_limit
);
363 /* xgettext: no-wrap */
365 Output format selection (default is to produce Info):\n\
366 --docbook output Docbook XML rather than Info.\n\
367 --html output HTML rather than Info.\n\
368 --xml output Texinfo XML rather than Info.\n\
369 --plaintext output plain text rather than Info.\n\
373 General output options:\n\
374 -E, --macro-expand FILE output macro-expanded source to FILE.\n\
375 ignoring any @setfilename.\n\
376 --no-headers suppress node separators, Node: lines, and menus\n\
377 from Info output (thus producing plain text)\n\
378 or from HTML (thus producing shorter output);\n\
379 also, write to standard output by default.\n\
380 --no-split suppress splitting of Info or HTML output,\n\
381 generate only one output file.\n\
382 --number-sections output chapter and sectioning numbers.\n\
383 -o, --output=FILE output to FILE (directory if split HTML),\n\
387 Options for Info and plain text:\n\
388 --enable-encoding output accented and special characters in\n\
389 Info output based on @documentencoding.\n\
390 --fill-column=NUM break Info lines at NUM characters (default %d).\n\
391 --footnote-style=STYLE output footnotes in Info according to STYLE:\n\
392 `separate' to put them in their own node;\n\
393 `end' to put them at the end of the node\n\
394 in which they are defined (default).\n\
395 --paragraph-indent=VAL indent Info paragraphs by VAL spaces (default %d).\n\
396 If VAL is `none', do not indent; if VAL is\n\
397 `asis', preserve existing indentation.\n\
398 --split-size=NUM split Info files at size NUM (default %d).\n"),
399 fill_column
, paragraph_start_indent
,
405 --css-include=FILE include FILE in HTML <style> output;\n\
406 read stdin if FILE is -.\n\
410 Options for XML and Docbook:\n\
411 --output-indent=VAL indent XML elements by VAL spaces (default %d).\n\
412 If VAL is 0, ignorable whitespace is dropped.\n\
413 "), xml_indentation_increment
);
417 Input file options:\n\
418 --commands-in-node-names allow @ commands in node names.\n\
419 -D VAR define the variable VAR, as with @set.\n\
420 -I DIR append DIR to the @include search path.\n\
421 -P DIR prepend DIR to the @include search path.\n\
422 -U VAR undefine the variable VAR, as with @clear.\n\
426 Conditional processing in input:\n\
427 --ifdocbook process @ifdocbook and @docbook even if\n\
428 not generating Docbook.\n\
429 --ifhtml process @ifhtml and @html even if not generating HTML.\n\
430 --ifinfo process @ifinfo even if not generating Info.\n\
431 --ifplaintext process @ifplaintext even if not generating plain text.\n\
432 --iftex process @iftex and @tex; implies --no-split.\n\
433 --ifxml process @ifxml and @xml.\n\
434 --no-ifdocbook do not process @ifdocbook and @docbook text.\n\
435 --no-ifhtml do not process @ifhtml and @html text.\n\
436 --no-ifinfo do not process @ifinfo text.\n\
437 --no-ifplaintext do not process @ifplaintext text.\n\
438 --no-iftex do not process @iftex and @tex text.\n\
439 --no-ifxml do not process @ifxml and @xml text.\n\
441 Also, for the --no-ifFORMAT options, do process @ifnotFORMAT text.\n\
445 The defaults for the @if... conditionals depend on the output format:\n\
446 if generating HTML, --ifhtml is on and the others are off;\n\
447 if generating Info, --ifinfo is on and the others are off;\n\
448 if generating plain text, --ifplaintext is on and the others are off;\n\
449 if generating XML, --ifxml is on and the others are off.\n\
454 makeinfo foo.texi write Info to foo's @setfilename\n\
455 makeinfo --html foo.texi write HTML to @setfilename\n\
456 makeinfo --xml foo.texi write Texinfo XML to @setfilename\n\
457 makeinfo --docbook foo.texi write DocBook XML to @setfilename\n\
458 makeinfo --no-headers foo.texi write plain text to standard output\n\
460 makeinfo --html --no-headers foo.texi write html without node lines, menus\n\
461 makeinfo --number-sections foo.texi write Info with numbered sections\n\
462 makeinfo --no-split foo.texi write one Info file however big\n\
466 Email bug reports to bug-texinfo@gnu.org,\n\
467 general questions and discussion to help-texinfo@gnu.org.\n\
468 Texinfo home page: http://www.gnu.org/software/texinfo/"));
470 } /* end of full help */
475 struct option long_options
[] =
477 { "commands-in-node-names", 0, &expensive_validation
, 1 },
478 { "css-include", 1, 0, 'C' },
479 { "docbook", 0, 0, 'd' },
480 { "enable-encoding", 0, &enable_encoding
, 1 },
481 { "error-limit", 1, 0, 'e' },
482 { "fill-column", 1, 0, 'f' },
483 { "footnote-style", 1, 0, 's' },
484 { "force", 0, &force
, 1 },
485 { "help", 0, 0, 'h' },
486 { "html", 0, 0, 'w' },
487 { "ifdocbook", 0, &process_docbook
, 1 },
488 { "ifhtml", 0, &process_html
, 1 },
489 { "ifinfo", 0, &process_info
, 1 },
490 { "ifplaintext", 0, &process_plaintext
, 1 },
491 { "iftex", 0, &process_tex
, 1 },
492 { "ifxml", 0, &process_xml
, 1 },
493 { "macro-expand", 1, 0, 'E' },
494 { "no-headers", 0, &no_headers
, 1 },
495 { "no-ifdocbook", 0, &process_docbook
, 0 },
496 { "no-ifhtml", 0, &process_html
, 0 },
497 { "no-ifinfo", 0, &process_info
, 0 },
498 { "no-ifplaintext", 0, &process_plaintext
, 0 },
499 { "no-iftex", 0, &process_tex
, 0 },
500 { "no-ifxml", 0, &process_xml
, 0 },
501 { "no-number-footnotes", 0, &number_footnotes
, 0 },
502 { "no-number-sections", 0, &number_sections
, 0 },
503 { "no-pointer-validate", 0, &validating
, 0 },
504 { "no-split", 0, &splitting
, 0 },
505 { "no-validate", 0, &validating
, 0 },
506 { "no-warn", 0, &print_warnings
, 0 },
507 { "number-footnotes", 0, &number_footnotes
, 1 },
508 { "number-sections", 0, &number_sections
, 1 },
509 { "output", 1, 0, 'o' },
510 { "output-indent", 1, 0, 'i' },
511 { "paragraph-indent", 1, 0, 'p' },
512 { "plaintext", 0, 0, 't' },
513 { "reference-limit", 1, 0, 'r' },
514 { "split-size", 1, 0, 'S'},
515 { "verbose", 0, &verbose_mode
, 1 },
516 { "version", 0, 0, 'V' },
517 { "xml", 0, 0, 'x' },
521 /* We use handle_variable_internal for -D and -U, and it depends on
522 execute_string, which depends on input_filename, which is not defined
523 while we are handling options. :-\ So we save these defines in this
524 struct, and handle them later. */
525 typedef struct command_line_define
527 struct command_line_define
*next
;
530 } COMMAND_LINE_DEFINE
;
532 static COMMAND_LINE_DEFINE
*command_line_defines
= NULL
;
534 /* For each file mentioned in the command line, process it, turning
535 Texinfo commands into wonderfully formatted output text. */
537 main (int argc
, char **argv
)
540 int reading_from_stdin
= 0;
542 #ifdef HAVE_SETLOCALE
543 /* Do not use LC_ALL, because LC_NUMERIC screws up the scanf parsing
544 of the argument to @multicolumn. */
545 setlocale (LC_TIME
, "");
546 #ifdef LC_MESSAGES /* ultrix */
547 setlocale (LC_MESSAGES
, "");
549 setlocale (LC_CTYPE
, "");
550 setlocale (LC_COLLATE
, "");
554 /* Set the text message domain. */
555 bindtextdomain (PACKAGE
, LOCALEDIR
);
556 textdomain (PACKAGE
);
559 /* If TEXINFO_OUTPUT_FORMAT envvar is set, use it to set default output.
560 Can be overridden with one of the output options. */
561 if (getenv ("TEXINFO_OUTPUT_FORMAT") != NULL
)
563 if (STREQ (getenv ("TEXINFO_OUTPUT_FORMAT"), "docbook"))
571 else if (STREQ (getenv ("TEXINFO_OUTPUT_FORMAT"), "html"))
578 else if (STREQ (getenv ("TEXINFO_OUTPUT_FORMAT"), "info"))
584 else if (STREQ (getenv ("TEXINFO_OUTPUT_FORMAT"), "plaintext"))
591 process_plaintext
= 1;
593 else if (STREQ (getenv ("TEXINFO_OUTPUT_FORMAT"), "xml"))
603 _("%s: Ignoring unrecognized TEXINFO_OUTPUT_FORMAT value `%s'.\n"),
604 progname
, getenv ("TEXINFO_OUTPUT_FORMAT"));
607 /* Parse argument flags from the input line. */
608 while ((c
= getopt_long (argc
, argv
, "D:de:E:f:hI:i:o:p:P:r:s:t:U:vV:wx",
609 long_options
, &ind
)) != EOF
)
611 if (c
== 0 && long_options
[ind
].flag
== 0)
612 c
= long_options
[ind
].val
;
616 case 'C': /* --css-include */
617 css_include
= xstrdup (optarg
);
622 /* User specified variable to set or clear. */
625 COMMAND_LINE_DEFINE
*new = xmalloc (sizeof (COMMAND_LINE_DEFINE
));
626 new->action
= (c
== 'D') ? SET
: CLEAR
;
627 new->define
= xstrdup (optarg
);
628 new->next
= command_line_defines
;
629 command_line_defines
= new;
632 handle_variable_internal ((c
== 'D' ? SET
: CLEAR
), optarg
);
635 case 'd': /* --docbook */
643 case 'e': /* --error-limit */
644 if (sscanf (optarg
, "%d", &max_error_level
) != 1)
647 _("%s: %s arg must be numeric, not `%s'.\n"),
648 progname
, "--error-limit", optarg
);
653 case 'E': /* --macro-expand */
654 if (!macro_expansion_output_stream
)
656 macro_expansion_filename
= optarg
;
657 macro_expansion_output_stream
658 = strcmp (optarg
, "-") == 0 ? stdout
: fopen (optarg
, "w");
659 if (!macro_expansion_output_stream
)
660 error (_("%s: could not open macro expansion output `%s'"),
665 _("%s: ignoring second macro expansion output `%s'.\n"),
669 case 'f': /* --fill-column */
670 if (sscanf (optarg
, "%d", &fill_column
) != 1)
673 _("%s: %s arg must be numeric, not `%s'.\n"),
674 progname
, "--fill-column", optarg
);
679 case 'h': /* --help */
684 /* Append user-specified dir to include file path. */
685 append_to_include_path (optarg
);
689 if (sscanf (optarg
, "%d", &xml_indentation_increment
) != 1)
692 _("%s: %s arg must be numeric, not `%s'.\n"),
693 progname
, "--output-indent", optarg
);
698 case 'o': /* --output */
699 command_output_filename
= xstrdup (optarg
);
700 save_command_output_filename
= command_output_filename
;
703 case 'p': /* --paragraph-indent */
704 if (set_paragraph_indent (optarg
) < 0)
707 _("%s: --paragraph-indent arg must be numeric/`none'/`asis', not `%s'.\n"),
714 /* Prepend user-specified include dir to include path. */
715 prepend_to_include_path (optarg
);
718 case 'r': /* --reference-limit */
719 if (sscanf (optarg
, "%d", &reference_warning_limit
) != 1)
722 _("%s: %s arg must be numeric, not `%s'.\n"),
723 progname
, "--reference-limit", optarg
);
728 case 's': /* --footnote-style */
729 if (set_footnote_style (optarg
) < 0)
732 _("%s: --footnote-style arg must be `separate' or `end', not `%s'.\n"),
736 footnote_style_preset
= 1;
739 case 'S': /* --split-size */
740 if (sscanf (optarg
, "%d", &split_size
) != 1)
743 _("%s: %s arg must be numeric, not `%s'.\n"),
744 progname
, "--split-size", optarg
);
749 case 't': /* --plaintext */
755 process_plaintext
= 1;
762 case 'V': /* --version */
763 print_version_info ();
765 puts ("Copyright (C) 2004 Free Software Foundation, Inc.");
766 printf (_("There is NO warranty. You may redistribute this software\n\
767 under the terms of the GNU General Public License.\n\
768 For more information about these matters, see the files named COPYING.\n"));
772 case 'w': /* --html */
779 case 'x': /* --xml */
793 if (macro_expansion_output_stream
)
797 expensive_validation
= 0;
801 /* Check to see if input is a file. If so, process that. */
802 if (!isatty (fileno (stdin
)))
803 reading_from_stdin
= 1;
806 fprintf (stderr
, _("%s: missing file argument.\n"), progname
);
813 /* If the user did not specify an output file, use stdout. */
814 if (!command_output_filename
)
815 command_output_filename
= xstrdup ("-");
817 if (html
&& splitting
&& !STREQ (command_output_filename
, "-"))
818 { /* --no-headers --no-split --html indicates confusion. */
820 "%s: can't split --html output to `%s' with --no-headers.\n",
821 progname
, command_output_filename
);
825 /* --no-headers implies --no-split. */
829 if (process_info
== -1)
830 { /* no explicit --[no-]ifinfo option, so we'll do @ifinfo
831 if we're generating info or (for compatibility) plain text. */
832 process_info
= !html
&& !xml
;
835 if (process_plaintext
== -1)
836 { /* no explicit --[no-]ifplaintext option, so we'll do @ifplaintext
837 if we're generating plain text. */
838 process_plaintext
= no_headers
&& !html
&& !xml
;
842 print_version_info ();
844 /* Remaining arguments are file names of texinfo files.
845 Convert them, one by one. */
846 if (!reading_from_stdin
)
848 while (optind
!= argc
)
849 convert_from_file (argv
[optind
++]);
852 convert_from_stream (stdin
, "stdin");
854 xexit (errors_printed
? 2 : 0);
855 return 0; /* Avoid bogus warnings. */
858 /* Hacking tokens and strings. */
860 /* Return the next token as a string pointer. We cons the string. This
861 `token' means simply a command name. */
863 /* = is so @alias works. ^ and _ are so macros can be used in math mode
864 without a space following. Possibly we should simply allow alpha, to
865 be compatible with TeX. */
866 #define COMMAND_CHAR(c) (!cr_or_whitespace(c) \
880 /* If the first character to be read is self-delimiting, then that
881 is the command itself. */
882 character
= curchar ();
883 if (self_delimiting (character
))
887 if (character
== '\n')
890 result
= xstrdup (" ");
895 for (i
= 0; ((input_text_offset
!= input_text_length
)
896 && (character
= curchar ())
897 && COMMAND_CHAR (character
));
898 i
++, input_text_offset
++);
899 result
= xmalloc (i
+ 1);
900 memcpy (result
, &input_text
[input_text_offset
- i
], i
);
905 /* Return nonzero if CHARACTER is self-delimiting. */
907 self_delimiting (int character
)
909 /* @; and @\ are not Texinfo commands, but they are listed here
910 anyway. I don't know why. --karl, 10aug96. */
911 return strchr ("~{|}`^\\@?=;:./-,*\'\" !\n\t", character
) != NULL
;
914 /* Clear whitespace from the front and end of string. */
916 canon_white (char *string
)
926 if (!cr_or_whitespace (*p
))
933 while (len
&& cr_or_whitespace (p
[len
-1]))
937 memmove (string
, p
, len
);
942 /* Bash STRING, replacing all whitespace with just one space. */
944 fix_whitespace (char *string
)
946 char *temp
= xmalloc (strlen (string
) + 1);
947 int string_index
= 0;
951 canon_white (string
);
953 while (string
[string_index
])
955 c
= temp
[temp_index
++] = string
[string_index
++];
957 if (c
== ' ' || c
== '\n' || c
== '\t')
959 temp
[temp_index
- 1] = ' ';
960 while ((c
= string
[string_index
]) && (c
== ' ' ||
966 temp
[temp_index
] = 0;
967 strcpy (string
, temp
);
971 /* Discard text until the desired string is found. The string is
972 included in the discarded text. */
974 discard_until (char *string
)
976 int temp
= search_forward (string
, input_text_offset
);
978 int tt
= (temp
< 0) ? input_text_length
: temp
+ strlen (string
);
979 int from
= input_text_offset
;
981 /* Find out what line we are on. */
983 if (input_text
[from
++] == '\n')
988 /* not found, move current position to end of string */
989 input_text_offset
= input_text_length
;
990 if (strcmp (string
, "\n") != 0)
991 { /* Give a more descriptive feedback, if we are looking for ``@end ''
992 during macro execution. That means someone used a multiline
993 command as an argument to, say, @section ... style commands. */
994 char *end_block
= xmalloc (8);
995 sprintf (end_block
, "\n%cend ", COMMAND_PREFIX
);
996 if (executing_string
&& strstr (string
, end_block
))
997 line_error (_("Multiline command %c%s used improperly"),
998 COMMAND_PREFIX
, command
);
1000 line_error (_("Expected `%s'"), string
);
1006 /* found, move current position to after the found string */
1007 input_text_offset
= temp
+ strlen (string
);
1010 /* Read characters from the file until we are at MATCH.
1011 Place the characters read into STRING.
1012 On exit input_text_offset is after the match string.
1013 Return the offset where the string starts. */
1015 get_until (char *match
, char **string
)
1017 int len
, current_point
, x
, new_point
, tem
;
1019 current_point
= x
= input_text_offset
;
1020 new_point
= search_forward (match
, input_text_offset
);
1023 new_point
= input_text_length
;
1024 len
= new_point
- current_point
;
1026 /* Keep track of which line number we are at. */
1027 tem
= new_point
+ (strlen (match
) - 1);
1029 if (input_text
[x
++] == '\n')
1032 *string
= xmalloc (len
+ 1);
1034 memcpy (*string
, &input_text
[current_point
], len
);
1037 /* Now leave input_text_offset in a consistent state. */
1038 input_text_offset
= tem
;
1040 if (input_text_offset
> input_text_length
)
1041 input_text_offset
= input_text_length
;
1046 /* Replace input_text[FROM .. TO] with its expansion. */
1048 replace_with_expansion (int from
, int *to
)
1051 unsigned xp_len
, new_len
;
1052 char *old_input
= input_text
;
1053 unsigned raw_len
= *to
- from
;
1056 /* The rest of the code here moves large buffers, so let's
1057 not waste time if the input cannot possibly expand
1058 into anything. Unfortunately, we cannot avoid expansion
1059 when we see things like @code etc., even if they only
1060 asked for expansion of macros, since any Texinfo command
1061 can be potentially redefined with a macro. */
1062 if (only_macro_expansion
&&
1063 memchr (input_text
+ from
, COMMAND_PREFIX
, raw_len
) == 0)
1066 /* Get original string from input. */
1067 str
= xmalloc (raw_len
+ 1);
1068 memcpy (str
, input_text
+ from
, raw_len
);
1071 /* We are going to relocate input_text, so we had better output
1072 pending portion of input_text now, before the pointer changes. */
1073 if (macro_expansion_output_stream
&& !executing_string
1074 && !me_inhibit_expansion
)
1075 append_to_expansion_output (from
);
1078 xp
= expansion (str
, 0);
1079 xp_len
= strlen (xp
);
1082 /* Plunk the expansion into the middle of `input_text' --
1083 which is terminated by a newline, not a null. Avoid
1084 expensive move of the rest of the input if the expansion
1085 has the same length as the original string. */
1086 if (xp_len
!= raw_len
)
1088 new_len
= from
+ xp_len
+ input_text_length
- *to
+ 1;
1089 if (executing_string
)
1090 { /* If we are in execute_string, we might need to update
1091 the relevant element in the execution_strings[] array,
1092 since it could have to be relocated from under our
1093 feet. (input_text is reallocated here as well, if needed.) */
1094 maybe_update_execution_strings (&input_text
, new_len
);
1096 else if (new_len
> input_text_length
+ 1)
1097 /* Don't bother to realloc if we have enough space. */
1098 input_text
= xrealloc (input_text
, new_len
);
1100 memmove (input_text
+ from
+ xp_len
,
1101 input_text
+ *to
, input_text_length
- *to
+ 1);
1103 *to
+= xp_len
- raw_len
;
1104 /* Since we change input_text_length here, the comparison above
1105 isn't really valid, but it seems the worst that might happen is
1106 an extra xrealloc or two, so let's not worry. */
1107 input_text_length
+= xp_len
- raw_len
;
1109 memcpy (input_text
+ from
, xp
, xp_len
);
1112 /* Synchronize the macro-expansion pointers with our new input_text. */
1113 if (input_text
!= old_input
)
1114 forget_itext (old_input
);
1115 if (macro_expansion_output_stream
&& !executing_string
)
1116 remember_itext (input_text
, from
);
1119 /* Read characters from the file until we are at MATCH or end of line.
1120 Place the characters read into STRING. If EXPAND is nonzero,
1121 expand the text before looking for MATCH for those cases where
1122 MATCH might be produced by some macro. */
1124 get_until_in_line (int expand
, char *match
, char **string
)
1126 int real_bottom
= input_text_length
;
1127 int limit
= search_forward ("\n", input_text_offset
);
1129 limit
= input_text_length
;
1131 /* Replace input_text[input_text_offset .. limit-1] with its expansion.
1132 This allows the node names and menu entries themselves to be
1133 constructed via a macro, as in:
1135 Together: \p\ & \q\.
1138 @node @foo{A,B}, next, prev, top
1140 Otherwise, the `,' separating the macro args A and B is taken as
1141 the node argument separator, so the node name is `@foo{A'. This
1142 expansion is only necessary on the first call, since we expand the
1146 replace_with_expansion (input_text_offset
, &limit
);
1149 real_bottom
= input_text_length
;
1150 input_text_length
= limit
;
1151 get_until (match
, string
);
1152 input_text_length
= real_bottom
;
1156 get_rest_of_line (int expand
, char **string
)
1163 /* Don't expand non-macros in input, since we want them
1164 intact in the macro-expanded output. */
1165 only_macro_expansion
++;
1166 get_until_in_line (1, "\n", &tem
);
1167 only_macro_expansion
--;
1168 *string
= expansion (tem
, 0);
1172 get_until_in_line (0, "\n", string
);
1174 canon_white (*string
);
1176 if (curchar () == '\n') /* as opposed to the end of the file... */
1179 input_text_offset
++;
1184 /* Backup the input pointer to the previous character, keeping track
1185 of the current line number. */
1187 backup_input_pointer (void)
1189 if (input_text_offset
)
1191 input_text_offset
--;
1192 if (curchar () == '\n')
1197 /* Read characters from the file until we are at MATCH or closing brace.
1198 Place the characters read into STRING. */
1200 get_until_in_braces (char *match
, char **string
)
1204 int match_len
= strlen (match
);
1206 for (i
= input_text_offset
; i
< input_text_length
; i
++)
1208 if (i
< input_text_length
- 1 && input_text
[i
] == '@')
1210 i
++; /* skip commands like @, and @{ */
1213 else if (input_text
[i
] == '{')
1215 else if (input_text
[i
] == '}')
1218 /* If looking for a brace, don't stop at the interior brace,
1219 like after "baz" in "@foo{something @bar{baz} more}". */
1223 else if (input_text
[i
] == '\n')
1227 (brace
== 0 && strncmp (input_text
+ i
, match
, match_len
) == 0))
1231 match_len
= i
- input_text_offset
;
1232 temp
= xmalloc (2 + match_len
);
1233 memcpy (temp
, input_text
+ input_text_offset
, match_len
);
1234 temp
[match_len
] = 0;
1235 input_text_offset
= i
;
1241 /* Converting a file. */
1243 /* Convert the file named by NAME. The output is saved on the file
1244 named as the argument to the @setfilename command. */
1245 static char *suffixes
[] = {
1246 /* ".txi" is checked first so that on 8+3 DOS filesystems, if they
1247 have "texinfo.txi" and "texinfo.tex" in the same directory, the
1248 former is used rather than the latter, due to file name truncation. */
1258 initialize_conversion (void)
1265 /* This is used for splitting the output file and for doing section
1266 headings. It was previously initialized in `init_paragraph', but its
1267 use there loses with the `init_paragraph' calls done by the
1268 multitable code; the tag indices get reset to zero. */
1269 output_position
= 0;
1272 /* Reverse the chain of structures in LIST. Output the new head
1273 of the chain. You should always assign the output value of this
1274 function to something, or you will lose the chain. */
1276 reverse_list (GENERIC_LIST
*list
)
1279 GENERIC_LIST
*prev
= NULL
;
1291 /* We read in multiples of 4k, simply because it is a typical pipe size
1293 #define READ_BUFFER_GROWTH (4 * 4096)
1295 /* Convert the Texinfo file coming from the open stream STREAM. Assume the
1296 source of the stream is named NAME. */
1298 convert_from_stream (FILE *stream
, char *name
)
1300 char *buffer
= NULL
;
1301 int buffer_offset
= 0, buffer_size
= 0;
1303 initialize_conversion ();
1305 /* Read until the end of the stream. This isn't strictly correct, since
1306 the texinfo input may end before the stream ends, but it is a quick
1307 working hueristic. */
1308 while (!feof (stream
))
1312 if (buffer_offset
+ (READ_BUFFER_GROWTH
+ 1) >= buffer_size
)
1314 xrealloc (buffer
, (buffer_size
+= READ_BUFFER_GROWTH
));
1316 count
= fread (buffer
+ buffer_offset
, 1, READ_BUFFER_GROWTH
, stream
);
1324 buffer_offset
+= count
;
1329 /* Set the globals to the new file. */
1330 input_text
= buffer
;
1331 input_text_length
= buffer_offset
;
1332 input_filename
= xstrdup (name
);
1333 node_filename
= xstrdup (name
);
1334 input_text_offset
= 0;
1337 /* Not strictly necessary. This magic prevents read_token () from doing
1338 extra unnecessary work each time it is called (that is a lot of times).
1339 The INPUT_TEXT_LENGTH is one past the actual end of the text. */
1340 input_text
[input_text_length
] = '\n';
1342 convert_from_loaded_file (name
);
1346 convert_from_file (char *name
)
1349 char *filename
= xmalloc (strlen (name
) + 50);
1351 /* Prepend file directory to the search path, so relative links work. */
1352 prepend_to_include_path (pathname_part (name
));
1354 initialize_conversion ();
1356 /* Try to load the file specified by NAME, concatenated with our
1357 various suffixes. Prefer files like `makeinfo.texi' to
1359 for (i
= 0; suffixes
[i
]; i
++)
1361 strcpy (filename
, name
);
1362 strcat (filename
, suffixes
[i
]);
1364 if (find_and_load (filename
, 1))
1367 if (!suffixes
[i
][0] && strrchr (filename
, '.'))
1369 fs_error (filename
);
1382 input_filename
= filename
;
1384 convert_from_loaded_file (name
);
1386 /* Pop the prepended path, so multiple filenames in the
1387 command line do not screw each others include paths. */
1388 pop_path_from_include_path ();
1392 create_html_directory (char *dir
, int can_remove_file
)
1396 /* Already exists. */
1397 if (stat (dir
, &st
) == 0)
1399 /* And it's a directory, so silently reuse it. */
1400 if (S_ISDIR (st
.st_mode
))
1402 /* Not a directory, so move it out of the way if we are allowed. */
1403 else if (can_remove_file
)
1405 if (unlink (dir
) != 0)
1412 if (mkdir (dir
, 0777) == 0)
1419 /* Given OUTPUT_FILENAME == ``/foo/bar/baz.html'', return
1420 "/foo/bar/baz/baz.html". This routine is called only if html && splitting.
1422 Split html output goes into the subdirectory of the toplevel
1423 filename, without extension. For example:
1424 @setfilename foo.info
1425 produces output in files foo/index.html, foo/second-node.html, ...
1427 But if the user said -o foo.whatever on the cmd line, then use
1428 foo.whatever unchanged. */
1431 insert_toplevel_subdirectory (char *output_filename
)
1433 static const char index_name
[] = "index.html";
1434 char *dir
, *subdir
, *base
, *basename
, *p
;
1436 const int index_len
= sizeof (index_name
) - 1;
1438 strcpy (buf
, output_filename
);
1439 dir
= pathname_part (buf
); /* directory of output_filename */
1440 base
= filename_part (buf
); /* strips suffix, too */
1441 basename
= xstrdup (base
); /* remember real @setfilename name */
1442 p
= dir
+ strlen (dir
) - 1;
1443 if (p
> dir
&& IS_SLASH (*p
))
1445 p
= strrchr (base
, '.');
1449 /* Split html output goes into subdirectory of toplevel name. */
1450 if (save_command_output_filename
1451 && STREQ (output_filename
, save_command_output_filename
))
1452 subdir
= basename
; /* from user, use unchanged */
1454 subdir
= base
; /* implicit, omit suffix */
1456 free (output_filename
);
1457 output_filename
= xmalloc (strlen (dir
) + 1
1458 + strlen (basename
) + 1
1461 strcpy (output_filename
, dir
);
1463 strcat (output_filename
, "/");
1464 strcat (output_filename
, subdir
);
1466 /* First try, do not remove existing file. */
1467 if (!create_html_directory (output_filename
, 0))
1469 /* That failed, try subdir name with .html.
1470 Remove it if it exists. */
1471 strcpy (output_filename
, dir
);
1473 strcat (output_filename
, "/");
1474 strcat (output_filename
, basename
);
1476 if (!create_html_directory (output_filename
, 1))
1478 /* Last try failed too :-\ */
1479 line_error (_("Can't create directory `%s': %s"),
1480 output_filename
, strerror (errno
));
1485 strcat (output_filename
, "/");
1486 strcat (output_filename
, index_name
);
1487 return output_filename
;
1490 /* FIXME: this is way too hairy */
1492 convert_from_loaded_file (char *name
)
1494 char *real_output_filename
= NULL
;
1496 remember_itext (input_text
, 0);
1498 input_text_offset
= 0;
1500 /* Avoid the `\input texinfo' line in HTML output (assuming it starts
1502 if (looking_at ("\\input"))
1503 discard_until ("\n");
1505 /* Search this file looking for the special string which starts conversion.
1506 Once found, we may truly begin. */
1507 while (input_text_offset
>= 0)
1510 search_forward (setfilename_search
, input_text_offset
);
1512 if (input_text_offset
== 0
1513 || (input_text_offset
> 0
1514 && input_text
[input_text_offset
-1] == '\n'))
1516 else if (input_text_offset
> 0)
1517 input_text_offset
++;
1520 if (input_text_offset
< 0)
1522 if (!command_output_filename
)
1524 #if defined (REQUIRE_SETFILENAME)
1525 error (_("No `%s' found in `%s'"), setfilename_search
, name
);
1528 command_output_filename
= output_name_from_input_name (name
);
1529 #endif /* !REQUIRE_SETFILENAME */
1533 int i
, end_of_first_line
;
1535 /* Find the end of the first line in the file. */
1536 for (i
= 0; i
< input_text_length
- 1; i
++)
1537 if (input_text
[i
] == '\n')
1540 end_of_first_line
= i
+ 1;
1542 for (i
= 0; i
< end_of_first_line
; i
++)
1544 if ((input_text
[i
] == '\\') &&
1545 (strncmp (input_text
+ i
+ 1, "input", 5) == 0))
1547 input_text_offset
= i
;
1554 input_text_offset
+= strlen (setfilename_search
);
1556 if (!command_output_filename
)
1558 get_until ("\n", &output_filename
); /* read rest of line */
1560 { /* Change any extension to .html or .xml. */
1561 char *html_name
, *directory_part
, *basename_part
, *temp
;
1563 canon_white (output_filename
);
1564 directory_part
= pathname_part (output_filename
);
1566 basename_part
= filename_part (output_filename
);
1568 /* Zap any existing extension. */
1569 temp
= strrchr (basename_part
, '.');
1573 /* Construct new filename. */
1574 html_name
= xmalloc (strlen (directory_part
)
1575 + strlen (basename_part
) + 6);
1576 strcpy (html_name
, directory_part
);
1577 strcat (html_name
, basename_part
);
1578 strcat (html_name
, html
? ".html" : ".xml");
1580 /* Replace name from @setfilename with the html name. */
1581 free (output_filename
);
1582 output_filename
= html_name
;
1587 if (input_text_offset
!= -1)
1588 discard_until ("\n");
1590 input_text_offset
= 0;
1592 real_output_filename
= output_filename
= command_output_filename
;
1593 command_output_filename
= NULL
; /* for included files or whatever */
1596 canon_white (output_filename
);
1597 toplevel_output_filename
= xstrdup (output_filename
);
1599 if (real_output_filename
&& strcmp (real_output_filename
, "-") == 0)
1601 if (macro_expansion_filename
1602 && strcmp (macro_expansion_filename
, "-") == 0)
1605 _("%s: Skipping macro expansion to stdout as Info output is going there.\n"),
1607 macro_expansion_output_stream
= NULL
;
1609 real_output_filename
= xstrdup (real_output_filename
);
1610 output_stream
= stdout
;
1611 splitting
= 0; /* Cannot split when writing to stdout. */
1615 if (html
&& splitting
)
1617 if (FILENAME_CMP (output_filename
, NULL_DEVICE
) == 0
1618 || FILENAME_CMP (output_filename
, ALSO_NULL_DEVICE
) == 0)
1621 output_filename
= insert_toplevel_subdirectory (output_filename
);
1622 real_output_filename
= xstrdup (output_filename
);
1624 else if (!real_output_filename
)
1625 real_output_filename
= expand_filename (output_filename
, name
);
1627 real_output_filename
= xstrdup (real_output_filename
);
1629 output_stream
= fopen (real_output_filename
, "w");
1632 set_current_output_filename (real_output_filename
);
1634 if (xml
&& !docbook
)
1635 xml_begin_document (filename_part (output_filename
));
1638 printf (_("Making %s file `%s' from `%s'.\n"),
1643 output_filename
, input_filename
);
1645 if (output_stream
== NULL
)
1647 fs_error (real_output_filename
);
1651 /* Make the displayable filename from output_filename. Only the base
1652 portion of the filename need be displayed. */
1653 flush_output (); /* in case there was no @bye */
1654 if (output_stream
!= stdout
)
1655 pretty_output_filename
= filename_part (output_filename
);
1657 pretty_output_filename
= xstrdup ("stdout");
1659 /* For this file only, count the number of newlines from the top of
1660 the file to here. This way, we keep track of line numbers for
1661 error reporting. Line_number starts at 1, since the user isn't
1666 while (temp
!= input_text_offset
)
1667 if (input_text
[temp
++] == '\n')
1671 /* html fixxme: should output this as trailer on first page. */
1672 if (!no_headers
&& !html
&& !xml
)
1673 add_word_args (_("This is %s, produced by makeinfo version %s from %s.\n"),
1674 output_filename
, VERSION
, input_filename
);
1678 if (xml
&& !docbook
)
1680 /* Just before the real main loop, let's handle the defines. */
1681 COMMAND_LINE_DEFINE
*temp
;
1683 for (temp
= command_line_defines
; temp
; temp
= temp
->next
)
1685 handle_variable_internal (temp
->action
, temp
->define
);
1692 xml_end_document ();
1696 discard_insertions (0);
1698 flush_file_stack ();
1700 if (macro_expansion_output_stream
)
1702 fclose (macro_expansion_output_stream
);
1703 if (errors_printed
&& !force
1704 && strcmp (macro_expansion_filename
, "-") != 0
1705 && FILENAME_CMP (macro_expansion_filename
, NULL_DEVICE
) != 0
1706 && FILENAME_CMP (macro_expansion_filename
, ALSO_NULL_DEVICE
) != 0)
1709 _("%s: Removing macro output file `%s' due to errors; use --force to preserve.\n"),
1710 progname
, macro_expansion_filename
);
1711 if (unlink (macro_expansion_filename
) < 0)
1712 perror (macro_expansion_filename
);
1718 output_pending_notes ();
1724 add_word ("</body></html>\n");
1728 /* maybe we want local variables in info output. */
1730 char *trailer
= info_trailer ();
1731 if (!xml
&& !docbook
&& trailer
)
1734 insert_string ("<!--");
1735 insert_string (trailer
);
1738 insert_string ("\n-->\n");
1742 /* Write stuff makeinfo generates after @bye, ie. info_trailer. */
1745 if (output_stream
!= stdout
)
1746 fclose (output_stream
);
1748 /* If validating, then validate the entire file right now. */
1750 validate_file (tag_table
);
1752 handle_delayed_writes ();
1756 tag_table
= (TAG_ENTRY
*) reverse_list ((GENERIC_LIST
*) tag_table
);
1757 if (!no_headers
&& !html
&& !STREQ (current_output_filename
, "-"))
1758 write_tag_table (real_output_filename
);
1761 if (splitting
&& !html
&& (!errors_printed
|| force
))
1763 clean_old_split_files (real_output_filename
);
1764 split_file (real_output_filename
, split_size
);
1766 else if (errors_printed
1768 && strcmp (real_output_filename
, "-") != 0
1769 && FILENAME_CMP (real_output_filename
, NULL_DEVICE
) != 0
1770 && FILENAME_CMP (real_output_filename
, ALSO_NULL_DEVICE
) != 0)
1771 { /* If there were errors, and no --force, remove the output. */
1773 _("%s: Removing output file `%s' due to errors; use --force to preserve.\n"),
1774 progname
, real_output_filename
);
1775 if (unlink (real_output_filename
) < 0)
1776 perror (real_output_filename
);
1779 free (real_output_filename
);
1782 /* If enable_encoding is set and @documentencoding is used, return a
1783 Local Variables section (as a malloc-ed string) so that Emacs'
1784 locale features can work. Else return NULL. */
1790 if (!enable_encoding
)
1793 encoding
= current_document_encoding ();
1795 if (encoding
&& *encoding
)
1797 #define LV_FMT "\n\037\nLocal Variables:\ncoding: %s\nEnd:\n"
1798 char *lv
= xmalloc (sizeof (LV_FMT
) + strlen (encoding
));
1799 sprintf (lv
, LV_FMT
, encoding
);
1809 free_and_clear (char **pointer
)
1818 /* Initialize some state. */
1820 init_internals (void)
1822 free_and_clear (&output_filename
);
1823 free_and_clear (&command
);
1824 free_and_clear (&input_filename
);
1825 free_node_references ();
1826 free_node_node_references ();
1828 init_insertion_stack ();
1829 init_brace_stack ();
1830 current_node
= NULL
; /* sometimes already freed */
1835 non_top_node_seen
= 0;
1840 init_paragraph (void)
1842 free (output_paragraph
);
1843 output_paragraph
= xmalloc (paragraph_buffer_len
);
1844 output_paragraph
[0] = 0;
1845 output_paragraph_offset
= 0;
1847 paragraph_is_open
= 0;
1852 /* This is called from `reader_loop' when we are at the * beginning a
1856 handle_menu_entry (void)
1860 /* Ugh, glean_node_from_menu wants to read the * itself. */
1861 input_text_offset
--;
1863 /* Find node name in menu entry and save it in references list for
1864 later validation. Use followed_reference type for detailmenu
1865 references since we don't want to use them for default node pointers. */
1866 tem
= glean_node_from_menu (1, in_detailmenu
1867 ? followed_reference
: menu_reference
);
1870 { /* Start a menu item with the cleaned-up line. Put an anchor
1871 around the start text (before `:' or the node name). */
1874 discard_until ("* ");
1876 /* The line number was already incremented in reader_loop when we
1877 saw the newline, and discard_until has now incremented again. */
1880 if (had_menu_commentary
)
1882 add_html_block_elt ("<ul class=\"menu\">\n");
1883 had_menu_commentary
= 0;
1889 add_html_block_elt ("</p>\n");
1890 add_html_block_elt ("<ul class=\"menu\">\n");
1896 add_html_block_elt ("<li><a");
1897 if (next_menu_item_number
<= 9)
1899 add_word(" accesskey=");
1900 add_word_args("\"%d\"", next_menu_item_number
);
1901 next_menu_item_number
++;
1903 add_word (" href=\"");
1904 string
= expansion (tem
, 0);
1905 add_anchor_name (string
, 1);
1909 /* The menu item may use macros, so expand them now. */
1910 only_macro_expansion
++;
1911 get_until_in_line (1, ":", &string
);
1912 only_macro_expansion
--;
1913 execute_string ("%s", string
); /* get escaping done */
1918 if (looking_at ("::"))
1919 discard_until (":");
1921 { /* discard the node name */
1922 get_until_in_line (0, ".", &string
);
1925 input_text_offset
++; /* discard the second colon or the period */
1927 /* Insert a colon only if there is a description of this menu item. */
1929 int save_input_text_offset
= input_text_offset
;
1930 int save_line_number
= line_number
;
1932 get_rest_of_line (0, &test_string
);
1933 if (strlen (test_string
) > 0)
1935 input_text_offset
= save_input_text_offset
;
1936 line_number
= save_line_number
;
1939 else if (xml
&& tem
)
1941 xml_start_menu_entry (tem
);
1944 { /* For Info output, we can just use the input and the main case in
1945 reader_loop where we output what comes in. Just move off the *
1946 so the next time through reader_loop we don't end up back here. */
1948 input_text_offset
+= 2; /* undo the pointer back-up above. */
1955 /* Find the command corresponding to STRING. If the command is found,
1956 return a pointer to the data structure. Otherwise return -1. */
1958 get_command_entry (char *string
)
1962 for (i
= 0; command_table
[i
].name
; i
++)
1963 if (strcmp (command_table
[i
].name
, string
) == 0)
1964 return &command_table
[i
];
1966 /* This command is not in our predefined command table. Perhaps
1967 it is a user defined command. */
1968 for (i
= 0; i
< user_command_array_len
; i
++)
1969 if (user_command_array
[i
] &&
1970 (strcmp (user_command_array
[i
]->name
, string
) == 0))
1971 return user_command_array
[i
];
1973 /* We never heard of this command. */
1974 return (COMMAND
*) -1;
1977 /* input_text_offset is right at the command prefix character.
1978 Read the next token to determine what to do. Return zero
1979 if there's no known command or macro after the prefix character. */
1984 int old_text_offset
= input_text_offset
++;
1986 free_and_clear (&command
);
1987 command
= read_token ();
1989 /* Check to see if this command is a macro. If so, execute it here. */
1993 def
= find_macro (command
);
1997 /* We disallow recursive use of a macro call. Inhibit the expansion
1998 of this macro during the life of its execution. */
1999 if (!(def
->flags
& ME_RECURSE
))
2003 execute_macro (def
);
2006 if (!(def
->flags
& ME_RECURSE
))
2013 if (only_macro_expansion
)
2015 /* Back up to the place where we were called, so the
2016 caller will have a chance to process this non-macro. */
2017 input_text_offset
= old_text_offset
;
2021 /* Perform alias expansion */
2022 command
= alias_expand (command
);
2024 if (enclosure_command (command
))
2026 remember_brace (enclosure_expand
);
2027 enclosure_expand (START
, output_paragraph_offset
, 0);
2031 entry
= get_command_entry (command
);
2032 if (entry
== (COMMAND
*)-1)
2034 line_error (_("Unknown command `%s'"), command
);
2038 if (entry
->argument_in_braces
== BRACE_ARGS
)
2039 remember_brace (entry
->proc
);
2040 else if (entry
->argument_in_braces
== MAYBE_BRACE_ARGS
)
2042 if (curchar () == '{')
2043 remember_brace (entry
->proc
);
2045 { /* No braces, so arg is next char. */
2047 int saved_offset
= output_paragraph_offset
;
2048 (*(entry
->proc
)) (START
, output_paragraph_offset
, 0);
2050 /* Possibilities left for the next character: @ (error), }
2051 (error), whitespace (skip) anything else (normal char). */
2056 line_error (_("Use braces to give a command as an argument to @%s"),
2062 /* Our caller will give the error message, because this }
2063 won't match anything. */
2068 input_text_offset
++;
2069 (*(entry
->proc
)) (END
, saved_offset
, output_paragraph_offset
);
2074 /* Get here if we have BRACE_ARGS, NO_BRACE_ARGS, or MAYBE_BRACE_ARGS
2076 (*(entry
->proc
)) (START
, output_paragraph_offset
, 0);
2080 /* Okay, we are ready to start the conversion. Call the reader on
2081 some text, and fill the text as it is output. Handle commands by
2082 remembering things like open braces and the current file position on a
2083 stack, and when the corresponding close brace is found, you can call
2084 the function with the proper arguments. Although the filling isn't
2085 necessary for HTML, it should do no harm. */
2094 if (input_text_offset
>= input_text_length
)
2097 character
= curchar ();
2099 /* If only_macro_expansion, only handle macros and leave
2100 everything else intact. */
2101 if (!only_macro_expansion
&& !in_fixed_width_font
2102 && ((!html
&& !xml
) || escape_html
)
2103 && (character
== '\'' || character
== '`')
2104 && input_text
[input_text_offset
+ 1] == character
)
2108 input_text_offset
+= 2;
2109 add_word (character
== '`' ? "“" : "”");
2114 input_text_offset
+= 2;
2115 xml_insert_entity (character
== '`' ? "ldquo" : "rdquo");
2120 input_text_offset
++;
2125 /* Convert --- to --. */
2126 if (!only_macro_expansion
&& character
== '-' && !in_fixed_width_font
2127 && ((!html
&& !xml
) || escape_html
))
2131 /* Get the number of consequtive dashes. */
2132 while (input_text
[input_text_offset
] == '-')
2135 input_text_offset
++;
2143 if (dash_count
== 0)
2146 while (dash_count
> 0)
2148 if (dash_count
>= 2)
2151 add_word ("—");
2153 xml_insert_entity ("mdash");
2156 else if (dash_count
>= 1)
2159 add_word ("–");
2161 xml_insert_entity ("ndash");
2169 while (--dash_count
> 0)
2176 /* If this is a whitespace character, then check to see if the line
2177 is blank. If so, advance to the carriage return. */
2178 if (!only_macro_expansion
&& whitespace (character
))
2180 int i
= input_text_offset
+ 1;
2182 while (i
< input_text_length
&& whitespace (input_text
[i
]))
2185 if (i
== input_text_length
|| input_text
[i
] == '\n')
2187 if (i
== input_text_length
)
2190 input_text_offset
= i
;
2191 character
= curchar ();
2195 if (character
== '\n')
2200 case '*': /* perhaps we are at a menu */
2201 /* We used to check for this in the \n case but an @c in a
2202 menu swallows its newline, so check here instead. */
2203 if (!only_macro_expansion
&& in_menu
2204 && input_text_offset
+ 1 < input_text_length
2205 && input_text
[input_text_offset
-1] == '\n')
2206 handle_menu_entry ();
2208 { /* Duplicate code from below, but not worth twisting the
2209 fallthroughs to get down there. */
2210 add_char (character
);
2211 input_text_offset
++;
2215 /* Escapes for HTML unless we're outputting raw HTML. Do
2216 this always, even if SGML rules don't require it since
2217 that's easier and safer for non-conforming browsers. */
2219 if (html
&& escape_html
)
2222 add_char (character
);
2223 input_text_offset
++;
2227 if (html
&& escape_html
)
2229 else if (xml
&& escape_html
)
2230 xml_insert_entity ("lt");
2232 add_char (character
);
2233 input_text_offset
++;
2237 if (html
&& escape_html
)
2239 else if (xml
&& escape_html
)
2240 xml_insert_entity ("gt");
2242 add_char (character
);
2243 input_text_offset
++;
2246 case COMMAND_PREFIX
: /* @ */
2247 if (read_command () || !only_macro_expansion
)
2250 /* FALLTHROUGH (usually) */
2252 /* Special case. We're not supposed to see this character by itself.
2253 If we do, it means there is a syntax error in the input text.
2254 Report the error here, but remember this brace on the stack so
2255 we can ignore its partner. */
2256 if (!only_macro_expansion
)
2258 if (command
&& !STREQ (command
, "math"))
2260 line_error (_("Misplaced %c"), '{');
2261 remember_brace (misplaced_brace
);
2264 /* We don't mind `extra' braces inside @math. */
2265 remember_brace (cm_no_op
);
2266 /* remember_brace advances input_text_offset. */
2270 /* FALLTHROUGH (usually) */
2272 if (!only_macro_expansion
)
2274 pop_and_call_brace ();
2275 input_text_offset
++;
2279 /* FALLTHROUGH (usually) */
2281 add_char (character
);
2282 input_text_offset
++;
2285 if (macro_expansion_output_stream
&& !only_macro_expansion
)
2286 maybe_write_itext (input_text
, input_text_offset
);
2290 init_brace_stack (void)
2295 /* Remember the current output position here. Save PROC
2296 along with it so you can call it later. */
2298 remember_brace_1 (COMMAND_FUNCTION (*proc
), int position
)
2300 BRACE_ELEMENT
*new = xmalloc (sizeof (BRACE_ELEMENT
));
2301 new->next
= brace_stack
;
2303 new->command
= command
? xstrdup (command
) : "";
2304 new->pos
= position
;
2305 new->line
= line_number
;
2306 new->in_fixed_width_font
= in_fixed_width_font
;
2311 remember_brace (COMMAND_FUNCTION (*proc
))
2313 if (curchar () != '{')
2314 line_error (_("%c%s expected braces"), COMMAND_PREFIX
, command
);
2316 input_text_offset
++;
2317 remember_brace_1 (proc
, output_paragraph_offset
);
2320 /* Pop the top of the brace stack, and call the associated function
2321 with the args END and POS. */
2323 pop_and_call_brace (void)
2325 if (brace_stack
== NULL
)
2327 line_error (_("Unmatched }"));
2332 BRACE_ELEMENT
*temp
;
2334 int pos
= brace_stack
->pos
;
2335 COMMAND_FUNCTION
*proc
= brace_stack
->proc
;
2336 in_fixed_width_font
= brace_stack
->in_fixed_width_font
;
2338 /* Reset current command, so the proc can know who it is. This is
2339 used in cm_accent. */
2340 command
= brace_stack
->command
;
2342 temp
= brace_stack
->next
;
2346 (*proc
) (END
, pos
, output_paragraph_offset
);
2350 /* Shift all of the markers in `brace_stack' by AMOUNT. */
2352 adjust_braces_following (int here
, int amount
)
2354 BRACE_ELEMENT
*stack
= brace_stack
;
2358 if (stack
->pos
>= here
)
2359 stack
->pos
+= amount
;
2360 stack
= stack
->next
;
2364 /* Return the string which invokes PROC; a pointer to a function.
2365 Always returns the first function in the command table if more than
2366 one matches PROC. */
2368 find_proc_name (COMMAND_FUNCTION (*proc
))
2372 for (i
= 0; command_table
[i
].name
; i
++)
2373 if (proc
== command_table
[i
].proc
)
2374 return command_table
[i
].name
;
2375 return _("NO_NAME!");
2378 /* You call discard_braces () when you shouldn't have any braces on the stack.
2379 I used to think that this happens for commands that don't take arguments
2380 in braces, but that was wrong because of things like @code{foo @@}. So now
2381 I only detect it at the beginning of nodes. */
2383 discard_braces (void)
2390 if (brace_stack
->proc
!= misplaced_brace
)
2392 const char *proc_name
;
2394 proc_name
= find_proc_name (brace_stack
->proc
);
2395 file_line_error (input_filename
, brace_stack
->line
,
2396 _("%c%s missing close brace"), COMMAND_PREFIX
,
2398 pop_and_call_brace ();
2402 BRACE_ELEMENT
*temp
;
2403 temp
= brace_stack
->next
;
2411 get_char_len (int character
)
2413 /* Return the printed length of the character. */
2419 len
= (output_column
+ 8) & 0xf7;
2420 if (len
> fill_column
)
2421 len
= fill_column
- output_column
;
2423 len
= len
- output_column
;
2427 len
= fill_column
- output_column
;
2431 /* ASCII control characters appear as two characters in the output
2432 (e.g., ^A). But characters with the high bit set are just one
2433 on suitable terminals, so don't count them as two for line
2434 breaking purposes. */
2435 if (0 <= character
&& character
< ' ')
2444 #if defined (VA_FPRINTF) && __STDC__
2445 add_word_args (const char *format
, ...)
2447 add_word_args (format
, va_alist
)
2452 char buffer
[2000]; /* xx no fixed limits */
2457 VA_START (ap
, format
);
2459 VA_SPRINTF (buffer
, format
, ap
);
2461 sprintf (buffer
, format
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
);
2462 #endif /* not VA_SPRINTF */
2467 /* Add STRING to output_paragraph. */
2469 add_word (char *string
)
2472 add_char (*string
++);
2475 /* Like add_word, but inhibits conversion of whitespace into .
2476 Use this to output HTML directives with embedded blanks, to make
2479 add_html_elt (char *string
)
2486 /* These two functions below, add_html_block_elt and add_html_block_elt_args,
2487 are mixtures of add_html_elt and add_word_args. They inform makeinfo that
2488 the current HTML element being inserted should not be enclosed in a <p>
2491 add_html_block_elt (char *string
)
2493 in_html_block_level_elt
++;
2495 in_html_block_level_elt
--;
2499 #if defined (VA_FPRINTF) && __STDC__
2500 add_html_block_elt_args (const char *format
, ...)
2502 add_html_block_elt_args (format
, va_alist
)
2507 char buffer
[2000]; /* xx no fixed limits */
2512 VA_START (ap
, format
);
2514 VA_SPRINTF (buffer
, format
, ap
);
2516 sprintf (buffer
, format
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
);
2517 #endif /* not VA_SPRINTF */
2519 add_html_block_elt (buffer
);
2522 /* Here is another awful kludge, used in add_char. Ordinarily, macro
2523 expansions take place in the body of the document, and therefore we
2524 should html_output_head when we see one. But there's an exception: a
2525 macro call might take place within @copying, and that does not start
2526 the real output, even though we fully expand the copying text.
2528 So we need to be able to check if we are defining the @copying text.
2529 We do this by looking back through the insertion stack. */
2531 defining_copying (void)
2534 for (i
= insertion_stack
; i
; i
= i
->next
)
2536 if (i
->insertion
== copying
)
2543 /* Add the character to the current paragraph. If filling_enabled is
2544 nonzero, then do filling as well. */
2546 add_char (int character
)
2550 xml_add_char (character
);
2554 /* If we are avoiding outputting headers, and we are currently
2555 in a menu, then simply return. But if we're only expanding macros,
2556 then we're being called from glean_node_from_menu to try to
2557 remember a menu reference, and we need that so we can do defaulting. */
2558 if (no_headers
&& !only_macro_expansion
&& (in_menu
|| in_detailmenu
))
2561 /* If we are adding a character now, then we don't have to
2562 ignore close_paragraph () calls any more. */
2563 if (must_start_paragraph
&& character
!= '\n')
2565 must_start_paragraph
= 0;
2566 line_already_broken
= 0; /* The line is no longer broken. */
2567 if (current_indent
> output_column
)
2569 indent (current_indent
- output_column
);
2570 output_column
= current_indent
;
2574 if (non_splitting_words
2575 && !(html
&& in_html_elt
)
2576 && strchr (" \t\n", character
))
2578 if (html
|| docbook
)
2579 { /* Seems cleaner to use than an 8-bit char. */
2580 int saved_escape_html
= escape_html
;
2583 escape_html
= saved_escape_html
;
2587 character
= META (' '); /* unmeta-d in flush_output */
2590 insertion_paragraph_closed
= 0;
2595 if (!filling_enabled
&& !(html
&& (in_menu
|| in_detailmenu
)))
2599 if (force_flush_right
)
2602 /* Hack to force single blank lines out in this mode. */
2608 if (!no_indent
&& paragraph_is_open
)
2609 indent (output_column
= current_indent
);
2612 else if (end_of_sentence_p ())
2613 /* CHARACTER is newline, and filling is enabled. */
2617 last_inserted_character
= character
;
2620 if (last_char_was_newline
)
2623 last_char_was_newline
++;
2629 last_char_was_newline
= 1;
2638 default: /* not at newline */
2640 int len
= get_char_len (character
);
2641 int suppress_insert
= 0;
2643 if ((character
== ' ') && (last_char_was_newline
))
2645 if (!paragraph_is_open
)
2652 /* This is sad, but it seems desirable to not force any
2653 particular order on the front matter commands. This way,
2654 the document can do @settitle, @documentlanguage, etc, in
2655 any order and with any omissions, and we'll still output
2656 the html <head> `just in time'. */
2657 if ((executing_macro
|| !executing_string
)
2658 && !only_macro_expansion
2659 && html
&& !html_output_head_p
&& !defining_copying ())
2660 html_output_head ();
2662 if (!paragraph_is_open
)
2665 /* If the paragraph is supposed to be indented a certain
2666 way, then discard all of the pending whitespace.
2667 Otherwise, we let the whitespace stay. */
2668 if (!paragraph_start_indent
)
2669 indent (pending_indent
);
2672 /* This check for in_html_block_level_elt prevents <p> from being
2673 inserted when we already have html markup starting a paragraph,
2674 as with <ul> and <h1> and the like. */
2675 if (html
&& !in_html_block_level_elt
)
2677 if ((in_menu
|| in_detailmenu
) && in_menu_item
)
2679 insert_string ("</li></ul>\n");
2682 insert_string ("<p>");
2684 adjust_braces_following (0, 3); /* adjust for <p> */
2688 output_column
+= len
;
2689 if (output_column
> fill_column
)
2691 if (filling_enabled
&& !html
)
2693 int temp
= output_paragraph_offset
;
2694 while (--temp
> 0 && output_paragraph
[temp
] != '\n')
2696 /* If we have found a space, we have the place to break
2698 if (output_paragraph
[temp
] == ' ')
2700 /* Remove trailing whitespace from output. */
2701 while (temp
&& whitespace (output_paragraph
[temp
- 1]))
2704 /* If we went back all the way to the newline of the
2705 preceding line, it probably means that the word we
2706 are adding is itself wider than the space that the
2707 indentation and the fill_column let us use. In
2708 that case, do NOT insert another newline, since it
2709 won't help. Just indent to current_indent and
2710 leave it alone, since that's the most we can do. */
2711 if (temp
&& output_paragraph
[temp
- 1] != '\n')
2712 output_paragraph
[temp
++] = '\n';
2714 /* We have correctly broken the line where we want
2715 to. What we don't want is spaces following where
2716 we have decided to break the line. We get rid of
2723 if (t1
== output_paragraph_offset
)
2725 if (whitespace (character
))
2726 suppress_insert
= 1;
2729 if (!whitespace (output_paragraph
[t1
]))
2735 adjust_braces_following (temp
, (- (t1
- temp
)));
2736 memmove (&output_paragraph
[temp
],
2737 &output_paragraph
[t1
],
2738 output_paragraph_offset
- t1
);
2739 output_paragraph_offset
-= (t1
- temp
);
2743 /* Filled, but now indent if that is right. */
2744 if (indented_fill
&& current_indent
> 0)
2746 int buffer_len
= ((output_paragraph_offset
- temp
)
2748 char *temp_buffer
= xmalloc (buffer_len
);
2749 int indentation
= 0;
2751 /* We have to shift any markers that are in
2752 front of the wrap point. */
2753 adjust_braces_following (temp
, current_indent
);
2755 while (current_indent
> 0 &&
2756 indentation
!= current_indent
)
2757 temp_buffer
[indentation
++] = ' ';
2759 memcpy ((char *) &temp_buffer
[current_indent
],
2760 (char *) &output_paragraph
[temp
],
2761 buffer_len
- current_indent
);
2763 if (output_paragraph_offset
+ buffer_len
2764 >= paragraph_buffer_len
)
2766 unsigned char *tt
= xrealloc
2768 (paragraph_buffer_len
+= buffer_len
));
2769 output_paragraph
= tt
;
2771 memcpy ((char *) &output_paragraph
[temp
],
2772 temp_buffer
, buffer_len
);
2773 output_paragraph_offset
+= current_indent
;
2777 while (temp
< output_paragraph_offset
)
2779 get_char_len (output_paragraph
[temp
++]);
2780 output_column
+= len
;
2787 if (!suppress_insert
)
2790 last_inserted_character
= character
;
2792 last_char_was_newline
= 0;
2793 line_already_broken
= 0;
2798 /* Add a character and store its position in meta_char_pos. */
2800 add_meta_char (int character
)
2802 meta_char_pos
= output_paragraph_offset
;
2803 add_char (character
);
2806 /* Insert CHARACTER into `output_paragraph'. */
2808 insert (int character
)
2810 /* We don't want to strip trailing whitespace in multitables. Otherwise
2811 horizontal separators confuse the font locking in Info mode in Emacs,
2812 because it looks like a @subsection. Adding a trailing space to those
2814 if (character
== '\n' && !html
&& !xml
&& !multitable_active
)
2816 while (output_paragraph_offset
2817 && whitespace (output_paragraph
[output_paragraph_offset
-1]))
2818 output_paragraph_offset
--;
2821 output_paragraph
[output_paragraph_offset
++] = character
;
2822 if (output_paragraph_offset
== paragraph_buffer_len
)
2825 xrealloc (output_paragraph
, (paragraph_buffer_len
+= 100));
2829 /* Insert the null-terminated string STRING into `output_paragraph'. */
2831 insert_string (const char *string
)
2838 /* Sentences might have these characters after the period (or whatever). */
2839 #define POST_SENTENCE(c) ((c) == ')' || (c) == '\'' || (c) == '"' \
2842 /* Return true if at an end-of-sentence character, possibly followed by
2843 post-sentence punctuation to ignore. */
2845 end_of_sentence_p (void)
2847 int loc
= output_paragraph_offset
- 1;
2849 /* If nothing has been output, don't check output_paragraph[-1]. */
2853 /* A post-sentence character that is at meta_char_pos is not really
2854 a post-sentence character; it was produced by a markup such as
2855 @samp. We don't want the period inside @samp to be treated as a
2858 && loc
!= meta_char_pos
&& POST_SENTENCE (output_paragraph
[loc
]))
2860 return loc
!= meta_char_pos
&& sentence_ender (output_paragraph
[loc
]);
2864 /* Remove upto COUNT characters of whitespace from the
2865 the current output line. If COUNT is less than zero,
2866 then remove until none left. */
2868 kill_self_indent (int count
)
2870 /* Handle infinite case first. */
2874 while (output_paragraph_offset
)
2876 if (whitespace (output_paragraph
[output_paragraph_offset
- 1]))
2877 output_paragraph_offset
--;
2884 while (output_paragraph_offset
&& count
--)
2885 if (whitespace (output_paragraph
[output_paragraph_offset
- 1]))
2886 output_paragraph_offset
--;
2892 /* Nonzero means do not honor calls to flush_output (). */
2893 static int flushing_ignored
= 0;
2895 /* Prevent calls to flush_output () from having any effect. */
2897 inhibit_output_flushing (void)
2902 /* Allow calls to flush_output () to write the paragraph data. */
2904 uninhibit_output_flushing (void)
2914 if (!output_paragraph_offset
|| flushing_ignored
)
2917 for (i
= 0; i
< output_paragraph_offset
; i
++)
2919 if (output_paragraph
[i
] == '\n')
2921 output_line_number
++;
2925 /* If we turned on the 8th bit for a space inside @w, turn it
2926 back off for output. This might be problematic, since the
2927 0x80 character may be used in 8-bit character sets. Sigh.
2928 In any case, don't do this for HTML, since the nbsp character
2929 is valid input and must be passed along to the browser. */
2930 if (!html
&& (output_paragraph
[i
] & meta_character_bit
))
2932 int temp
= UNMETA (output_paragraph
[i
]);
2934 output_paragraph
[i
] &= 0x7f;
2938 fwrite (output_paragraph
, 1, output_paragraph_offset
, output_stream
);
2940 output_position
+= output_paragraph_offset
;
2941 output_paragraph_offset
= 0;
2945 /* How to close a paragraph controlling the number of lines between
2946 this one and the last one. */
2948 /* Paragraph spacing is controlled by this variable. It is the number of
2949 blank lines that you wish to appear between paragraphs. A value of
2950 1 creates a single blank line between paragraphs. */
2951 int paragraph_spacing
= DEFAULT_PARAGRAPH_SPACING
;
2954 close_paragraph_with_lines (int lines
)
2956 int old_spacing
= paragraph_spacing
;
2957 paragraph_spacing
= lines
;
2959 paragraph_spacing
= old_spacing
;
2962 /* Close the current paragraph, leaving no blank lines between them. */
2964 close_single_paragraph (void)
2966 close_paragraph_with_lines (0);
2969 /* Close a paragraph after an insertion has ended. */
2971 close_insertion_paragraph (void)
2973 if (!insertion_paragraph_closed
)
2975 /* Close the current paragraph, breaking the line. */
2976 close_single_paragraph ();
2978 /* Start a new paragraph, with the correct indentation for the now
2979 current insertion level (one above the one that we are ending). */
2982 /* Tell `close_paragraph' that the previous line has already been
2983 broken, so it should insert one less newline. */
2984 line_already_broken
= 1;
2986 /* Tell functions such as `add_char' we've already found a newline. */
2987 ignore_blank_line ();
2991 /* If the insertion paragraph is closed already, then we are seeing
2992 two `@end' commands in a row. Note that the first one we saw was
2993 handled in the first part of this if-then-else clause, and at that
2994 time `start_paragraph' was called, partially to handle the proper
2995 indentation of the current line. However, the indentation level
2996 may have just changed again, so we may have to outdent the current
2997 line to the new indentation level. */
2998 if (current_indent
< output_column
)
2999 kill_self_indent (output_column
- current_indent
);
3002 insertion_paragraph_closed
= 1;
3005 /* Close the currently open paragraph. */
3007 close_paragraph (void)
3011 /* We don't need these newlines in XML and Docbook outputs for
3012 paragraph seperation. We have <para> element for that. */
3016 /* The insertion paragraph is no longer closed. */
3017 insertion_paragraph_closed
= 0;
3019 if (paragraph_is_open
&& !must_start_paragraph
)
3021 int tindex
= output_paragraph_offset
;
3023 /* Back up to last non-newline/space character, forcing all such
3024 subsequent characters to be newlines. This isn't strictly
3025 necessary, but a couple of functions use the presence of a newline
3026 to make decisions. */
3027 for (tindex
= output_paragraph_offset
- 1; tindex
>= 0; --tindex
)
3029 int c
= output_paragraph
[tindex
];
3031 if (c
== ' '|| c
== '\n')
3032 output_paragraph
[tindex
] = '\n';
3037 /* All trailing whitespace is ignored. */
3038 output_paragraph_offset
= ++tindex
;
3040 /* Break the line if that is appropriate. */
3041 if (paragraph_spacing
>= 0)
3044 /* Add as many blank lines as is specified in `paragraph_spacing'. */
3045 if (!force_flush_right
)
3047 for (i
= 0; i
< (paragraph_spacing
- line_already_broken
); i
++)
3050 /* Don't need anything extra for HTML in usual case of no
3051 extra paragraph spacing. */
3053 insert_string ("<br>");
3057 /* If we are doing flush right indentation, then do it now
3058 on the paragraph (really a single line). */
3059 if (force_flush_right
)
3060 do_flush_right_indentation ();
3063 paragraph_is_open
= 0;
3068 ignore_blank_line ();
3071 /* Make the last line just read look as if it were only a newline. */
3073 ignore_blank_line (void)
3075 last_inserted_character
= '\n';
3076 last_char_was_newline
= 1;
3079 /* Align the end of the text in output_paragraph with fill_column. */
3081 do_flush_right_indentation (void)
3086 kill_self_indent (-1);
3088 if (output_paragraph
[0] != '\n')
3090 output_paragraph
[output_paragraph_offset
] = 0;
3092 if (output_paragraph_offset
< fill_column
)
3096 if (fill_column
>= paragraph_buffer_len
)
3098 xrealloc (output_paragraph
,
3099 (paragraph_buffer_len
+= fill_column
));
3101 temp_len
= strlen ((char *)output_paragraph
);
3102 temp
= xmalloc (temp_len
+ 1);
3103 memcpy (temp
, (char *)output_paragraph
, temp_len
);
3105 for (i
= 0; i
< fill_column
- output_paragraph_offset
; i
++)
3106 output_paragraph
[i
] = ' ';
3108 memcpy ((char *)output_paragraph
+ i
, temp
, temp_len
);
3110 output_paragraph_offset
= fill_column
;
3111 adjust_braces_following (0, i
);
3116 /* Begin a new paragraph. */
3118 start_paragraph (void)
3120 /* First close existing one. */
3121 if (paragraph_is_open
)
3124 /* In either case, the insertion paragraph is no longer closed. */
3125 insertion_paragraph_closed
= 0;
3127 /* However, the paragraph is open! */
3128 paragraph_is_open
= 1;
3130 /* If we MUST_START_PARAGRAPH, that simply means that start_paragraph ()
3131 had to be called before we would allow any other paragraph operations
3132 to have an effect. */
3133 if (!must_start_paragraph
)
3135 int amount_to_indent
= 0;
3137 /* If doing indentation, then insert the appropriate amount. */
3140 if (inhibit_paragraph_indentation
)
3142 amount_to_indent
= current_indent
;
3143 if (inhibit_paragraph_indentation
< 0)
3144 inhibit_paragraph_indentation
++;
3146 else if (paragraph_start_indent
< 0)
3147 amount_to_indent
= current_indent
;
3149 amount_to_indent
= current_indent
+ paragraph_start_indent
;
3151 if (amount_to_indent
>= output_column
)
3153 amount_to_indent
-= output_column
;
3154 indent (amount_to_indent
);
3155 output_column
+= amount_to_indent
;
3160 must_start_paragraph
= 0;
3163 /* Insert the indentation specified by AMOUNT. */
3167 /* For every START_POS saved within the brace stack which will be affected
3168 by this indentation, bump that start pos forward. */
3169 adjust_braces_following (output_paragraph_offset
, amount
);
3171 while (--amount
>= 0)
3175 /* Search forward for STRING in input_text.
3176 FROM says where where to start. */
3178 search_forward (char *string
, int from
)
3180 int len
= strlen (string
);
3182 while (from
< input_text_length
)
3184 if (strncmp (input_text
+ from
, string
, len
) == 0)
3191 /* search_forward until n characters. */
3193 search_forward_until_pos (char *string
, int from
, int end_pos
)
3195 int save_input_text_length
= input_text_length
;
3196 input_text_length
= end_pos
;
3198 from
= search_forward (string
, from
);
3200 input_text_length
= save_input_text_length
;
3205 /* Return next non-whitespace and non-cr character. */
3207 next_nonwhitespace_character (void)
3209 /* First check the current input_text. Start from the next char because
3210 we already have input_text[input_text_offset] in ``current''. */
3211 int pos
= input_text_offset
+ 1;
3213 while (pos
< input_text_length
)
3215 if (!cr_or_whitespace(input_text
[pos
]))
3216 return input_text
[pos
];
3220 { /* Can't find a valid character, so go through filestack
3221 in case we are doing @include or expanding a macro. */
3222 FSTACK
*tos
= filestack
;
3226 int tmp_input_text_length
= filestack
->size
;
3227 int tmp_input_text_offset
= filestack
->offset
;
3228 char *tmp_input_text
= filestack
->text
;
3230 while (tmp_input_text_offset
< tmp_input_text_length
)
3232 if (!cr_or_whitespace(tmp_input_text
[tmp_input_text_offset
]))
3233 return tmp_input_text
[tmp_input_text_offset
];
3234 tmp_input_text_offset
++;
3244 /* An external image is a reference, kind of. The parsing is (not
3245 coincidentally) similar, anyway. */
3249 char *name_arg
, *w_arg
, *h_arg
, *alt_arg
, *ext_arg
;
3254 name_arg
= get_xref_token (1); /* expands all macros in image */
3255 w_arg
= get_xref_token (0);
3256 h_arg
= get_xref_token (0);
3257 alt_arg
= get_xref_token (1); /* expands all macros in alt text */
3258 ext_arg
= get_xref_token (0);
3262 struct stat file_info
;
3263 char *pathname
= NULL
;
3264 char *fullname
= xmalloc (strlen (name_arg
)
3265 + (ext_arg
&& *ext_arg
? strlen (ext_arg
) + 1: 4) + 1);
3267 if (ext_arg
&& *ext_arg
)
3269 sprintf (fullname
, "%s%s", name_arg
, ext_arg
);
3270 if (access (fullname
, R_OK
) != 0)
3271 pathname
= get_file_info_in_path (fullname
, include_files_path
,
3274 if (pathname
== NULL
)
3276 /* Backwards compatibility (4.6 <= version < 4.7):
3277 try prefixing @image's EXTENSION parameter with a period. */
3278 sprintf (fullname
, "%s.%s", name_arg
, ext_arg
);
3279 if (access (fullname
, R_OK
) != 0)
3280 pathname
= get_file_info_in_path (fullname
, include_files_path
,
3286 sprintf (fullname
, "%s.png", name_arg
);
3287 if (access (fullname
, R_OK
) != 0) {
3288 pathname
= get_file_info_in_path (fullname
,
3289 include_files_path
, &file_info
);
3290 if (pathname
== NULL
) {
3291 sprintf (fullname
, "%s.jpg", name_arg
);
3292 if (access (fullname
, R_OK
) != 0) {
3293 sprintf (fullname
, "%s.gif", name_arg
);
3294 if (access (fullname
, R_OK
) != 0) {
3295 pathname
= get_file_info_in_path (fullname
,
3296 include_files_path
, &file_info
);
3305 int image_in_div
= 0;
3307 if (pathname
== NULL
&& access (fullname
, R_OK
) != 0)
3309 line_error(_("@image file `%s' (for HTML) not readable: %s"),
3310 fullname
, strerror (errno
));
3313 if (pathname
!= NULL
&& access (pathname
, R_OK
) != 0)
3315 line_error (_("No such file `%s'"),
3320 if (!paragraph_is_open
)
3322 add_html_block_elt ("<div class=\"block-image\">");
3326 add_html_elt ("<img src=");
3327 add_word_args ("\"%s\"", fullname
);
3328 add_html_elt (" alt=");
3329 add_word_args ("\"%s\">",
3330 escape_string (*alt_arg
? text_expansion (alt_arg
) : fullname
));
3333 add_html_block_elt ("</div>");
3335 else if (xml
&& docbook
)
3336 xml_insert_docbook_image (name_arg
);
3339 extern int xml_in_para
;
3340 extern int xml_no_para
;
3341 int elt
= xml_in_para
? INLINEIMAGE
: IMAGE
;
3346 xml_insert_element_with_attribute (elt
,
3347 START
, "width=\"%s\" height=\"%s\" name=\"%s\" extension=\"%s\"",
3348 w_arg
, h_arg
, name_arg
, ext_arg
);
3349 xml_insert_element (IMAGEALTTEXT
, START
);
3350 execute_string ("%s", alt_arg
);
3351 xml_insert_element (IMAGEALTTEXT
, END
);
3352 xml_insert_element (elt
, END
);
3358 { /* Try to open foo.EXT or foo.txt. */
3360 char *txtpath
= NULL
;
3361 char *txtname
= xmalloc (strlen (name_arg
)
3362 + (ext_arg
&& *ext_arg
3363 ? strlen (ext_arg
) : 4) + 1);
3364 strcpy (txtname
, name_arg
);
3365 strcat (txtname
, ".txt");
3366 image_file
= fopen (txtname
, "r");
3367 if (image_file
== NULL
)
3369 txtpath
= get_file_info_in_path (txtname
,
3370 include_files_path
, &file_info
);
3371 if (txtpath
!= NULL
)
3372 image_file
= fopen (txtpath
, "r");
3375 if (image_file
!= NULL
3376 || access (fullname
, R_OK
) == 0
3377 || (pathname
!= NULL
&& access (pathname
, R_OK
) == 0))
3380 int save_inhibit_indentation
= inhibit_paragraph_indentation
;
3381 int save_filling_enabled
= filling_enabled
;
3382 int image_in_brackets
= paragraph_is_open
;
3384 /* Write magic ^@^H[image ...^@^H] cookie in the info file, if
3385 there's an accompanying bitmap. Otherwise just include the
3386 text image. In the plaintext output, always include the text
3387 image without the magic cookie. */
3388 int use_magic_cookie
= !no_headers
3389 && access (fullname
, R_OK
) == 0 && !STREQ (fullname
, txtname
);
3391 inhibit_paragraph_indentation
= 1;
3392 filling_enabled
= 0;
3393 last_char_was_newline
= 0;
3395 if (use_magic_cookie
)
3398 add_word ("\010[image");
3400 if (access (fullname
, R_OK
) == 0
3401 || (pathname
!= NULL
&& access (pathname
, R_OK
) == 0))
3402 add_word_args (" src=\"%s\"", fullname
);
3405 add_word_args (" alt=\"%s\"", alt_arg
);
3408 if (image_file
!= NULL
)
3410 if (use_magic_cookie
)
3411 add_word (" text=\"");
3413 if (image_in_brackets
)
3416 /* Maybe we need to remove the final newline if the image
3417 file is only one line to allow in-line images. On the
3418 other hand, they could just make the file without a
3420 while ((ch
= getc (image_file
)) != EOF
)
3422 if (use_magic_cookie
&& (ch
== '"' || ch
== '\\'))
3427 if (image_in_brackets
)
3430 if (use_magic_cookie
)
3433 if (fclose (image_file
) != 0)
3437 if (use_magic_cookie
)
3443 inhibit_paragraph_indentation
= save_inhibit_indentation
;
3444 filling_enabled
= save_filling_enabled
;
3447 warning (_("@image file `%s' (for text) unreadable: %s"),
3448 txtname
, strerror (errno
));
3456 line_error (_("@image missing filename argument"));
3472 /* A structure which contains `defined' variables. */
3473 typedef struct defines
{
3474 struct defines
*next
;
3479 /* The linked list of `set' defines. */
3480 DEFINE
*defines
= NULL
;
3482 /* Add NAME to the list of `set' defines. */
3484 set (char *name
, char *value
)
3488 for (temp
= defines
; temp
; temp
= temp
->next
)
3489 if (strcmp (name
, temp
->name
) == 0)
3492 temp
->value
= xstrdup (value
);
3496 temp
= xmalloc (sizeof (DEFINE
));
3497 temp
->next
= defines
;
3498 temp
->name
= xstrdup (name
);
3499 temp
->value
= xstrdup (value
);
3502 if (xml
&& !docbook
)
3504 xml_insert_element_with_attribute (SETVALUE
, START
, "name=\"%s\"", name
);
3505 execute_string ("%s", value
);
3506 xml_insert_element (SETVALUE
, END
);
3510 /* Remove NAME from the list of `set' defines. */
3514 DEFINE
*temp
, *last
;
3521 if (strcmp (temp
->name
, name
) == 0)
3524 last
->next
= temp
->next
;
3526 defines
= temp
->next
;
3537 if (xml
&& !docbook
)
3539 xml_insert_element_with_attribute (CLEARVALUE
, START
, "name=\"%s\"", name
);
3540 xml_insert_element (CLEARVALUE
, END
);
3544 /* Return the value of NAME. The return value is NULL if NAME is unset. */
3550 for (temp
= defines
; temp
; temp
= temp
->next
)
3551 if (strcmp (temp
->name
, name
) == 0)
3557 /* Create a variable whose name appears as the first word on this line. */
3561 handle_variable (SET
);
3564 /* Remove a variable whose name appears as the first word on this line. */
3568 handle_variable (CLEAR
);
3574 handle_variable (IFSET
);
3580 handle_variable (IFCLEAR
);
3583 /* This command takes braces, but we parse the contents specially, so we
3584 don't use the standard brace popping code.
3586 The syntax @ifeq{arg1, arg2, texinfo-commands} performs texinfo-commands
3587 if ARG1 and ARG2 caselessly string compare to the same string, otherwise,
3588 it produces no output. */
3594 arglist
= get_brace_args (0);
3598 if (array_len (arglist
) > 1)
3600 if ((strcasecmp (arglist
[0], arglist
[1]) == 0) &&
3602 execute_string ("%s\n", arglist
[2]);
3605 free_array (arglist
);
3610 cm_value (int arg
, int start_pos
, int end_pos
)
3612 static int value_level
= 0, saved_meta_pos
= -1;
3614 /* xml_add_char() skips any content inside menus when output format is
3615 Docbook, so @value{} is no use there. Also start_pos and end_pos does not
3616 get updated, causing name to be empty string. So just return. */
3617 if (docbook
&& in_menu
)
3620 /* All the text after @value{ upto the matching } will eventually
3621 disappear from output_paragraph, when this function is called
3622 with ARG == END. If the text produced until then sets
3623 meta_char_pos, we will need to restore it to the value it had
3624 before @value was seen. So we need to save the previous value
3625 of meta_char_pos here. */
3628 /* If we are already inside some outer @value, don't overwrite
3629 the value saved in saved_meta_pos. */
3631 saved_meta_pos
= meta_char_pos
;
3633 /* While the argument of @value is processed, we need to inhibit
3634 textual transformations like "--" into "-", since @set didn't
3635 do that when it grabbed the name of the variable. */
3636 in_fixed_width_font
++;
3640 char *name
= (char *) &output_paragraph
[start_pos
];
3642 output_paragraph
[end_pos
] = 0;
3643 name
= xstrdup (name
);
3644 value
= set_p (name
);
3645 output_column
-= end_pos
- start_pos
;
3646 output_paragraph_offset
= start_pos
;
3648 /* Restore the previous value of meta_char_pos if the stuff
3649 inside this @value{} moved it. */
3650 if (saved_meta_pos
== -1) /* can't happen inside @value{} */
3652 if (value_level
== 1
3653 && meta_char_pos
>= start_pos
&& meta_char_pos
< end_pos
)
3655 meta_char_pos
= saved_meta_pos
;
3656 saved_meta_pos
= -1;
3659 /* No need to decrement in_fixed_width_font, since before
3660 we are called with arg == END, the reader loop already
3661 popped the brace stack, which restored in_fixed_width_font,
3662 among other things. */
3666 /* We need to get past the closing brace since the value may
3667 expand to a context-sensitive macro (e.g. @xref) and produce
3668 spurious warnings */
3669 input_text_offset
++;
3670 execute_string ("%s", value
);
3671 input_text_offset
--;
3675 warning (_("undefined flag: %s"), name
);
3676 add_word_args (_("{No value for `%s'}"), name
);
3683 /* Set, clear, or conditionalize based on ACTION. */
3685 handle_variable (int action
)
3689 get_rest_of_line (0, &name
);
3690 /* If we hit the end of text in get_rest_of_line, backing up
3691 input pointer will cause the last character of the last line
3692 be pushed back onto the input, which is wrong. */
3693 if (input_text_offset
< input_text_length
)
3694 backup_input_pointer ();
3695 handle_variable_internal (action
, name
);
3700 handle_variable_internal (int action
, char *name
)
3703 int delimiter
, additional_text_present
= 0;
3705 /* Only the first word of NAME is a valid tag. */
3708 while (*temp
&& (delimiter
|| !whitespace (*temp
)))
3710 /* #if defined (SET_WITH_EQUAL) */
3711 if (*temp
== '"' || *temp
== '\'')
3713 if (*temp
== delimiter
)
3718 /* #endif SET_WITH_EQUAL */
3723 additional_text_present
++;
3728 line_error (_("%c%s requires a name"), COMMAND_PREFIX
, command
);
3737 #if defined (SET_WITH_EQUAL)
3738 /* Allow a value to be saved along with a variable. The value is
3739 the text following an `=' sign in NAME, if any is present. */
3741 for (value
= name
; *value
&& *value
!= '='; value
++);
3746 if (*value
== '"' || *value
== '\'')
3749 value
[strlen (value
) - 1] = 0;
3752 #else /* !SET_WITH_EQUAL */
3753 /* The VALUE of NAME is the remainder of the line sans
3755 if (additional_text_present
)
3758 canon_white (value
);
3762 #endif /* !SET_WITH_VALUE */
3774 /* If IFSET and NAME is not set, or if IFCLEAR and NAME is set,
3775 read lines from the the file until we reach a matching
3776 "@end CONDITION". This means that we only take note of
3777 "@ifset/clear" and "@end" commands. */
3781 int orig_line_number
= line_number
;
3783 if (action
== IFSET
)
3784 strcpy (condition
, "ifset");
3786 strcpy (condition
, "ifclear");
3788 condition_len
= strlen (condition
);
3790 if ((action
== IFSET
&& !set_p (name
))
3791 || (action
== IFCLEAR
&& set_p (name
)))
3793 int level
= 0, done
= 0;
3795 while (!done
&& input_text_offset
< input_text_length
)
3797 char *freeable_line
, *line
;
3799 get_rest_of_line (0, &freeable_line
);
3801 for (line
= freeable_line
; whitespace (*line
); line
++);
3803 if (*line
== COMMAND_PREFIX
&&
3804 (strncmp (line
+ 1, condition
, condition_len
) == 0))
3806 else if (strncmp (line
, "@end", 4) == 0)
3808 char *cname
= line
+ 4;
3811 while (*cname
&& whitespace (*cname
))
3815 while (*temp
&& !whitespace (*temp
))
3819 if (strcmp (cname
, condition
) == 0)
3829 free (freeable_line
);
3833 file_line_error (input_filename
, orig_line_number
,
3834 _("Reached eof before matching @end %s"),
3837 /* We found the end of a false @ifset/ifclear. If we are
3838 in a menu, back up over the newline that ends the ifset,
3839 since that newline may also begin the next menu entry. */
3844 if (action
== IFSET
)
3845 begin_insertion (ifset
);
3847 begin_insertion (ifclear
);
3855 /* Execution of random text not in file. */
3857 char *string
; /* The string buffer. */
3858 int size
; /* The size of the buffer. */
3859 int in_use
; /* Nonzero means string currently in use. */
3862 static EXECUTION_STRING
**execution_strings
= NULL
;
3863 static int execution_strings_index
= 0;
3864 static int execution_strings_slots
= 0;
3866 static EXECUTION_STRING
*
3867 get_execution_string (int initial_size
)
3870 EXECUTION_STRING
*es
= NULL
;
3872 if (execution_strings
)
3874 for (i
= 0; i
< execution_strings_index
; i
++)
3875 if (execution_strings
[i
] && (execution_strings
[i
]->in_use
== 0))
3877 es
= execution_strings
[i
];
3884 if (execution_strings_index
+ 1 >= execution_strings_slots
)
3886 execution_strings
= xrealloc
3888 (execution_strings_slots
+= 3) * sizeof (EXECUTION_STRING
*));
3889 for (; i
< execution_strings_slots
; i
++)
3890 execution_strings
[i
] = NULL
;
3893 execution_strings
[execution_strings_index
] =
3894 xmalloc (sizeof (EXECUTION_STRING
));
3895 es
= execution_strings
[execution_strings_index
];
3896 execution_strings_index
++;
3903 if (initial_size
> es
->size
)
3905 es
->string
= xrealloc (es
->string
, initial_size
);
3906 es
->size
= initial_size
;
3911 /* Given a pointer to TEXT and its desired length NEW_LEN, find TEXT's
3912 entry in the execution_strings[] array and change the .STRING and
3913 .SIZE members of that entry as appropriate. */
3915 maybe_update_execution_strings (char **text
, unsigned int new_len
)
3919 if (execution_strings
)
3921 for (i
= 0; i
< execution_strings_index
; i
++)
3922 if (execution_strings
[i
] && (execution_strings
[i
]->in_use
== 1) &&
3923 execution_strings
[i
]->string
== *text
)
3925 /* Don't ever shrink the string storage in execution_strings[]!
3926 execute_string assumes that it is always big enough to store
3927 every possible execution_string, and will break if that's
3928 not true. So we only enlarge the string storage if the
3929 current size isn't big enough. */
3930 if (execution_strings
[i
]->size
< new_len
)
3932 execution_strings
[i
]->string
=
3933 *text
= xrealloc (*text
, new_len
+ 1);
3934 execution_strings
[i
]->size
= new_len
+ 1;
3939 /* We should *never* end up here, since if we are inside
3940 execute_string, TEXT is always in execution_strings[]. */
3944 /* FIXME: this is an arbitrary limit. */
3945 #define EXECUTE_STRING_MAX 16*1024
3947 /* Execute the string produced by formatting the ARGs with FORMAT. This
3948 is like submitting a new file with @include. */
3950 #if defined (VA_FPRINTF) && __STDC__
3951 execute_string (char *format
, ...)
3953 execute_string (format
, va_alist
)
3958 EXECUTION_STRING
*es
;
3959 char *temp_string
, *temp_input_filename
;
3963 int insertion_level_at_start
= insertion_level
;
3965 es
= get_execution_string (EXECUTE_STRING_MAX
);
3966 temp_string
= es
->string
;
3969 VA_START (ap
, format
);
3971 VA_SPRINTF (temp_string
, format
, ap
);
3973 sprintf (temp_string
, format
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
);
3974 #endif /* not VA_SPRINTF */
3978 input_text_offset
= 0;
3979 input_text
= temp_string
;
3980 input_text_length
= strlen (temp_string
);
3981 input_filename
= xstrdup (input_filename
);
3982 temp_input_filename
= input_filename
;
3987 /* If insertion stack level changes during execution, that means a multiline
3988 command is used inside braces or @section ... kind of commands. */
3989 if (insertion_level_at_start
!= insertion_level
&& !executing_macro
)
3991 line_error (_("Multiline command %c%s used improperly"),
3994 /* We also need to keep insertion_level intact to make sure warnings are
3995 issued for @end ... command. */
3996 while (insertion_level
> insertion_level_at_start
)
4003 free (temp_input_filename
);
4007 /* Return what would be output for STR (in newly-malloced memory), i.e.,
4008 expand Texinfo commands according to the current output format. If
4009 IMPLICIT_CODE is set, expand @code{STR}. This is generally used for
4010 short texts; filling, indentation, and html escapes are disabled. */
4013 expansion (char *str
, int implicit_code
)
4015 return maybe_escaped_expansion (str
, implicit_code
, 0);
4019 /* Do HTML escapes according to DO_HTML_ESCAPE. Needed in
4020 cm_printindex, q.v. */
4023 maybe_escaped_expansion (char *str
, int implicit_code
, int do_html_escape
)
4027 /* Inhibit indentation and filling, so that extra newlines
4028 are not added to the expansion. (This is undesirable if
4029 we write the expanded text to macro_expansion_output_stream.) */
4030 int saved_filling_enabled
= filling_enabled
;
4031 int saved_indented_fill
= indented_fill
;
4032 int saved_no_indent
= no_indent
;
4033 int saved_escape_html
= escape_html
;
4035 filling_enabled
= 0;
4038 escape_html
= do_html_escape
;
4040 result
= full_expansion (str
, implicit_code
);
4042 filling_enabled
= saved_filling_enabled
;
4043 indented_fill
= saved_indented_fill
;
4044 no_indent
= saved_no_indent
;
4045 escape_html
= saved_escape_html
;
4051 /* Expand STR (or @code{STR} if IMPLICIT_CODE is nonzero). No change to
4052 any formatting parameters -- filling, indentation, html escapes,
4053 etc., are not reset. Always returned in new memory. */
4056 full_expansion (char *str
, int implicit_code
)
4061 /* Inhibit any real output. */
4062 int start
= output_paragraph_offset
;
4063 int saved_paragraph_is_open
= paragraph_is_open
;
4064 int saved_output_column
= output_column
;
4066 /* More output state to save. */
4067 int saved_meta_pos
= meta_char_pos
;
4068 int saved_last_char
= last_inserted_character
;
4069 int saved_last_nl
= last_char_was_newline
;
4071 /* If we are called in the middle of processing a command, we need
4072 to dup and save the global variable `command' (which holds the
4073 name of this command), since the recursive reader loop will free
4074 it from under our feet if it finds any macros in STR. */
4075 char *saved_command
= command
? xstrdup (command
) : NULL
;
4077 inhibit_output_flushing ();
4078 paragraph_is_open
= 1;
4079 if (strlen (str
) > (implicit_code
4080 ? EXECUTE_STRING_MAX
- 1 - sizeof("@code{}")
4081 : EXECUTE_STRING_MAX
- 1))
4082 line_error (_("`%.40s...' is too long for expansion; not expanded"), str
);
4084 execute_string (implicit_code
? "@code{%s}" : "%s", str
);
4085 uninhibit_output_flushing ();
4087 /* Copy the expansion from the buffer. */
4088 length
= output_paragraph_offset
- start
;
4089 result
= xmalloc (1 + length
);
4090 memcpy (result
, (char *) (output_paragraph
+ start
), length
);
4093 /* Pretend it never happened. */
4094 free_and_clear (&command
);
4095 command
= saved_command
;
4097 output_paragraph_offset
= start
;
4098 paragraph_is_open
= saved_paragraph_is_open
;
4099 output_column
= saved_output_column
;
4101 meta_char_pos
= saved_meta_pos
;
4102 last_inserted_character
= saved_last_char
;
4103 last_char_was_newline
= saved_last_nl
;
4109 /* Return text (info) expansion of STR no matter what the current output
4113 text_expansion (char *str
)
4116 int save_html
= html
;
4118 int save_docbook
= docbook
;
4123 ret
= expansion (str
, 0);
4126 docbook
= save_docbook
;
4132 /* Set the paragraph indentation variable to the value specified in STRING.
4134 `asis': Don't change existing indentation.
4135 `none': Remove existing indentation.
4136 NUM: Indent NUM spaces at the starts of paragraphs.
4137 If NUM is zero, we assume `none'.
4138 Returns 0 if successful, or nonzero if STRING isn't one of the above. */
4140 set_paragraph_indent (char *string
)
4142 if (strcmp (string
, "asis") == 0 || strcmp (string
, _("asis")) == 0)
4143 paragraph_start_indent
= 0;
4144 else if (strcmp (string
, "none") == 0 || strcmp (string
, _("none")) == 0)
4145 paragraph_start_indent
= -1;
4148 if (sscanf (string
, "%d", ¶graph_start_indent
) != 1)
4152 if (paragraph_start_indent
== 0)
4153 paragraph_start_indent
= -1;