summaryrefslogtreecommitdiffstats
path: root/contrib/texinfo/makeinfo
diff options
context:
space:
mode:
authorru <ru@FreeBSD.org>2005-05-23 10:46:22 +0000
committerru <ru@FreeBSD.org>2005-05-23 10:46:22 +0000
commit212fa58b27874a1ac997e85e3f696ffad810e44c (patch)
tree3fc59092050a7fe0bd61c1e105cf78dc1c99d284 /contrib/texinfo/makeinfo
parent007f372a86653605d72852e22dcd423d0276786c (diff)
downloadFreeBSD-src-212fa58b27874a1ac997e85e3f696ffad810e44c.zip
FreeBSD-src-212fa58b27874a1ac997e85e3f696ffad810e44c.tar.gz
Import of stripped down GNU texinfo 4.8
Diffstat (limited to 'contrib/texinfo/makeinfo')
-rw-r--r--contrib/texinfo/makeinfo/README2
-rw-r--r--contrib/texinfo/makeinfo/cmds.c1012
-rw-r--r--contrib/texinfo/makeinfo/cmds.h168
-rw-r--r--contrib/texinfo/makeinfo/defun.c396
-rw-r--r--contrib/texinfo/makeinfo/defun.h6
-rw-r--r--contrib/texinfo/makeinfo/files.c407
-rw-r--r--contrib/texinfo/makeinfo/files.h45
-rw-r--r--contrib/texinfo/makeinfo/float.c430
-rw-r--r--contrib/texinfo/makeinfo/float.h56
-rw-r--r--contrib/texinfo/makeinfo/footnote.c58
-rw-r--r--contrib/texinfo/makeinfo/footnote.h13
-rw-r--r--contrib/texinfo/makeinfo/html.c591
-rw-r--r--contrib/texinfo/makeinfo/html.h32
-rw-r--r--contrib/texinfo/makeinfo/index.c432
-rw-r--r--contrib/texinfo/makeinfo/index.h65
-rw-r--r--contrib/texinfo/makeinfo/insertion.c1076
-rw-r--r--contrib/texinfo/makeinfo/insertion.h46
-rw-r--r--contrib/texinfo/makeinfo/lang.c393
-rw-r--r--contrib/texinfo/makeinfo/lang.h66
-rw-r--r--contrib/texinfo/makeinfo/macro.c146
-rw-r--r--contrib/texinfo/makeinfo/macro.h38
-rw-r--r--contrib/texinfo/makeinfo/makeinfo.c1705
-rw-r--r--contrib/texinfo/makeinfo/makeinfo.h116
-rw-r--r--contrib/texinfo/makeinfo/multi.c513
-rw-r--r--contrib/texinfo/makeinfo/multi.h28
-rw-r--r--contrib/texinfo/makeinfo/node.c334
-rw-r--r--contrib/texinfo/makeinfo/node.h28
-rw-r--r--contrib/texinfo/makeinfo/sectioning.c406
-rw-r--r--contrib/texinfo/makeinfo/sectioning.h61
-rw-r--r--contrib/texinfo/makeinfo/toc.c286
-rw-r--r--contrib/texinfo/makeinfo/toc.h17
-rw-r--r--contrib/texinfo/makeinfo/xml.c1915
-rw-r--r--contrib/texinfo/makeinfo/xml.h113
-rw-r--r--contrib/texinfo/makeinfo/xref.c620
-rw-r--r--contrib/texinfo/makeinfo/xref.h30
35 files changed, 7864 insertions, 3786 deletions
diff --git a/contrib/texinfo/makeinfo/README b/contrib/texinfo/makeinfo/README
index 4d2ecf6..17c4371 100644
--- a/contrib/texinfo/makeinfo/README
+++ b/contrib/texinfo/makeinfo/README
@@ -1,4 +1,4 @@
-$Id: README,v 1.2 2002/09/11 16:32:09 karl Exp $
+$Id: README,v 1.3 2004/04/11 17:56:46 karl Exp $
texinfo/makeinfo/README
Copyright (C) 2002 Free Software Foundation, Inc.
diff --git a/contrib/texinfo/makeinfo/cmds.c b/contrib/texinfo/makeinfo/cmds.c
index db9472b..87ac7bb 100644
--- a/contrib/texinfo/makeinfo/cmds.c
+++ b/contrib/texinfo/makeinfo/cmds.c
@@ -1,7 +1,7 @@
/* cmds.c -- Texinfo commands.
- $Id: cmds.c,v 1.18 2003/04/21 01:02:39 karl Exp $
+ $Id: cmds.c,v 1.55 2004/12/14 00:15:36 karl Exp $
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
Foundation, Inc.
This program is free software; you can redistribute it and/or modify
@@ -39,70 +39,32 @@
#include <time.h>
#endif
-
-void insert_self (), insert_space (), cm_ignore_line (), cm_ignore_arg ();
-
-void
- cm_TeX (), cm_acronym (), cm_asterisk (), cm_b (), cm_bullet (), cm_cite (),
- cm_code (), cm_copyright (), cm_ctrl (), cm_dfn (), cm_dircategory (),
- cm_direntry (), cm_dmn (), cm_dots (), cm_emph (), cm_enddots (), cm_i (),
- cm_image (), cm_kbd (), cm_key (), cm_no_op (),
- cm_novalidate (), cm_not_fixed_width (), cm_r (),
- cm_strong (), cm_var (), cm_sc (), cm_w (), cm_email (), cm_url (),
- cm_verb (), cm_copying (), cm_insert_copying (),
- cm_documentdescription ();
-
-void
- cm_anchor (), cm_node (), cm_menu (), cm_xref (), cm_ftable (),
- cm_vtable (), cm_pxref (), cm_inforef (), cm_uref (), cm_email (),
- cm_quotation (), cm_display (), cm_smalldisplay (), cm_itemize (),
- cm_enumerate (), cm_tab (), cm_table (), cm_itemx (),
- cm_noindent (), cm_indent (),
- cm_setfilename (), cm_br (), cm_sp (), cm_page (), cm_group (),
- cm_center (), cm_ref (), cm_include (), cm_bye (), cm_item (), cm_end (),
- cm_kindex (), cm_cindex (), cm_findex (), cm_pindex (), cm_vindex (),
- cm_tindex (), cm_synindex (), cm_printindex (), cm_minus (),
- cm_example (), cm_smallexample (), cm_smalllisp (), cm_lisp (),
- cm_format (), cm_smallformat (), cm_exdent (), cm_defindex (),
- cm_defcodeindex (), cm_result (), cm_expansion (), cm_equiv (),
- cm_print (), cm_error (), cm_point (), cm_today (), cm_flushleft (),
- cm_flushright (), cm_finalout (), cm_cartouche (), cm_detailmenu (),
- cm_multitable (), cm_settitle (), cm_titlefont (), cm_titlepage (),
- cm_tie (), cm_tt (),
- cm_verbatim (), cm_verbatiminclude ();
-
-/* Conditionals. */
-void cm_set (), cm_clear (), cm_ifset (), cm_ifclear ();
-void cm_value (), cm_ifeq ();
-
/* Options. */
-static void
- cm_exampleindent (),
- cm_firstparagraphindent (),
- cm_paragraphindent ();
+static void cm_exampleindent (void),
+ cm_firstparagraphindent (void),
+ cm_paragraphindent (void),
+ cm_novalidate (void);
/* Internals. */
-static void cm_obsolete ();
-
-/* A random string. */
-static const char small_tag[] = "small";
+static void cm_obsolete (int arg, int start, int end),
+ not_fixed_width (int arg);
/* The dispatch table. */
COMMAND command_table[] = {
{ "\t", insert_space, NO_BRACE_ARGS },
{ "\n", insert_space, NO_BRACE_ARGS },
{ " ", insert_space, NO_BRACE_ARGS },
- { "!", insert_self, NO_BRACE_ARGS },
+ { "!", cm_punct, NO_BRACE_ARGS },
{ "\"", cm_accent_umlaut, MAYBE_BRACE_ARGS },
{ "'", cm_accent_acute, MAYBE_BRACE_ARGS },
{ "*", cm_asterisk, NO_BRACE_ARGS },
{ ",", cm_accent_cedilla, MAYBE_BRACE_ARGS },
{ "-", cm_no_op, NO_BRACE_ARGS },
- { ".", insert_self, NO_BRACE_ARGS },
+ { ".", cm_punct, NO_BRACE_ARGS },
{ "/", cm_no_op, NO_BRACE_ARGS },
- { ":", cm_no_op, NO_BRACE_ARGS },
+ { ":", cm_colon, NO_BRACE_ARGS },
{ "=", cm_accent, MAYBE_BRACE_ARGS },
- { "?", insert_self, NO_BRACE_ARGS },
+ { "?", cm_punct, NO_BRACE_ARGS },
{ "@", insert_self, NO_BRACE_ARGS },
{ "\\", insert_self, NO_BRACE_ARGS },
{ "^", cm_accent_hat, MAYBE_BRACE_ARGS },
@@ -115,10 +77,12 @@ COMMAND command_table[] = {
{ "AE", cm_special_char, BRACE_ARGS },
{ "H", cm_accent, MAYBE_BRACE_ARGS },
{ "L", cm_special_char, BRACE_ARGS },
+ { "LaTeX", cm_LaTeX, BRACE_ARGS },
{ "O", cm_special_char, BRACE_ARGS },
{ "OE", cm_special_char, BRACE_ARGS },
{ "TeX", cm_TeX, BRACE_ARGS },
{ "aa", cm_special_char, BRACE_ARGS },
+ { "abbr", cm_abbr, BRACE_ARGS },
{ "acronym", cm_acronym, BRACE_ARGS },
{ "ae", cm_special_char, BRACE_ARGS },
{ "afivepaper", cm_ignore_line, NO_BRACE_ARGS },
@@ -133,10 +97,12 @@ COMMAND command_table[] = {
{ "appendixsubsec", cm_appendixsubsec, NO_BRACE_ARGS },
{ "appendixsubsubsec", cm_appendixsubsubsec, NO_BRACE_ARGS },
{ "asis", cm_no_op, BRACE_ARGS },
+ { "author", cm_author, NO_BRACE_ARGS },
{ "b", cm_b, BRACE_ARGS },
{ "bullet", cm_bullet, BRACE_ARGS },
{ "bye", cm_bye, NO_BRACE_ARGS },
- { "c", cm_ignore_line, NO_BRACE_ARGS },
+ { "c", cm_comment, NO_BRACE_ARGS },
+ { "caption", cm_caption, BRACE_ARGS },
{ "cartouche", cm_cartouche, NO_BRACE_ARGS },
{ "center", cm_center, NO_BRACE_ARGS },
{ "centerchap", cm_unnumbered, NO_BRACE_ARGS },
@@ -146,8 +112,9 @@ COMMAND command_table[] = {
{ "cite", cm_cite, BRACE_ARGS },
{ "clear", cm_clear, NO_BRACE_ARGS },
{ "code", cm_code, BRACE_ARGS },
+ { "comma", cm_comma, BRACE_ARGS },
{ "command", cm_code, BRACE_ARGS },
- { "comment", cm_ignore_line, NO_BRACE_ARGS },
+ { "comment", cm_comment, NO_BRACE_ARGS },
{ "contents", cm_contents, NO_BRACE_ARGS },
{ "copying", cm_copying, NO_BRACE_ARGS },
{ "copyright", cm_copyright, BRACE_ARGS },
@@ -173,6 +140,8 @@ COMMAND command_table[] = {
{ "defspecx", cm_defun, NO_BRACE_ARGS },
{ "deftp", cm_defun, NO_BRACE_ARGS },
{ "deftpx", cm_defun, NO_BRACE_ARGS },
+ { "deftypecv", cm_defun, NO_BRACE_ARGS },
+ { "deftypecvx", cm_defun, NO_BRACE_ARGS },
{ "deftypefn", cm_defun, NO_BRACE_ARGS },
{ "deftypefnx", cm_defun, NO_BRACE_ARGS },
{ "deftypefun", cm_defun, NO_BRACE_ARGS },
@@ -198,7 +167,8 @@ COMMAND command_table[] = {
{ "dircategory", cm_dircategory, NO_BRACE_ARGS },
{ "direntry", cm_direntry, NO_BRACE_ARGS },
{ "display", cm_display, NO_BRACE_ARGS },
- { "dmn", cm_no_op, BRACE_ARGS },
+ { "dmn", cm_dmn, BRACE_ARGS },
+ { "docbook", cm_docbook, NO_BRACE_ARGS },
{ "documentdescription", cm_documentdescription, NO_BRACE_ARGS },
{ "documentencoding", cm_documentencoding, NO_BRACE_ARGS },
{ "documentlanguage", cm_documentlanguage, NO_BRACE_ARGS },
@@ -213,6 +183,7 @@ COMMAND command_table[] = {
{ "env", cm_code, BRACE_ARGS },
{ "equiv", cm_equiv, BRACE_ARGS },
{ "error", cm_error, BRACE_ARGS },
+ { "euro", cm_special_char, BRACE_ARGS },
{ "evenfooting", cm_ignore_line, NO_BRACE_ARGS },
{ "evenheading", cm_ignore_line, NO_BRACE_ARGS },
{ "everyfooting", cm_ignore_line, NO_BRACE_ARGS },
@@ -226,6 +197,7 @@ COMMAND command_table[] = {
{ "finalout", cm_no_op, NO_BRACE_ARGS },
{ "findex", cm_findex, NO_BRACE_ARGS },
{ "firstparagraphindent", cm_firstparagraphindent, NO_BRACE_ARGS },
+ { "float", cm_float, NO_BRACE_ARGS },
{ "flushleft", cm_flushleft, NO_BRACE_ARGS },
{ "flushright", cm_flushright, NO_BRACE_ARGS },
{ "footnote", cm_footnote, NO_BRACE_ARGS}, /* self-arg eater */
@@ -235,13 +207,16 @@ COMMAND command_table[] = {
{ "group", cm_group, NO_BRACE_ARGS },
{ "heading", cm_heading, NO_BRACE_ARGS },
{ "headings", cm_ignore_line, NO_BRACE_ARGS },
+ { "headitem", cm_headitem, NO_BRACE_ARGS },
{ "html", cm_html, NO_BRACE_ARGS },
{ "hyphenation", cm_ignore_arg, BRACE_ARGS },
{ "i", cm_i, BRACE_ARGS },
{ "ifclear", cm_ifclear, NO_BRACE_ARGS },
{ "ifeq", cm_ifeq, NO_BRACE_ARGS },
+ { "ifdocbook", cm_ifdocbook, NO_BRACE_ARGS },
{ "ifhtml", cm_ifhtml, NO_BRACE_ARGS },
{ "ifinfo", cm_ifinfo, NO_BRACE_ARGS },
+ { "ifnotdocbook", cm_ifnotdocbook, NO_BRACE_ARGS },
{ "ifnothtml", cm_ifnothtml, NO_BRACE_ARGS },
{ "ifnotinfo", cm_ifnotinfo, NO_BRACE_ARGS },
{ "ifnotplaintext", cm_ifnotplaintext, NO_BRACE_ARGS },
@@ -255,6 +230,7 @@ COMMAND command_table[] = {
{ "image", cm_image, BRACE_ARGS },
{ "include", cm_include, NO_BRACE_ARGS },
{ "indent", cm_indent, NO_BRACE_ARGS },
+ { "indicateurl", cm_indicate_url, BRACE_ARGS },
{ "inforef", cm_inforef, BRACE_ARGS },
{ "insertcopying", cm_insert_copying, NO_BRACE_ARGS },
{ "item", cm_item, NO_BRACE_ARGS },
@@ -266,16 +242,17 @@ COMMAND command_table[] = {
{ "kindex", cm_kindex, NO_BRACE_ARGS },
{ "l", cm_special_char, BRACE_ARGS },
{ "lisp", cm_lisp, NO_BRACE_ARGS },
+ { "listoffloats", cm_listoffloats, NO_BRACE_ARGS },
{ "lowersections", cm_lowersections, NO_BRACE_ARGS },
{ "macro", cm_macro, NO_BRACE_ARGS },
{ "majorheading", cm_majorheading, NO_BRACE_ARGS },
- { "math", cm_no_op, BRACE_ARGS },
+ { "math", cm_math, BRACE_ARGS },
{ "menu", cm_menu, NO_BRACE_ARGS },
{ "minus", cm_minus, BRACE_ARGS },
{ "multitable", cm_multitable, NO_BRACE_ARGS },
{ "need", cm_ignore_line, NO_BRACE_ARGS },
{ "node", cm_node, NO_BRACE_ARGS },
- { "noindent", cm_noindent, NO_BRACE_ARGS },
+ { "noindent", cm_noindent_cmd, NO_BRACE_ARGS },
{ "novalidate", cm_novalidate, NO_BRACE_ARGS },
{ "nwnode", cm_node, NO_BRACE_ARGS },
{ "o", cm_special_char, BRACE_ARGS },
@@ -283,6 +260,8 @@ COMMAND command_table[] = {
{ "oddheading", cm_ignore_line, NO_BRACE_ARGS },
{ "oe", cm_special_char, BRACE_ARGS },
{ "option", cm_code, BRACE_ARGS },
+ { "ordf", cm_special_char, BRACE_ARGS },
+ { "ordm", cm_special_char, BRACE_ARGS },
{ "page", cm_no_op, NO_BRACE_ARGS },
{ "pagesizes", cm_ignore_line, NO_BRACE_ARGS },
{ "paragraphindent", cm_paragraphindent, NO_BRACE_ARGS },
@@ -298,10 +277,12 @@ COMMAND command_table[] = {
{ "raisesections", cm_raisesections, NO_BRACE_ARGS },
{ "ref", cm_ref, BRACE_ARGS },
{ "refill", cm_no_op, NO_BRACE_ARGS },
+ { "registeredsymbol", cm_registeredsymbol, BRACE_ARGS },
{ "result", cm_result, BRACE_ARGS },
{ "ringaccent", cm_accent, MAYBE_BRACE_ARGS },
{ "rmacro", cm_rmacro, NO_BRACE_ARGS },
{ "samp", cm_code, BRACE_ARGS },
+ { "sansserif", cm_sansserif, BRACE_ARGS },
{ "sc", cm_sc, BRACE_ARGS },
{ "section", cm_section, NO_BRACE_ARGS },
{ "set", cm_set, NO_BRACE_ARGS },
@@ -311,8 +292,10 @@ COMMAND command_table[] = {
{ "setfilename", cm_setfilename, NO_BRACE_ARGS },
{ "setshortcontentsaftertitlepage", cm_no_op, NO_BRACE_ARGS },
{ "settitle", cm_settitle, NO_BRACE_ARGS },
- { "shortcontents", cm_shortcontents, NO_BRACE_ARGS },
+ { "shortcaption", cm_caption, BRACE_ARGS },
+ { "shortcontents", cm_contents, NO_BRACE_ARGS },
{ "shorttitlepage", cm_ignore_line, NO_BRACE_ARGS },
+ { "slanted", cm_slanted, BRACE_ARGS },
{ "smallbook", cm_ignore_line, NO_BRACE_ARGS },
{ "smalldisplay", cm_smalldisplay, NO_BRACE_ARGS },
{ "smallexample", cm_smallexample, NO_BRACE_ARGS },
@@ -325,7 +308,8 @@ COMMAND command_table[] = {
{ "subsection", cm_subsection, NO_BRACE_ARGS },
{ "subsubheading", cm_subsubheading, NO_BRACE_ARGS },
{ "subsubsection", cm_subsubsection, NO_BRACE_ARGS },
- { "summarycontents", cm_shortcontents, NO_BRACE_ARGS },
+ { "subtitle", cm_titlepage_cmds, NO_BRACE_ARGS },
+ { "summarycontents", cm_contents, NO_BRACE_ARGS },
{ "syncodeindex", cm_synindex, NO_BRACE_ARGS },
{ "synindex", cm_synindex, NO_BRACE_ARGS },
{ "t", cm_tt, BRACE_ARGS },
@@ -335,6 +319,7 @@ COMMAND command_table[] = {
{ "tie", cm_tie, BRACE_ARGS },
{ "tieaccent", cm_accent, MAYBE_BRACE_ARGS },
{ "tindex", cm_tindex, NO_BRACE_ARGS },
+ { "title", cm_titlepage_cmds, NO_BRACE_ARGS },
{ "titlefont", cm_titlefont, BRACE_ARGS },
{ "titlepage", cm_titlepage, NO_BRACE_ARGS },
{ "today", cm_today, BRACE_ARGS },
@@ -348,7 +333,7 @@ COMMAND command_table[] = {
{ "unnumberedsubsec", cm_unnumberedsubsec, NO_BRACE_ARGS },
{ "unnumberedsubsubsec", cm_unnumberedsubsubsec, NO_BRACE_ARGS },
{ "uref", cm_uref, BRACE_ARGS },
- { "url", cm_url, BRACE_ARGS },
+ { "url", cm_uref, BRACE_ARGS },
{ "v", cm_accent, MAYBE_BRACE_ARGS },
{ "value", cm_value, BRACE_ARGS },
{ "var", cm_var, BRACE_ARGS },
@@ -357,8 +342,9 @@ COMMAND command_table[] = {
{ "verbatiminclude", cm_verbatiminclude, NO_BRACE_ARGS },
{ "vindex", cm_vindex, NO_BRACE_ARGS },
{ "vtable", cm_vtable, NO_BRACE_ARGS },
+ { "vskip", cm_ignore_line, NO_BRACE_ARGS },
{ "w", cm_w, BRACE_ARGS },
- { "xml", cm_html, NO_BRACE_ARGS },
+ { "xml", cm_xml, NO_BRACE_ARGS },
{ "xref", cm_xref, BRACE_ARGS },
/* Deprecated commands. These used to be for italics. */
@@ -387,16 +373,14 @@ COMMAND command_table[] = {
/* Commands which insert their own names. */
void
-insert_self (arg)
- int arg;
+insert_self (int arg)
{
if (arg == START)
add_word (command);
}
void
-insert_space (arg)
- int arg;
+insert_space (int arg)
{
if (arg == START)
{
@@ -407,9 +391,19 @@ insert_space (arg)
}
}
+/* Insert a comma. Useful when a literal , would break our parsing of
+ multiple arguments. */
+void
+cm_comma (int arg)
+{
+ if (arg == START)
+ add_char (',');
+}
+
+
/* Force a line break in the output. */
void
-cm_asterisk ()
+cm_asterisk (void)
{
if (html)
add_word ("<br>");
@@ -426,8 +420,7 @@ cm_asterisk ()
/* Insert ellipsis. */
void
-cm_dots (arg)
- int arg;
+cm_dots (int arg)
{
if (arg == START)
{
@@ -436,15 +429,16 @@ cm_dots (arg)
else if (docbook)
xml_insert_entity ("hellip");
else
- add_word (html && !in_fixed_width_font
- ? "<small class=\"dots\">...</small>" : "...");
+ if (html && !in_fixed_width_font)
+ insert_string ("<small class=\"dots\">...</small>");
+ else
+ add_word ("...");
}
}
/* Insert ellipsis for sentence end. */
void
-cm_enddots (arg)
- int arg;
+cm_enddots (int arg)
{
if (arg == START)
{
@@ -456,19 +450,20 @@ cm_enddots (arg)
add_char ('.');
}
else
- add_word (html && !in_fixed_width_font
- ? "<small class=\"enddots\">....</small>" : "....");
+ if (html && !in_fixed_width_font)
+ insert_string ("<small class=\"enddots\">....</small>");
+ else
+ add_word ("....");
}
}
void
-cm_bullet (arg)
- int arg;
+cm_bullet (int arg)
{
if (arg == START)
{
if (html)
- add_word ("&#149;");
+ add_word ("&bull;");
else if (xml && !docbook)
xml_insert_entity ("bullet");
else if (docbook)
@@ -479,36 +474,79 @@ cm_bullet (arg)
}
void
-cm_minus (arg)
- int arg;
+cm_minus (int arg)
{
if (arg == START)
{
if (xml)
xml_insert_entity ("minus");
+ else if (html)
+ add_word ("&minus;");
else
add_char ('-');
}
}
+/* Formatting a dimension unit. */
+void
+cm_dmn (int arg)
+{
+ if (html)
+ insert_html_tag_with_attribute (arg, "span", "class=\"dmn\"");
+ else if (docbook)
+ /* No units in docbook yet. */
+ ;
+ else if (xml)
+ xml_insert_element (DIMENSION, arg);
+}
+
/* Insert "TeX". */
void
-cm_TeX (arg)
- int arg;
+cm_TeX (int arg)
{
+ static int last_position;
+
if (arg == START)
{
- if (xml && ! docbook)
+ if (xml)
xml_insert_entity ("tex");
else
add_word ("TeX");
+
+ last_position = output_paragraph_offset;
+ }
+ else if (last_position != output_paragraph_offset)
+ {
+ warning (_("arguments to @%s ignored"), command);
+ output_paragraph_offset = last_position;
+ }
+}
+
+/* Insert "LaTeX". */
+void
+cm_LaTeX (int arg)
+{
+ static int last_position;
+
+ if (arg == START)
+ {
+ if (xml)
+ xml_insert_entity ("latex");
+ else
+ add_word ("LaTeX");
+
+ last_position = output_paragraph_offset;
+ }
+ else if (last_position != output_paragraph_offset)
+ {
+ warning (_("arguments to @%s ignored"), command);
+ output_paragraph_offset = last_position;
}
}
/* Copyright symbol. */
void
-cm_copyright (arg)
- int arg;
+cm_copyright (int arg)
{
if (arg == START)
{
@@ -523,9 +561,25 @@ cm_copyright (arg)
}
}
+/* Registered symbol. */
+void
+cm_registeredsymbol (int arg)
+{
+ if (arg == START)
+ {
+ if (html)
+ add_word ("&reg;");
+ else if (docbook)
+ xml_insert_entity ("reg");
+ else if (xml && !docbook)
+ xml_insert_entity ("registered");
+ else
+ add_word ("(R)");
+ }
+}
+
void
-cm_today (arg)
- int arg;
+cm_today (int arg)
{
static char *months[12] =
{ N_("January"), N_("February"), N_("March"), N_("April"), N_("May"),
@@ -541,18 +595,191 @@ cm_today (arg)
}
void
-cm_acronym (arg)
- int arg;
+cm_comment (void)
+{
+ /* For HTML, do not output comments before HTML header is written,
+ otherwise comments before @settitle cause an empty <title> in the
+ header. */
+ if ((html && html_output_head_p) || xml)
+ {
+ char *line;
+ get_rest_of_line (0, &line);
+
+ if (strlen (line) > 0)
+ {
+ int save_inhibit_indentation = inhibit_paragraph_indentation;
+ int save_paragraph_is_open = paragraph_is_open;
+ int save_escape_html = escape_html;
+ int save_xml_no_para = xml_no_para;
+ int i;
+
+ inhibit_paragraph_indentation = 1;
+ escape_html = 0;
+ xml_no_para = 1;
+
+ /* @c and @comment can appear between @item and @itemx,
+ @deffn and @deffnx. */
+ xml_dont_touch_items_defs++;
+
+ /* Use insert for HTML, and XML when indentation is enabled.
+ For Docbook, use add_char. */
+ if (xml && xml_indentation_increment > 0
+ && output_paragraph[output_paragraph_offset-1] != '\n')
+ insert ('\n');
+
+ /* Crunch double hyphens in comments. */
+ add_html_block_elt ("<!-- ");
+ for (i = 0; i < strlen (line); i++)
+ if (line[i] != '-' || (i && line[i-1] != '-'))
+ add_char (line[i]);
+ add_word (" -->");
+
+ if (html)
+ add_char ('\n');
+
+ inhibit_paragraph_indentation = save_inhibit_indentation;
+ paragraph_is_open = save_paragraph_is_open;
+ escape_html = save_escape_html;
+ xml_no_para = save_xml_no_para;
+ xml_dont_touch_items_defs--;
+ }
+
+ free (line);
+ }
+ else
+ cm_ignore_line ();
+}
+
+
+
+/* We keep acronyms with two arguments around, to be able to refer to them
+ later with only one argument. */
+static ACRONYM_DESC *acronyms_stack = NULL;
+
+static void
+cm_acronym_or_abbr (int arg, int is_abbr)
{
+ char *aa, *description;
+ unsigned len;
+
+ /* We do everything at START. */
+ if (arg == END)
+ return;
+
+ get_until_in_braces (",", &aa);
+ if (input_text[input_text_offset] == ',')
+ input_text_offset++;
+ get_until_in_braces ("}", &description);
+
+ canon_white (aa);
+ canon_white (description);
+
+ /* If not enclosed in braces, strip after comma to be compatible
+ with texinfo.tex. */
+ if (description[0] != '{' && strchr (description, ',') != NULL)
+ {
+ int i = 0;
+ while (description[i] != ',')
+ i++;
+ /* For now, just terminate the string at comma. */
+ description[i] = 0;
+ }
+
+ /* Get description out of braces. */
+ if (description[0] == '{')
+ description++;
+
+ len = strlen (description);
+ if (len && description[len-1] == '}')
+ description[len-1] = 0;
+
+ /* Save new description. */
+ if (strlen (description) > 0)
+ {
+ ACRONYM_DESC *new = xmalloc (sizeof (ACRONYM_DESC));
+
+ new->acronym = xstrdup (aa);
+ new->description = xstrdup (description);
+ new->next = acronyms_stack;
+ acronyms_stack = new;
+ }
+
if (html)
- insert_html_tag (arg, small_tag);
+ {
+ add_word (is_abbr ? "<abbr" : "<acronym");
+
+ if (strlen (description) > 0)
+ add_word_args (" title=\"%s\"", text_expansion (description));
+ else if (acronyms_stack)
+ {
+ /* No second argument, get from previous. Search order is from
+ last to first defined, so we get the most recent version of
+ the description. */
+ ACRONYM_DESC *temp = acronyms_stack;
+
+ while (temp)
+ {
+ if (STREQ (aa, temp->acronym)
+ && strlen (temp->description) > 0)
+ {
+ add_word_args (" title=\"%s\"",
+ text_expansion (temp->description));
+ break;
+ }
+ temp = temp->next;
+ }
+ }
+
+ add_char ('>');
+ execute_string ("%s", aa);
+ add_word (is_abbr ? "</abbr>" : "</acronym>");
+ }
+ else if (docbook)
+ {
+ xml_insert_element (is_abbr ? ABBREV : ACRONYM, START);
+ execute_string ("%s", aa);
+ xml_insert_element (is_abbr ? ABBREV : ACRONYM, END);
+ }
else if (xml)
- xml_insert_element (ACRONYM, arg);
+ {
+ xml_insert_element (is_abbr ? ABBREV : ACRONYM, START);
+
+ xml_insert_element (is_abbr ? ABBREVWORD : ACRONYMWORD, START);
+ execute_string ("%s", aa);
+ xml_insert_element (is_abbr ? ABBREVWORD : ACRONYMWORD, END);
+
+ if (strlen (description) > 0)
+ {
+ xml_insert_element (is_abbr ? ABBREVDESC : ACRONYMDESC, START);
+ execute_string ("%s", description);
+ xml_insert_element (is_abbr ? ABBREVDESC : ACRONYMDESC, END);
+ }
+
+ xml_insert_element (is_abbr ? ABBREV : ACRONYM, END);
+ }
+ else
+ execute_string ("%s", aa);
+
+ /* Put description into parenthesis after the acronym for all outputs
+ except XML. */
+ if (strlen (description) > 0 && (!xml || docbook))
+ add_word_args (" (%s)", description);
}
void
-cm_tt (arg)
- int arg;
+cm_acronym (int arg)
+{
+ cm_acronym_or_abbr (arg, 0);
+}
+
+void
+cm_abbr (int arg)
+{
+ cm_acronym_or_abbr (arg, 1);
+}
+
+void
+cm_tt (int arg)
{
/* @t{} is a no-op in Info. */
if (html)
@@ -562,37 +789,73 @@ cm_tt (arg)
}
void
-cm_code (arg)
- int arg;
+cm_code (int arg)
{
+ if (arg == START)
+ in_fixed_width_font++;
+
if (xml)
- xml_insert_element (CODE, arg);
- else
{
- extern int printing_index;
-
- if (arg == START)
+ if (STREQ (command, "command"))
+ xml_insert_element (COMMAND_TAG, arg);
+ else if (STREQ (command, "env"))
+ xml_insert_element (ENV, arg);
+ else if (STREQ (command, "file"))
+ xml_insert_element (FILE_TAG, arg);
+ else if (STREQ (command, "option"))
+ xml_insert_element (OPTION, arg);
+ else if (STREQ (command, "samp"))
{
- in_fixed_width_font++;
-
- if (html)
- insert_html_tag (arg, "code");
- else if (!printing_index)
- add_char ('`');
+ if (docbook && arg == START)
+ {
+ /* Even though @samp is in_fixed_width_font, it
+ should always start a paragraph. Unfortunately,
+ in_fixed_width_font inhibits that. */
+ xml_start_para ();
+ xml_insert_entity ("lsquo");
+ }
+ xml_insert_element (SAMP, arg);
+ if (docbook && arg == END)
+ xml_insert_entity ("rsquo");
}
- else if (html)
+ else
+ xml_insert_element (CODE, arg);
+ }
+ else if (html)
+ {
+ if (STREQ (command, "code"))
insert_html_tag (arg, "code");
else
+ { /* Use <samp> tag in general to get typewriter. */
+ if (arg == START)
+ { /* If @samp specifically, add quotes a la TeX output. */
+ if (STREQ (command, "samp")) add_char ('`');
+ add_word ("<samp>");
+ }
+ insert_html_tag_with_attribute (arg, "span", "class=\"%s\"",command);
+ if (arg == END)
+ {
+ add_word ("</samp>");
+ if (STREQ (command, "samp")) add_char ('\'');
+ }
+ }
+ }
+ else
+ {
+ extern int printing_index;
+
+ if (!printing_index)
{
- if (!printing_index)
+ if (arg == START)
+ add_char ('`');
+ else
add_meta_char ('\'');
}
}
}
void
-cm_kbd (arg)
- int arg;
+cm_kbd (int arg)
{
if (xml)
xml_insert_element (KBD, arg);
@@ -612,8 +875,9 @@ cm_kbd (arg)
}
}
+/* Just show a url (http://example.org/..., for example), don't link to it. */
void
-cm_url (arg, start, end)
+cm_indicate_url (int arg, int start, int end)
{
if (xml)
xml_insert_element (URL, arg);
@@ -633,8 +897,7 @@ cm_url (arg, start, end)
}
void
-cm_key (arg)
- int arg;
+cm_key (int arg)
{
if (xml)
xml_insert_element (KEY, arg);
@@ -646,8 +909,7 @@ cm_key (arg)
/* Handle a command that switches to a non-fixed-width font. */
void
-not_fixed_width (arg)
- int arg;
+not_fixed_width (int arg)
{
if (arg == START)
in_fixed_width_font = 0;
@@ -655,8 +917,7 @@ not_fixed_width (arg)
/* @var in makeinfo just uppercases the text. */
void
-cm_var (arg, start_pos, end_pos)
- int arg, start_pos, end_pos;
+cm_var (int arg, int start_pos, int end_pos)
{
if (xml)
xml_insert_element (VAR, arg);
@@ -681,51 +942,50 @@ cm_var (arg, start_pos, end_pos)
}
void
-cm_sc (arg, start_pos, end_pos)
- int arg, start_pos, end_pos;
+cm_sc (int arg, int start_pos, int end_pos)
{
if (xml)
xml_insert_element (SC, arg);
else
{
- not_fixed_width (arg);
-
- if (arg == START)
- {
- if (html)
- insert_html_tag (arg, small_tag);
- }
- else
- {
- int all_upper;
+ not_fixed_width (arg);
- if (html)
- start_pos += sizeof (small_tag) + 2 - 1; /* skip <small> */
+ if (arg == START)
+ {
+ if (html)
+ insert_html_tag_with_attribute (arg, "span", "class=\"sc\"");
+ }
+ else
+ {
+ int all_upper;
- /* Avoid the warning below if there's no text inside @sc{}, or
- when processing menus under --no-headers. */
- all_upper = start_pos < end_pos;
+ if (html)
+ start_pos += sizeof ("<span class=\"sc\">") - 1; /* skip <span> */
+
+ /* Avoid the warning below if there's no text inside @sc{}, or
+ when processing menus under --no-headers. */
+ all_upper = start_pos < end_pos;
+
+ while (start_pos < end_pos)
+ {
+ unsigned char c = output_paragraph[start_pos];
+ if (!isupper (c))
+ all_upper = 0;
+ if (!html)
+ output_paragraph[start_pos] = coerce_to_upper (c);
+ start_pos++;
+ }
+ if (all_upper)
+ warning (_("@sc argument all uppercase, thus no effect"));
- while (start_pos < end_pos)
- {
- unsigned char c = output_paragraph[start_pos];
- if (!isupper (c))
- all_upper = 0;
- output_paragraph[start_pos] = coerce_to_upper (c);
- start_pos++;
+ if (html)
+ insert_html_tag (arg, "span");
}
- if (all_upper)
- warning (_("@sc argument all uppercase, thus no effect"));
-
- if (html)
- insert_html_tag (arg, small_tag);
- }
}
}
void
-cm_dfn (arg, position)
- int arg, position;
+cm_dfn (int arg, int position)
{
if (xml)
xml_insert_element (DFN, arg);
@@ -741,8 +1001,7 @@ cm_dfn (arg, position)
}
void
-cm_emph (arg)
- int arg;
+cm_emph (int arg)
{
if (xml)
xml_insert_element (EMPH, arg);
@@ -753,11 +1012,10 @@ cm_emph (arg)
}
void
-cm_verb (arg)
- int arg;
+cm_verb (int arg)
{
int character;
- int delimiter;
+ int delimiter = 0; /* avoid warning */
int seen_end = 0;
in_fixed_width_font++;
@@ -799,7 +1057,7 @@ cm_verb (arg)
else if (html && character == '&')
add_word ("&amp;");
- else if (character == delimiter)
+ else if (character == delimiter && input_text[input_text_offset+1] == '}')
{ /* Assume no newlines in END_VERBATIM. */
seen_end = 1;
input_text_offset++;
@@ -832,20 +1090,33 @@ cm_verb (arg)
void
-cm_strong (arg, position)
- int arg, position;
+cm_strong (int arg, int start_pos, int end_pos)
{
- if (xml)
+ if (docbook && arg == START)
+ xml_insert_element_with_attribute (B, arg, "role=\"bold\"");
+ else if (xml)
xml_insert_element (STRONG, arg);
else if (html)
insert_html_tag (arg, "strong");
else
add_char ('*');
+
+ if (!xml && !html && !docbook && !no_headers
+ && arg == END
+ && end_pos - start_pos >= 6
+ && (STRNCASEEQ ((char *) output_paragraph + start_pos, "*Note:", 6)
+ || STRNCASEEQ ((char *) output_paragraph + start_pos, "*Note ", 6)))
+ {
+ /* Translators: "Note:" is literal here and should not be
+ translated. @strong{Nota}, say, does not cause the problem. */
+ warning (_("@strong{Note...} produces a spurious cross-reference in Info; reword to avoid that"));
+ /* Adjust the output to avoid writing the bad xref. */
+ output_paragraph[start_pos + 5] = '_';
+ }
}
void
-cm_cite (arg, position)
- int arg, position;
+cm_cite (int arg, int position)
{
if (xml)
xml_insert_element (CITE, arg);
@@ -862,8 +1133,7 @@ cm_cite (arg, position)
/* No highlighting, but argument switches fonts. */
void
-cm_not_fixed_width (arg, start, end)
- int arg, start, end;
+cm_not_fixed_width (int arg, int start, int end)
{
if (xml)
xml_insert_element (NOTFIXEDWIDTH, arg);
@@ -871,10 +1141,14 @@ cm_not_fixed_width (arg, start, end)
}
void
-cm_i (arg)
- int arg;
+cm_i (int arg)
{
- if (xml)
+ /* Make use of <lineannotation> of Docbook, if we are
+ inside an @example or similar. */
+ extern int printing_index;
+ if (docbook && !filling_enabled && !printing_index)
+ xml_insert_element (LINEANNOTATION, arg);
+ else if (xml)
xml_insert_element (I, arg);
else if (html)
insert_html_tag (arg, "i");
@@ -883,10 +1157,31 @@ cm_i (arg)
}
void
-cm_b (arg)
- int arg;
+cm_slanted (int arg)
{
- if (xml)
+ /* Make use of <lineannotation> of Docbook, if we are
+ inside an @example or similar. */
+ extern int printing_index;
+ if (docbook && !filling_enabled && !printing_index)
+ xml_insert_element (LINEANNOTATION, arg);
+ else if (xml)
+ xml_insert_element (SLANTED, arg);
+ else if (html)
+ insert_html_tag (arg, "i");
+ else
+ not_fixed_width (arg);
+}
+
+void
+cm_b (int arg)
+{
+ /* See cm_i comments. */
+ extern int printing_index;
+ if (docbook && !filling_enabled && !printing_index)
+ xml_insert_element (LINEANNOTATION, arg);
+ else if (docbook && arg == START)
+ xml_insert_element_with_attribute (B, arg, "role=\"bold\"");
+ else if (xml)
xml_insert_element (B, arg);
else if (html)
insert_html_tag (arg, "b");
@@ -895,23 +1190,37 @@ cm_b (arg)
}
void
-cm_r (arg)
- int arg;
+cm_r (int arg)
{
- if (xml)
+ /* See cm_i comments. */
+ extern int printing_index;
+ if (docbook && !filling_enabled && !printing_index)
+ xml_insert_element (LINEANNOTATION, arg);
+ else if (xml)
xml_insert_element (R, arg);
+ else if (html)
+ insert_html_tag_with_attribute (arg, "span", "class=\"roman\"");
else
- {
- if (html)
- insert_html_tag (arg, "");
+ not_fixed_width (arg);
+}
- not_fixed_width (arg);
- }
+void
+cm_sansserif (int arg)
+{
+ /* See cm_i comments. */
+ extern int printing_index;
+ if (docbook && !filling_enabled && !printing_index)
+ xml_insert_element (LINEANNOTATION, arg);
+ else if (xml)
+ xml_insert_element (SANSSERIF, arg);
+ else if (html)
+ insert_html_tag_with_attribute (arg, "span", "class=\"sansserif\"");
+ else
+ not_fixed_width (arg);
}
void
-cm_titlefont (arg)
- int arg;
+cm_titlefont (int arg)
{
if (xml)
xml_insert_element (TITLEFONT, arg);
@@ -929,26 +1238,26 @@ cm_titlefont (arg)
}
}
-int titlepage_cmd_present = 0;
+/* Unfortunately, we cannot interpret @math{} contents like TeX does. We just
+ pass them through. */
void
-cm_titlepage (arg)
- int arg;
+cm_math (int arg)
{
- titlepage_cmd_present = 1;
- command_name_condition ();
+ if (xml && !docbook)
+ xml_insert_element (MATH, arg);
}
/* Various commands are no-op's. */
void
-cm_no_op ()
+cm_no_op (void)
{
}
/* For proofing single chapters, etc. */
void
-cm_novalidate ()
+cm_novalidate (void)
{
validating = 0;
}
@@ -956,13 +1265,19 @@ cm_novalidate ()
/* Prevent the argument from being split across two lines. */
void
-cm_w (arg, start, end)
- int arg, start, end;
+cm_w (int arg)
{
if (arg == START)
non_splitting_words++;
else
- non_splitting_words--;
+ {
+ if (docbook || html || xml)
+ /* This is so @w{$}Log$ doesn't end up as <dollar>Log<dollar>
+ in the output. */
+ insert_string ("<!-- /@w -->");
+
+ non_splitting_words--;
+ }
}
@@ -970,8 +1285,7 @@ cm_w (arg, start, end)
for TeX (the space stretches and stretches, and does not inhibit
hyphenation). */
void
-cm_tie (arg)
- int arg;
+cm_tie (int arg)
{
if (arg == START)
{
@@ -985,8 +1299,7 @@ cm_tie (arg)
/* Explain that this command is obsolete, thus the user shouldn't
do anything with it. */
static void
-cm_obsolete (arg, start, end)
- int arg, start, end;
+cm_obsolete (int arg, int start, int end)
{
if (arg == START)
warning (_("%c%s is obsolete"), COMMAND_PREFIX, command);
@@ -996,17 +1309,44 @@ cm_obsolete (arg, start, end)
/* Inhibit the indentation of the next paragraph, but not of following
paragraphs. */
void
-cm_noindent ()
+cm_noindent (void)
{
if (!inhibit_paragraph_indentation)
inhibit_paragraph_indentation = -1;
}
+void
+cm_noindent_cmd (void)
+{
+ cm_noindent ();
+ xml_no_indent = 1;
+ skip_whitespace_and_newlines();
+
+ if (xml)
+ xml_start_para ();
+ else if (html && !paragraph_is_open)
+ add_html_block_elt ("<p class=\"noindent\">");
+ else
+ {
+ paragraph_is_open = 0;
+ start_paragraph ();
+ }
+}
+
/* Force indentation of the next paragraph. */
void
-cm_indent ()
+cm_indent (void)
{
inhibit_paragraph_indentation = 0;
+ xml_no_indent = 0;
+ skip_whitespace_and_newlines();
+
+ if (xml)
+ xml_start_para ();
+ else if (html && !paragraph_is_open)
+ add_html_block_elt ("<p class=\"indent\">");
+ else
+ start_paragraph ();
}
/* I don't know exactly what to do with this. Should I allow
@@ -1016,7 +1356,7 @@ cm_indent ()
switch files. Finally, complain, or at least warn. It doesn't
really matter, anyway, since this doesn't get executed. */
void
-cm_setfilename ()
+cm_setfilename (void)
{
char *filename;
get_rest_of_line (1, &filename);
@@ -1027,7 +1367,7 @@ cm_setfilename ()
}
void
-cm_settitle ()
+cm_settitle (void)
{
if (xml)
{
@@ -1038,11 +1378,6 @@ cm_settitle ()
execute_string ("%s", title);
xml_in_book_title = 0;
xml_insert_element (SETTITLE, END);
- if (docbook && !xml_in_bookinfo)
- {
- xml_insert_element (BOOKINFO, START);
- xml_in_bookinfo = 1;
- }
}
else
get_rest_of_line (0, &title);
@@ -1051,8 +1386,7 @@ cm_settitle ()
/* Ignore argument in braces. */
void
-cm_ignore_arg (arg, start_pos, end_pos)
- int arg, start_pos, end_pos;
+cm_ignore_arg (int arg, int start_pos, int end_pos)
{
if (arg == END)
output_paragraph_offset = start_pos;
@@ -1060,19 +1394,21 @@ cm_ignore_arg (arg, start_pos, end_pos)
/* Ignore argument on rest of line. */
void
-cm_ignore_line ()
+cm_ignore_line (void)
{
discard_until ("\n");
}
/* Insert the number of blank lines passed as argument. */
void
-cm_sp ()
+cm_sp (void)
{
int lines;
char *line;
- get_rest_of_line (1, &line);
+ /* Due to tricky stuff in execute_string(), @value{} can't be expanded.
+ So there is really no reason to enable expansion for @sp parameters. */
+ get_rest_of_line (0, &line);
if (sscanf (line, "%d", &lines) != 1 || lines <= 0)
line_error (_("@sp requires a positive numeric argument, not `%s'"), line);
@@ -1080,41 +1416,45 @@ cm_sp ()
{
if (xml)
{
+ /* @sp can appear between @item and @itemx, @deffn and @deffnx. */
+ xml_dont_touch_items_defs++;
xml_insert_element_with_attribute (SP, START, "lines=\"%s\"", line);
/* insert_string (line);*/
xml_insert_element (SP, END);
+ xml_dont_touch_items_defs--;
}
else
- {
- /* Must disable filling since otherwise multiple newlines is like
- multiple spaces. Must close paragraph since that's what the
- manual says and that's what TeX does. */
- int save_filling_enabled = filling_enabled;
- filling_enabled = 0;
-
- /* close_paragraph generates an extra blank line. */
- close_single_paragraph ();
+ {
+ /* Must disable filling since otherwise multiple newlines is like
+ multiple spaces. Must close paragraph since that's what the
+ manual says and that's what TeX does. */
+ int save_filling_enabled = filling_enabled;
+ filling_enabled = 0;
- if (lines && html && !executing_string)
- html_output_head ();
+ /* close_paragraph generates an extra blank line. */
+ close_single_paragraph ();
- while (lines--)
- {
- if (html)
- insert_string ("<br><p>\n");
- else
- add_char ('\n');
- }
+ if (lines && html && !executing_string)
+ html_output_head ();
- filling_enabled = save_filling_enabled;
- }
+ if (html)
+ add_html_block_elt ("<pre class=\"sp\">\n");
+
+ while (lines--)
+ add_char ('\n');
+
+ if (html)
+ add_html_block_elt ("</pre>\n");
+
+ filling_enabled = save_filling_enabled;
+ }
}
free (line);
}
/* @dircategory LINE outputs INFO-DIR-SECTION LINE, unless --no-headers. */
void
-cm_dircategory ()
+cm_dircategory (void)
{
char *line;
@@ -1148,77 +1488,79 @@ cm_dircategory ()
Then center the line of text.
*/
void
-cm_center ()
+cm_center (void)
{
if (xml)
{
- unsigned char *line;
+ char *line;
xml_insert_element (CENTER, START);
- get_rest_of_line (0, (char **)&line);
- execute_string ("%s", (char *)line);
+ get_rest_of_line (0, &line);
+ execute_string ("%s", line);
free (line);
xml_insert_element (CENTER, END);
}
else
{
- int i, start, length;
- unsigned char *line;
- int save_indented_fill = indented_fill;
- int save_filling_enabled = filling_enabled;
- int fudge_factor = 1;
+ int i, start, length;
+ char *line;
+ int save_indented_fill = indented_fill;
+ int save_filling_enabled = filling_enabled;
+ int fudge_factor = 1;
- filling_enabled = indented_fill = 0;
- cm_noindent ();
- start = output_paragraph_offset;
+ filling_enabled = indented_fill = 0;
+ cm_noindent ();
+ start = output_paragraph_offset;
- if (html)
- add_word ("<div align=\"center\">");
+ if (html)
+ add_html_block_elt ("<div align=\"center\">");
- inhibit_output_flushing ();
- get_rest_of_line (0, (char **)&line);
- execute_string ("%s", (char *)line);
- free (line);
- uninhibit_output_flushing ();
- if (html)
- add_word ("</div>");
+ inhibit_output_flushing ();
+ get_rest_of_line (0, &line);
+ execute_string ("%s", line);
+ free (line);
+ uninhibit_output_flushing ();
+ if (html)
+ add_html_block_elt ("</div>");
- else
- {
- i = output_paragraph_offset - 1;
- while (i > (start - 1) && output_paragraph[i] == '\n')
- i--;
+ else
+ {
+ i = output_paragraph_offset - 1;
+ while (i > (start - 1) && output_paragraph[i] == '\n')
+ i--;
- output_paragraph_offset = ++i;
- length = output_paragraph_offset - start;
+ output_paragraph_offset = ++i;
+ length = output_paragraph_offset - start;
- if (length < (fill_column - fudge_factor))
- {
- line = xmalloc (1 + length);
- memcpy (line, (char *)(output_paragraph + start), length);
+ if (length < (fill_column - fudge_factor))
+ {
+ line = xmalloc (1 + length);
+ memcpy (line, (char *)(output_paragraph + start), length);
- i = (fill_column - fudge_factor - length) / 2;
- output_paragraph_offset = start;
+ i = (fill_column - fudge_factor - length) / 2;
+ output_paragraph_offset = start;
- while (i--)
- insert (' ');
+ while (i--)
+ insert (' ');
- for (i = 0; i < length; i++)
- insert (line[i]);
+ for (i = 0; i < length; i++)
+ insert (line[i]);
- free (line);
- }
- }
+ free (line);
+ }
+ }
- insert ('\n');
- filling_enabled = save_filling_enabled;
- indented_fill = save_indented_fill;
+ insert ('\n');
+ filling_enabled = save_filling_enabled;
+ indented_fill = save_indented_fill;
+ close_single_paragraph ();
+ if (looking_at("\n"))
+ insert ('\n');
}
}
/* Show what an expression returns. */
void
-cm_result (arg)
- int arg;
+cm_result (int arg)
{
if (arg == END)
add_word (html ? "=&gt;" : "=>");
@@ -1226,8 +1568,7 @@ cm_result (arg)
/* What an expression expands to. */
void
-cm_expansion (arg)
- int arg;
+cm_expansion (int arg)
{
if (arg == END)
add_word (html ? "==&gt;" : "==>");
@@ -1235,8 +1576,7 @@ cm_expansion (arg)
/* Indicates two expressions are equivalent. */
void
-cm_equiv (arg)
- int arg;
+cm_equiv (int arg)
{
if (arg == END)
add_word ("==");
@@ -1244,8 +1584,7 @@ cm_equiv (arg)
/* What an expression may print. */
void
-cm_print (arg)
- int arg;
+cm_print (int arg)
{
if (arg == END)
add_word ("-|");
@@ -1253,8 +1592,7 @@ cm_print (arg)
/* An error signaled. */
void
-cm_error (arg)
- int arg;
+cm_error (int arg)
{
if (arg == END)
add_word (html ? "error--&gt;" : "error-->");
@@ -1262,8 +1600,7 @@ cm_error (arg)
/* The location of point in an example of a buffer. */
void
-cm_point (arg)
- int arg;
+cm_point (int arg)
{
if (arg == END)
add_word ("-!-");
@@ -1272,7 +1609,7 @@ cm_point (arg)
/* @exdent: Start a new line with just this text on it.
The text is outdented one level if possible. */
void
-cm_exdent ()
+cm_exdent (void)
{
char *line;
int save_indent = current_indent;
@@ -1294,6 +1631,10 @@ cm_exdent ()
if (html)
add_word ("<br>");
+ else if (docbook)
+ xml_insert_element (LINEANNOTATION, START);
+ else if (xml)
+ xml_insert_element (EXDENT, START);
/* Can't close_single_paragraph, then we lose preceding blank lines. */
flush_output ();
@@ -1302,11 +1643,18 @@ cm_exdent ()
if (html)
add_word ("<br>");
+ else if (xml)
+ {
+ xml_insert_element (docbook ? LINEANNOTATION : EXDENT, END);
+ insert ('\n');
+ }
+
close_single_paragraph ();
current_indent = save_indent;
in_fixed_width_font = save_in_fixed_width_font;
- start_paragraph ();
+ if (!xml)
+ start_paragraph ();
}
/*
@@ -1315,15 +1663,16 @@ cm_exdent ()
verbatim_include != 0: process through handle_verbatim_environment
*/
static void
-handle_include (verbatim_include)
- int verbatim_include;
+handle_include (int verbatim_include)
{
char *arg, *filename;
if (macro_expansion_output_stream && !executing_string)
me_append_before_this_command ();
- close_paragraph ();
+ if (!insertion_stack)
+ close_paragraph (); /* No blank lines etc. if not at outer level. */
+
get_rest_of_line (0, &arg);
/* We really only want to expand @value, but it's easier to just do
everything. TeX will only work with @value. */
@@ -1350,7 +1699,7 @@ handle_include (verbatim_include)
fflush (stdout);
}
- if (!find_and_load (filename))
+ if (!find_and_load (filename, 1))
{
popfile ();
line_number--;
@@ -1379,7 +1728,7 @@ handle_include (verbatim_include)
/* Include file as if put in @verbatim environment */
void
-cm_verbatiminclude ()
+cm_verbatiminclude (void)
{
handle_include (1);
}
@@ -1387,7 +1736,7 @@ cm_verbatiminclude ()
/* Remember this file, and move onto the next. */
void
-cm_include ()
+cm_include (void)
{
handle_include (0);
}
@@ -1396,17 +1745,16 @@ cm_include ()
/* @bye: Signals end of processing. Easy to make this happen. */
void
-cm_bye ()
+cm_bye (void)
{
discard_braces (); /* should not have any unclosed braces left */
- flush_output ();
input_text_offset = input_text_length;
}
/* @paragraphindent */
static void
-cm_paragraphindent ()
+cm_paragraphindent (void)
{
char *arg;
@@ -1420,26 +1768,28 @@ cm_paragraphindent ()
/* @exampleindent: change indentation of example-like environments. */
static int
-set_default_indentation_increment (string)
- char *string;
+set_example_indentation_increment (char *string)
{
if (strcmp (string, "asis") == 0 || strcmp (string, _("asis")) == 0)
;
else if (strcmp (string, "none") == 0 || strcmp (string, _("none")) == 0)
- default_indentation_increment = 0;
- else if (sscanf (string, "%d", &default_indentation_increment) != 1)
+ example_indentation_increment = 0;
+ else if (sscanf (string, "%d", &example_indentation_increment) != 1)
return -1;
return 0;
}
static void
-cm_exampleindent ()
+cm_exampleindent (void)
{
char *arg;
get_rest_of_line (1, &arg);
- if (set_default_indentation_increment (arg) != 0)
- line_error (_("Bad argument to %c%s"), COMMAND_PREFIX, command);
+ if (set_example_indentation_increment (arg) != 0)
+ line_error (_("Bad argument to @%s"), command);
+
+ if (input_text[input_text_offset] == '\n')
+ close_single_paragraph ();
free (arg);
}
@@ -1448,8 +1798,7 @@ cm_exampleindent ()
/* @firstparagraphindent: suppress indentation in first paragraphs after
headings. */
static int
-set_firstparagraphindent (string)
- char *string;
+set_firstparagraphindent (char *string)
{
if (STREQ (string, "insert") || STREQ (string, _("insert")))
do_first_par_indent = 1;
@@ -1461,7 +1810,7 @@ set_firstparagraphindent (string)
}
static void
-cm_firstparagraphindent ()
+cm_firstparagraphindent (void)
{
char *arg;
@@ -1471,3 +1820,64 @@ cm_firstparagraphindent ()
free (arg);
}
+
+/* For DocBook and XML, produce &period; for `.@:'. This gives the processing
+ software a fighting chance to treat it specially by not adding extra space.
+
+ Do this also for ?, !, and :. */
+void
+cm_colon (void)
+{
+ if (xml)
+ {
+ if (strchr (".?!:", input_text[input_text_offset-3]) != NULL)
+ {
+ /* Erase literal character that's there, except `>', which is
+ part of the XML tag. */
+ if (output_paragraph[output_paragraph_offset-1] != '>')
+ output_paragraph_offset--;
+
+ switch (input_text[input_text_offset-3])
+ {
+ case '.':
+ xml_insert_entity ("period");
+ break;
+ case '?':
+ xml_insert_entity ("quest");
+ break;
+ case '!':
+ xml_insert_entity ("excl");
+ break;
+ case ':':
+ xml_insert_entity ("colon");
+ break;
+ }
+ }
+ }
+}
+
+/* Ending sentences explicitly. Currently, only outputs entities for XML
+ output, for other formats it calls insert_self. */
+void
+cm_punct (int arg)
+{
+ if (xml && !docbook)
+ {
+ switch (input_text[input_text_offset-1])
+ {
+ case '.':
+ xml_insert_entity ("eosperiod");
+ break;
+ case '?':
+ xml_insert_entity ("eosquest");
+ break;
+ case '!':
+ xml_insert_entity ("eosexcl");
+ break;
+ }
+ }
+ else
+ {
+ insert_self (arg);
+ }
+}
diff --git a/contrib/texinfo/makeinfo/cmds.h b/contrib/texinfo/makeinfo/cmds.h
index e9b860a..6824550 100644
--- a/contrib/texinfo/makeinfo/cmds.h
+++ b/contrib/texinfo/makeinfo/cmds.h
@@ -1,7 +1,8 @@
/* cmds.h -- declarations for cmds.c.
- $Id: cmds.h,v 1.3 2002/11/04 22:15:19 karl Exp $
+ $Id: cmds.h,v 1.9 2004/11/26 00:48:35 karl Exp $
- Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2002, 2003, 2004 Free Software Foundation,
+ Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -47,7 +48,166 @@ typedef struct
extern COMMAND command_table[];
-/* Nonzero if we have seen an @titlepage command. */
-extern int titlepage_cmd_present;
+typedef struct acronym_desc
+{
+ struct acronym_desc *next;
+ char *acronym;
+ char *description;
+} ACRONYM_DESC;
+
+/* Texinfo commands. */
+extern void insert_self (int arg),
+ insert_space (int arg),
+ cm_ignore_line (void),
+ cm_ignore_arg (int arg, int start_pos, int end_pos),
+ cm_comment (void),
+ cm_no_op (void);
+
+/* Document structure and meta information. */
+extern void cm_setfilename (void),
+ cm_settitle (void),
+ cm_documentdescription (void),
+ cm_node (void),
+ cm_menu (void),
+ cm_detailmenu (void),
+ cm_dircategory (void),
+ cm_direntry (void),
+ cm_bye (void);
+
+/* File inclusion. */
+extern void cm_include (void),
+ cm_verbatiminclude (void);
+
+/* Cross referencing commands. */
+extern void cm_anchor (int arg),
+ cm_xref (int arg),
+ cm_pxref (int arg),
+ cm_ref (int arg),
+ cm_inforef (int arg),
+ cm_uref (int arg);
+
+/* Special insertions. */
+extern void cm_LaTeX (int arg),
+ cm_TeX (int arg),
+ cm_bullet (int arg),
+ cm_colon (void),
+ cm_comma (int arg),
+ cm_copyright (int arg),
+ cm_dots (int arg),
+ cm_enddots (int arg),
+ cm_equiv (int arg),
+ cm_error (int arg),
+ cm_expansion (int arg),
+ cm_image (int arg),
+ cm_insert_copying (void),
+ cm_minus (int arg),
+ cm_point (int arg),
+ cm_print (int arg),
+ cm_punct (int arg),
+ cm_registeredsymbol (int arg),
+ cm_result (int arg);
+
+/* Emphasis and markup. */
+extern void cm_acronym (int arg),
+ cm_abbr (int arg),
+ cm_b (int arg),
+ cm_cite (int arg, int position),
+ cm_code (int arg),
+ cm_dfn (int arg, int position),
+ cm_dmn (int arg),
+ cm_email (int arg),
+ cm_emph (int arg),
+ cm_i (int arg),
+ cm_kbd (int arg),
+ cm_key (int arg),
+ cm_math (int arg),
+ cm_not_fixed_width (int arg, int start, int end),
+ cm_r (int arg),
+ cm_sansserif (int arg),
+ cm_sc (int arg, int start_pos, int end_pos),
+ cm_slanted (int arg),
+ cm_strong (int arg, int start_pos, int end_pos),
+ cm_tt (int arg),
+ cm_indicate_url (int arg, int start, int end),
+ cm_var (int arg, int start_pos, int end_pos),
+ cm_verb (int arg);
+
+/* Block environments. */
+extern void cm_cartouche (void),
+ cm_group (void),
+ cm_display (void),
+ cm_smalldisplay (void),
+ cm_example (void),
+ cm_smallexample (void),
+ cm_smalllisp (void),
+ cm_lisp (void),
+ cm_format (void),
+ cm_smallformat (void),
+ cm_quotation (void),
+ cm_copying (void),
+ cm_flushleft (void),
+ cm_flushright (void),
+ cm_verbatim (void),
+ cm_end (void);
+
+/* Tables, lists, enumerations. */
+extern void cm_table (void),
+ cm_ftable (void),
+ cm_vtable (void),
+ cm_itemize (void),
+ cm_enumerate (void),
+ cm_multitable (void),
+ cm_headitem (void),
+ cm_item (void),
+ cm_itemx (void),
+ cm_tab (void);
+
+extern void cm_center (void),
+ cm_exdent (void),
+ cm_indent (void),
+ cm_noindent (void),
+ cm_noindent_cmd (void);
+
+/* Line and page breaks. */
+extern void cm_asterisk (void),
+ cm_sp (void),
+ cm_page (void);
+
+/* Non breaking words. */
+extern void cm_tie (int arg),
+ cm_w (int arg);
+
+/* Title page creation. */
+extern void cm_titlepage (void),
+ cm_author (void),
+ cm_titlepage_cmds (void),
+ cm_titlefont (int arg),
+ cm_today (int arg);
+
+/* Floats. */
+extern void cm_float (void),
+ cm_caption (int arg),
+ cm_shortcaption (void),
+ cm_listoffloats (void);
+
+/* Indices. */
+extern void cm_kindex (void),
+ cm_cindex (void),
+ cm_findex (void),
+ cm_pindex (void),
+ cm_vindex (void),
+ cm_tindex (void),
+ cm_defindex (void),
+ cm_defcodeindex (void),
+ cm_synindex (void),
+ cm_printindex (void);
+
+/* Conditionals. */
+extern void cm_set (void),
+ cm_clear (void),
+ cm_ifset (void),
+ cm_ifclear (void),
+ cm_ifeq (void),
+ cm_value (int arg, int start_pos, int end_pos);
#endif /* !CMDS_H */
diff --git a/contrib/texinfo/makeinfo/defun.c b/contrib/texinfo/makeinfo/defun.c
index 992cf3b..0323353 100644
--- a/contrib/texinfo/makeinfo/defun.c
+++ b/contrib/texinfo/makeinfo/defun.c
@@ -1,7 +1,7 @@
/* defun.c -- @defun and friends.
- $Id: defun.c,v 1.6 2003/05/09 23:51:10 karl Exp $
+ $Id: defun.c,v 1.11 2004/04/11 17:56:46 karl Exp $
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
Foundation, Inc.
This program is free software; you can redistribute it and/or modify
@@ -38,8 +38,7 @@ struct token_accumulator
};
static void
-initialize_token_accumulator (accumulator)
- struct token_accumulator *accumulator;
+initialize_token_accumulator (struct token_accumulator *accumulator)
{
accumulator->length = 0;
accumulator->index = 0;
@@ -47,9 +46,7 @@ initialize_token_accumulator (accumulator)
}
static void
-accumulate_token (accumulator, token)
- struct token_accumulator *accumulator;
- char *token;
+accumulate_token (struct token_accumulator *accumulator, char *token)
{
if (accumulator->index >= accumulator->length)
{
@@ -64,8 +61,7 @@ accumulate_token (accumulator, token)
/* Given STRING_POINTER pointing at an open brace, skip forward and return a
pointer to just past the matching close brace. */
static int
-scan_group_in_string (string_pointer)
- char **string_pointer;
+scan_group_in_string (char **string_pointer)
{
char *scan_string = (*string_pointer) + 1;
unsigned int level = 1;
@@ -106,8 +102,7 @@ scan_group_in_string (string_pointer)
Contiguous whitespace characters are converted to a token
consisting of a single space. */
static char **
-args_from_string (string)
- char *string;
+args_from_string (char *string)
{
struct token_accumulator accumulator;
char *token_start, *token_end;
@@ -176,6 +171,15 @@ args_from_string (string)
token_end = balanced ? (scan_string - 1) : scan_string;
}
+ /* Make commas separate tokens so to differentiate them from
+ parameter types in XML output. */
+ else if (*scan_string == ',')
+ {
+ token_start = scan_string;
+ scan_string += 1;
+ token_end = scan_string;
+ }
+
/* Otherwise a token is delimited by whitespace, parentheses,
brackets, or braces. A token is also ended by a command. */
else
@@ -198,6 +202,14 @@ args_from_string (string)
break;
}
+ /* End token if we are looking at a comma, as commas are
+ delimiters too. */
+ if (c == ',')
+ {
+ scan_string--;
+ break;
+ }
+
/* If we encounter a command embedded within a token,
then end the token. */
if (c == COMMAND_PREFIX)
@@ -216,12 +228,16 @@ args_from_string (string)
}
static void
-process_defun_args (defun_args, auto_var_p)
- char **defun_args;
- int auto_var_p;
+process_defun_args (char **defun_args, int auto_var_p)
{
int pending_space = 0;
+ if (xml)
+ {
+ xml_process_defun_args (defun_args, auto_var_p);
+ return;
+ }
+
for (;;)
{
char *defun_arg = *defun_args++;
@@ -245,38 +261,25 @@ process_defun_args (defun_args, auto_var_p)
{
/* Within @deffn and friends, texinfo.tex makes parentheses
sans serif and brackets bold. We use roman instead. */
- insert_html_tag (START, "");
+ if (html)
+ insert_html_tag (START, "");
+
add_char (defun_arg[0]);
- insert_html_tag (END, "");
+
+ if (html)
+ insert_html_tag (END, "");
}
- else if (defun_arg[0] == '&')
- if (html)
- {
- defun_arg = escape_string (xstrdup (defun_arg));
- add_word (defun_arg);
- free (defun_arg);
- }
- else
- add_word (defun_arg);
- else if (defun_arg[0] == COMMAND_PREFIX)
- execute_string ("%s", defun_arg);
- else if (auto_var_p)
- if (html)
- {
- defun_arg = escape_string (xstrdup (defun_arg));
- add_word (defun_arg);
- free (defun_arg);
- }
- else
- add_word (defun_arg);
+ /* else if (defun_arg[0] == '&' || defun_arg[0] == COMMAND_PREFIX) */
+ /* execute_string ("%s", defun_arg); */
+ /* else if (auto_var_p) */
+ /* execute_string ("%s", defun_arg); */
else
- add_word (defun_arg);
+ execute_string ("%s", defun_arg);
}
}
static char *
-next_nonwhite_defun_arg (arg_pointer)
- char ***arg_pointer;
+next_nonwhite_defun_arg (char ***arg_pointer)
{
char **scan = (*arg_pointer);
char *arg = (*scan++);
@@ -296,10 +299,9 @@ next_nonwhite_defun_arg (arg_pointer)
/* This is needed also in insertion.c. */
enum insertion_type
-get_base_type (type)
- enum insertion_type type;
+get_base_type (int type)
{
- enum insertion_type base_type;
+ int base_type;
switch (type)
{
case defivar: base_type = defcv; break;
@@ -307,6 +309,7 @@ get_base_type (type)
case defmethod: base_type = defop; break;
case defopt: base_type = defvr; break;
case defspec: base_type = deffn; break;
+ case deftypecv: base_type = deftypecv; break;
case deftypefun: base_type = deftypefn; break;
case deftypeivar: base_type = deftypeivar; break;
case deftypemethod: base_type = deftypemethod; break;
@@ -326,14 +329,14 @@ get_base_type (type)
TYPE says which insertion this is.
X_P, if nonzero, says not to start a new insertion. */
static void
-defun_internal (type, x_p)
- enum insertion_type type;
- int x_p;
+defun_internal (int type, int x_p)
{
- enum insertion_type base_type;
+ int base_type;
char **defun_args, **scan_args;
const char *category;
- char *defined_name, *type_name, *type_name2;
+ char *defined_name;
+ char *type_name = NULL;
+ char *type_name2 = NULL;
{
char *line;
@@ -355,6 +358,33 @@ defun_internal (type, x_p)
Unfortunately, this means that you can't call macros, use @value, etc.
inside @def.. commands, sigh. */
get_rest_of_line (0, &line);
+
+ /* Basic line continuation. If a line ends with \s*@\s* concatanate
+ the next line. */
+ {
+ char *next_line, *new_line;
+ int i;
+
+ line_continuation:
+ i = strlen (line) - 1;
+
+ if (line[i] == '@' && line[i-1] != '@')
+ {
+ get_rest_of_line (0, &next_line);
+ new_line = (char *) xmalloc (i + strlen (next_line) + 2);
+ strncpy (new_line, line, i);
+ new_line[i] = '\0';
+ free (line);
+ strcat (new_line, " ");
+ strcat (new_line, next_line);
+ line = xstrdup (new_line);
+ free (next_line);
+ free (new_line);
+
+ goto line_continuation;
+ }
+ }
+
defun_args = (args_from_string (line));
free (line);
}
@@ -399,7 +429,8 @@ defun_internal (type, x_p)
}
/* The class name. */
- if ((base_type == deftypefn)
+ if ((base_type == deftypecv)
+ || (base_type == deftypefn)
|| (base_type == deftypevr)
|| (base_type == defcv)
|| (base_type == defop)
@@ -410,8 +441,9 @@ defun_internal (type, x_p)
type_name = next_nonwhite_defun_arg (&scan_args);
/* The type name for typed languages. */
- if ((base_type == deftypemethod)
+ if ((base_type == deftypecv)
|| (base_type == deftypeivar)
+ || (base_type == deftypemethod)
|| (base_type == deftypeop)
)
type_name2 = next_nonwhite_defun_arg (&scan_args);
@@ -452,131 +484,115 @@ defun_internal (type, x_p)
current_indent -= default_indentation_increment;
start_paragraph ();
- if (!x_p) {
- /* Start the definition on new paragraph. */
- if (html)
- add_word ("<p>\n");
- }
-
- if (!html && !docbook)
+ if (!html && !xml)
switch (base_type)
{
case deffn:
case defvr:
case deftp:
- execute_string (" -- %s: %s", category, defined_name);
+ execute_string (" --- %s: %s", category, defined_name);
break;
case deftypefn:
case deftypevr:
- execute_string (" -- %s: %s %s", category, type_name, defined_name);
+ execute_string (" --- %s: %s %s", category, type_name, defined_name);
break;
case defcv:
- execute_string (" -- %s %s %s: %s", category, _("of"), type_name,
+ execute_string (" --- %s %s %s: %s", category, _("of"), type_name,
defined_name);
break;
+ case deftypecv:
case deftypeivar:
- execute_string (" -- %s %s %s: %s %s", category, _("of"), type_name,
+ execute_string (" --- %s %s %s: %s %s", category, _("of"), type_name,
type_name2, defined_name);
break;
case defop:
- execute_string (" -- %s %s %s: %s", category, _("on"), type_name,
+ execute_string (" --- %s %s %s: %s", category, _("on"), type_name,
defined_name);
break;
case deftypeop:
- execute_string (" -- %s %s %s: %s %s", category, _("on"), type_name,
+ execute_string (" --- %s %s %s: %s %s", category, _("on"), type_name,
type_name2, defined_name);
break;
case deftypemethod:
- execute_string (" -- %s %s %s: %s %s", category, _("on"), type_name,
+ execute_string (" --- %s %s %s: %s %s", category, _("on"), type_name,
type_name2, defined_name);
break;
}
-
- if (html)
+ else if (html)
{
/* If this is not a @def...x version, it could only
be a normal version @def.... So start the table here. */
if (!x_p)
- {
- add_html_elt ("<table width=");
- add_word ("\"100%\">\n");
- }
-
- /* If this is an @def...x there has to be an other @def... before
- it, so this is only a new row within an existing table. With
- two complete standalone tables the gap between them is too big. */
- add_word ("<tr>\n");
- add_html_elt ("<td align=\"left\">");
+ insert_string ("<div class=\"defun\">\n");
+ else
+ rollback_empty_tag ("blockquote");
+ /* xx The single words (on, off) used here, should depend on
+ documentlanguage and NOT on gettext --kama. */
switch (base_type)
{
case deffn:
case defvr:
case deftp:
- /* <i> is for the following function arguments. */
- insert_html_tag (START, "b");
- execute_string ("%s", defined_name);
- insert_html_tag (END, "b");
- insert_html_tag (START, "i");
- break;
case deftypefn:
case deftypevr:
- execute_string ("%s ", type_name);
- insert_html_tag (START, "b");
- execute_string ("%s", defined_name);
- insert_html_tag (END, "b");
- insert_html_tag (START, "i");
+ execute_string ("--- %s: ", category);
break;
+
case defcv:
+ case deftypecv:
+ case deftypeivar:
+ execute_string ("--- %s %s %s: ", category, _("of"), type_name);
+ break;
+
case defop:
- insert_html_tag (START, "b");
- execute_string ("%s", defined_name);
- insert_html_tag (END, "b");
- insert_html_tag (START, "i");
- break;
case deftypemethod:
case deftypeop:
- case deftypeivar:
- execute_string ("%s ", type_name2);
- insert_html_tag (START, "b");
- execute_string ("%s", defined_name);
- insert_html_tag (END, "b");
- insert_html_tag (START, "i");
- break;
- }
- } /* if (html)... */
+ execute_string ("--- %s %s %s: ", category, _("on"), type_name);
+ break;
+ } /* switch (base_type)... */
- if (docbook)
- {
switch (base_type)
{
case deffn:
case defvr:
case deftp:
- case defcv:
- case defop:
- xml_insert_element (FUNCTION, START);
+ /* <var> is for the following function arguments. */
+ insert_html_tag (START, "b");
execute_string ("%s", defined_name);
- xml_insert_element (FUNCTION, END);
+ insert_html_tag (END, "b");
+ insert_html_tag (START, "var");
break;
case deftypefn:
case deftypevr:
execute_string ("%s ", type_name);
- xml_insert_element (FUNCTION, START);
+ insert_html_tag (START, "b");
execute_string ("%s", defined_name);
- xml_insert_element (FUNCTION, END);
+ insert_html_tag (END, "b");
+ insert_html_tag (START, "var");
break;
+ case defcv:
+ case defop:
+ insert_html_tag (START, "b");
+ execute_string ("%s", defined_name);
+ insert_html_tag (END, "b");
+ insert_html_tag (START, "var");
+ break;
+ case deftypecv:
+ case deftypeivar:
case deftypemethod:
case deftypeop:
- case deftypeivar:
execute_string ("%s ", type_name2);
- xml_insert_element (FUNCTION, START);
+ insert_html_tag (START, "b");
execute_string ("%s", defined_name);
- xml_insert_element (FUNCTION, END);
+ insert_html_tag (END, "b");
+ insert_html_tag (START, "var");
break;
}
-
- } /* if (docbook)... */
+ }
+ else if (xml)
+ xml_begin_def_term (base_type, category, defined_name, type_name,
+ type_name2);
current_indent += default_indentation_increment;
@@ -606,95 +622,52 @@ defun_internal (type, x_p)
}
current_indent -= default_indentation_increment;
- close_single_paragraph ();
-
- if (html)
- {
- /* xx The single words (on, off) used here, should depend on
- documentlanguage and NOT on gettext --kama. */
- switch (base_type)
- {
- case deffn:
- case defvr:
- case deftp:
- case deftypefn:
- case deftypevr:
- insert_html_tag (END, "i"); /* close italic area for arguments */
- /* put the rest into the second column */
- add_word ("</td>\n");
- add_html_elt ("<td align=\"right\">");
- execute_string ("%s", category);
- break;
-
- case defcv:
- add_word ("</td>\n");
- add_html_elt ("<td align=\"right\">");
- execute_string ("%s %s %s", category, _("of"), type_name);
- break;
-
- case defop:
- case deftypemethod:
- case deftypeop:
- insert_html_tag (END, "i");
- add_word ("</td>\n");
- add_html_elt ("<td align=\"right\">");
- execute_string ("%s %s %s", category, _("on"), type_name);
- break;
-
- case deftypeivar:
- insert_html_tag (END, "i");
- add_word ("</td>\n");
- add_html_elt ("<td align=\"right\">");
- execute_string ("%s %s %s", category, _("of"), type_name);
- break;
- } /* switch (base_type)... */
+ if (!html)
+ close_single_paragraph ();
- add_word ("</td>\n"); /* close second column */
- add_word ("</tr>\n"); /* close row */
-
- /* This is needed because I have to know if the next line is
- normal text or another @def..x. If text follows, create a new
- table to get the indentation for the following text.
-
- This construction would fail if someone uses:
- @deffn
- @sp 2
- @deffnx
- .
- @end deffn
- But we don't care. */
- if (!looking_at ("@def"))
- {
- add_word ("</table>\n");
- add_html_elt ("<table width=\"95%\" align=\"center\">");
- add_word ("\n<tr><td>\n");
- }
-
- } /* if (html)... */
+ /* Make an entry in the appropriate index. (XML and
+ Docbook already got their entries, so skip them.) */
+ if (!xml)
+ switch (base_type)
+ {
+ case deffn:
+ case deftypefn:
+ execute_string ("@findex %s\n", defined_name);
+ break;
+ case defcv:
+ case deftypecv:
+ case deftypevr:
+ case defvr:
+ execute_string ("@vindex %s\n", defined_name);
+ break;
+ case deftypeivar:
+ execute_string ("@vindex %s %s %s\n", defined_name, _("of"),
+ type_name);
+ break;
+ case defop:
+ case deftypeop:
+ case deftypemethod:
+ execute_string ("@findex %s %s %s\n", defined_name, _("on"),
+ type_name);
+ break;
+ case deftp:
+ execute_string ("@tindex %s\n", defined_name);
+ break;
+ }
- /* Make an entry in the appropriate index. */
- switch (base_type)
+ if (xml)
+ xml_end_def_term ();
+ else if (html)
{
- case deffn:
- case deftypefn:
- execute_string ("@findex %s\n", defined_name);
- break;
- case defvr:
- case deftypevr:
- case defcv:
- execute_string ("@vindex %s\n", defined_name);
- break;
- case deftypeivar:
- execute_string ("@vindex %s %s %s\n", defined_name, _("of"), type_name);
- break;
- case defop:
- case deftypeop:
- case deftypemethod:
- execute_string ("@findex %s %s %s\n", defined_name, _("on"), type_name);
- break;
- case deftp:
- execute_string ("@tindex %s\n", defined_name);
- break;
+ inhibit_paragraph_indentation = 1;
+ no_indent = 1;
+ insert_html_tag (END, "var");
+ insert_string ("<br>\n");
+ /* Indent the definition a bit. */
+ add_html_block_elt ("<blockquote>");
+ no_indent = 0;
+ inhibit_paragraph_indentation = 0;
+ paragraph_is_open = 0;
}
/* Deallocate the token list. */
@@ -713,9 +686,9 @@ defun_internal (type, x_p)
If the name of the calling command ends in `x', then this is an extra
entry included in the body of an insertion of the same type. */
void
-cm_defun ()
+cm_defun (void)
{
- enum insertion_type type;
+ int type;
char *base_command = xstrdup (command); /* command with any `x' removed */
int x_p = (command[strlen (command) - 1] == 'x');
@@ -726,15 +699,22 @@ cm_defun ()
/* If we are adding to an already existing insertion, then make sure
that we are already in an insertion of type TYPE. */
- if (x_p && (!insertion_level || insertion_stack->insertion != type))
+ if (x_p)
{
- line_error (_("Must be in `@%s' environment to use `@%s'"),
- base_command, command);
- discard_until ("\n");
- return;
+ INSERTION_ELT *i = insertion_stack;
+ /* Skip over ifclear and ifset conditionals. */
+ while (i && (i->insertion == ifset || i->insertion == ifclear))
+ i = i->next;
+
+ if (!i || i->insertion != type)
+ {
+ line_error (_("Must be in `@%s' environment to use `@%s'"),
+ base_command, command);
+ discard_until ("\n");
+ return;
+ }
}
- else
- defun_internal (type, x_p);
+ defun_internal (type, x_p);
free (base_command);
}
diff --git a/contrib/texinfo/makeinfo/defun.h b/contrib/texinfo/makeinfo/defun.h
index a701201..9af73ec 100644
--- a/contrib/texinfo/makeinfo/defun.h
+++ b/contrib/texinfo/makeinfo/defun.h
@@ -1,5 +1,5 @@
/* defun.h -- declaration for defuns.
- $Id: defun.h,v 1.1 2002/08/25 23:38:38 karl Exp $
+ $Id: defun.h,v 1.2 2004/04/11 17:56:47 karl Exp $
Copyright (C) 1999 Free Software Foundation, Inc.
@@ -24,8 +24,8 @@
#include "insertion.h"
-extern enum insertion_type get_base_type ();
-extern void cm_defun ();
+extern enum insertion_type get_base_type (int type);
+extern void cm_defun (void);
#endif /* !DEFUN_H */
diff --git a/contrib/texinfo/makeinfo/files.c b/contrib/texinfo/makeinfo/files.c
index a6a69d2..db11226 100644
--- a/contrib/texinfo/makeinfo/files.c
+++ b/contrib/texinfo/makeinfo/files.c
@@ -1,7 +1,7 @@
/* files.c -- file-related functions for makeinfo.
- $Id: files.c,v 1.3 2003/03/06 14:05:30 karl Exp $
+ $Id: files.c,v 1.5 2004/07/27 00:06:31 karl Exp $
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
Foundation, Inc.
This program is free software; you can redistribute it and/or modify
@@ -20,15 +20,17 @@
#include "system.h"
#include "files.h"
+#include "html.h"
+#include "index.h"
#include "macro.h"
#include "makeinfo.h"
+#include "node.h"
FSTACK *filestack = NULL;
static int node_filename_stack_index = 0;
static int node_filename_stack_size = 0;
static char **node_filename_stack = NULL;
-
/* Looking for include files. */
@@ -36,9 +38,7 @@ static char **node_filename_stack = NULL;
return the next one pointed to by INDEX, or NULL if there are no more.
Advance INDEX to the character after the colon. */
static char *
-extract_colon_unit (string, index)
- char *string;
- int *index;
+extract_colon_unit (char *string, int *index)
{
int start;
int path_sep_char = PATH_SEP[0];
@@ -84,9 +84,7 @@ extract_colon_unit (string, index)
If PATH is NULL, only the current directory is searched.
If the file could not be found, return a NULL pointer. */
char *
-get_file_info_in_path (filename, path, finfo)
- char *filename, *path;
- struct stat *finfo;
+get_file_info_in_path (char *filename, char *path, struct stat *finfo)
{
char *dir;
int result, index = 0;
@@ -129,12 +127,68 @@ get_file_info_in_path (filename, path, finfo)
}
return NULL;
}
+
+/* Prepend and append new paths to include_files_path. */
+void
+prepend_to_include_path (char *path)
+{
+ if (!include_files_path)
+ {
+ include_files_path = xstrdup (path);
+ include_files_path = xrealloc (include_files_path,
+ strlen (include_files_path) + 3); /* 3 for ":.\0" */
+ strcat (strcat (include_files_path, PATH_SEP), ".");
+ }
+ else
+ {
+ char *tmp = xstrdup (include_files_path);
+ include_files_path = xrealloc (include_files_path,
+ strlen (include_files_path) + strlen (path) + 2); /* 2 for ":\0" */
+ strcpy (include_files_path, path);
+ strcat (include_files_path, PATH_SEP);
+ strcat (include_files_path, tmp);
+ free (tmp);
+ }
+}
+
+void
+append_to_include_path (char *path)
+{
+ if (!include_files_path)
+ include_files_path = xstrdup (".");
+
+ include_files_path = (char *) xrealloc (include_files_path,
+ 2 + strlen (include_files_path) + strlen (path));
+ strcat (include_files_path, PATH_SEP);
+ strcat (include_files_path, path);
+}
+
+/* Remove the first path from the include_files_path. */
+void
+pop_path_from_include_path (void)
+{
+ int i = 0;
+ char *tmp;
+
+ if (include_files_path)
+ for (i = 0; i < strlen (include_files_path)
+ && include_files_path[i] != ':'; i++);
+
+ /* Advance include_files_path to the next char from ':' */
+ tmp = (char *) xmalloc (strlen (include_files_path) - i);
+ strcpy (tmp, (char *) include_files_path + i + 1);
+
+ free (include_files_path);
+ include_files_path = tmp;
+}
/* Find and load the file named FILENAME. Return a pointer to
- the loaded file, or NULL if it can't be loaded. */
+ the loaded file, or NULL if it can't be loaded. If USE_PATH is zero,
+ just look for the given file (this is used in handle_delayed_writes),
+ else search along include_files_path. */
+
char *
-find_and_load (filename)
- char *filename;
+find_and_load (char *filename, int use_path)
{
struct stat fileinfo;
long file_size;
@@ -144,7 +198,9 @@ find_and_load (filename)
result = fullpath = NULL;
- fullpath = get_file_info_in_path (filename, include_files_path, &fileinfo);
+ fullpath
+ = get_file_info_in_path (filename, use_path ? include_files_path : NULL,
+ &fileinfo);
if (!fullpath)
goto error_exit;
@@ -205,8 +261,8 @@ error_exit:
}
/* Pushing and popping files. */
-void
-push_node_filename ()
+static void
+push_node_filename (void)
{
if (node_filename_stack_index + 1 > node_filename_stack_size)
node_filename_stack = xrealloc
@@ -216,15 +272,15 @@ push_node_filename ()
node_filename_stack_index++;
}
-void
-pop_node_filename ()
+static void
+pop_node_filename (void)
{
node_filename = node_filename_stack[--node_filename_stack_index];
}
/* Save the state of the current input file. */
void
-pushfile ()
+pushfile (void)
{
FSTACK *newstack = xmalloc (sizeof (FSTACK));
newstack->filename = input_filename;
@@ -240,7 +296,7 @@ pushfile ()
/* Make the current file globals be what is on top of the file stack. */
void
-popfile ()
+popfile (void)
{
FSTACK *tos = filestack;
@@ -274,7 +330,7 @@ popfile ()
/* Flush all open files on the file stack. */
void
-flush_file_stack ()
+flush_file_stack (void)
{
while (filestack)
{
@@ -289,8 +345,7 @@ flush_file_stack ()
/* Return the index of the first character in the filename
which is past all the leading directory characters. */
static int
-skip_directory_part (filename)
- char *filename;
+skip_directory_part (char *filename)
{
int i = strlen (filename) - 1;
@@ -304,9 +359,8 @@ skip_directory_part (filename)
return i;
}
-char *
-filename_non_directory (name)
- char *name;
+static char *
+filename_non_directory (char *name)
{
return xstrdup (name + skip_directory_part (name));
}
@@ -315,8 +369,7 @@ filename_non_directory (name)
filename without the path information, or extensions.
This conses up a new string. */
char *
-filename_part (filename)
- char *filename;
+filename_part (char *filename)
{
char *basename = filename_non_directory (filename);
@@ -333,10 +386,8 @@ filename_part (filename)
/* Return the pathname part of filename. This can be NULL. */
char *
-pathname_part (filename)
- char *filename;
+pathname_part (char *filename)
{
- char *expand_filename ();
char *result = NULL;
int i;
@@ -353,72 +404,9 @@ pathname_part (filename)
return result;
}
-/* Return the expansion of FILENAME. */
-char *
-expand_filename (filename, input_name)
- char *filename, *input_name;
-{
- int i;
- char *full_pathname ();
-
- if (filename)
- {
- filename = full_pathname (filename);
- if (IS_ABSOLUTE (filename)
- || (*filename == '.' &&
- (IS_SLASH (filename[1]) ||
- (filename[1] == '.' && IS_SLASH (filename[2])))))
- return filename;
- }
- else
- {
- filename = filename_non_directory (input_name);
-
- if (!*filename)
- {
- free (filename);
- filename = xstrdup ("noname.texi");
- }
-
- for (i = strlen (filename) - 1; i; i--)
- if (filename[i] == '.')
- break;
-
- if (!i)
- i = strlen (filename);
-
- if (i + 6 > (strlen (filename)))
- filename = xrealloc (filename, i + 6);
- strcpy (filename + i, html ? ".html" : ".info");
- return filename;
- }
-
- if (IS_ABSOLUTE (input_name))
- {
- /* Make it so that relative names work. */
- char *result;
-
- i = strlen (input_name) - 1;
-
- result = xmalloc (1 + strlen (input_name) + strlen (filename));
- strcpy (result, input_name);
-
- while (!IS_SLASH (result[i]) && i)
- i--;
- if (IS_SLASH (result[i]))
- i++;
-
- strcpy (&result[i], filename);
- free (filename);
- return result;
- }
- return filename;
-}
-
/* Return the full path to FILENAME. */
-char *
-full_pathname (filename)
- char *filename;
+static char *
+full_pathname (char *filename)
{
int initial_character;
char *result;
@@ -508,9 +496,68 @@ full_pathname (filename)
return result;
}
+/* Return the expansion of FILENAME. */
char *
-output_name_from_input_name (name)
- char *name;
+expand_filename (char *filename, char *input_name)
+{
+ int i;
+
+ if (filename)
+ {
+ filename = full_pathname (filename);
+ if (IS_ABSOLUTE (filename)
+ || (*filename == '.' &&
+ (IS_SLASH (filename[1]) ||
+ (filename[1] == '.' && IS_SLASH (filename[2])))))
+ return filename;
+ }
+ else
+ {
+ filename = filename_non_directory (input_name);
+
+ if (!*filename)
+ {
+ free (filename);
+ filename = xstrdup ("noname.texi");
+ }
+
+ for (i = strlen (filename) - 1; i; i--)
+ if (filename[i] == '.')
+ break;
+
+ if (!i)
+ i = strlen (filename);
+
+ if (i + 6 > (strlen (filename)))
+ filename = xrealloc (filename, i + 6);
+ strcpy (filename + i, html ? ".html" : ".info");
+ return filename;
+ }
+
+ if (IS_ABSOLUTE (input_name))
+ {
+ /* Make it so that relative names work. */
+ char *result;
+
+ i = strlen (input_name) - 1;
+
+ result = xmalloc (1 + strlen (input_name) + strlen (filename));
+ strcpy (result, input_name);
+
+ while (!IS_SLASH (result[i]) && i)
+ i--;
+ if (IS_SLASH (result[i]))
+ i++;
+
+ strcpy (&result[i], filename);
+ free (filename);
+ return result;
+ }
+ return filename;
+}
+
+char *
+output_name_from_input_name (char *name)
{
return expand_filename (NULL, name);
}
@@ -522,8 +569,7 @@ output_name_from_input_name (name)
never be longer than the original, otherwise we couldn't be sure we
have enough space in the original string to modify it in place. */
char *
-normalize_filename (fname)
- char *fname;
+normalize_filename (char *fname)
{
int maxlen;
char orig[PATH_MAX + 1];
@@ -573,3 +619,166 @@ normalize_filename (fname)
return fname;
}
+
+/* Delayed writing functions. A few of the commands
+ needs to be handled at the end, namely @contents,
+ @shortcontents, @printindex and @listoffloats.
+ These functions take care of that. */
+static DELAYED_WRITE *delayed_writes = NULL;
+int handling_delayed_writes = 0;
+
+void
+register_delayed_write (char *delayed_command)
+{
+ DELAYED_WRITE *new;
+
+ if (!current_output_filename || !*current_output_filename)
+ {
+ /* Cannot register if we don't know what the output file is. */
+ warning (_("`%s' omitted before output filename"), delayed_command);
+ return;
+ }
+
+ if (STREQ (current_output_filename, "-"))
+ {
+ /* Do not register a new write if the output file is not seekable.
+ Let the user know about it first, though. */
+ warning (_("`%s' omitted since writing to stdout"), delayed_command);
+ return;
+ }
+
+ /* Don't complain if the user is writing /dev/null, since surely they
+ don't care, but don't register the delayed write, either. */
+ if (FILENAME_CMP (current_output_filename, NULL_DEVICE) == 0
+ || FILENAME_CMP (current_output_filename, ALSO_NULL_DEVICE) == 0)
+ return;
+
+ /* We need the HTML header in the output,
+ to get a proper output_position. */
+ if (!executing_string && html)
+ html_output_head ();
+ /* Get output_position updated. */
+ flush_output ();
+
+ new = xmalloc (sizeof (DELAYED_WRITE));
+ new->command = xstrdup (delayed_command);
+ new->filename = xstrdup (current_output_filename);
+ new->input_filename = xstrdup (input_filename);
+ new->position = output_position;
+ new->calling_line = line_number;
+ new->node = current_node ? xstrdup (current_node): "";
+
+ new->node_order = node_order;
+ new->index_order = index_counter;
+
+ new->next = delayed_writes;
+ delayed_writes = new;
+}
+
+void
+handle_delayed_writes (void)
+{
+ DELAYED_WRITE *temp = (DELAYED_WRITE *) reverse_list
+ ((GENERIC_LIST *) delayed_writes);
+ int position_shift_amount, line_number_shift_amount;
+ char *delayed_buf;
+
+ handling_delayed_writes = 1;
+
+ while (temp)
+ {
+ delayed_buf = find_and_load (temp->filename, 0);
+
+ if (output_paragraph_offset > 0)
+ {
+ error (_("Output buffer not empty."));
+ return;
+ }
+
+ if (!delayed_buf)
+ {
+ fs_error (temp->filename);
+ return;
+ }
+
+ output_stream = fopen (temp->filename, "w");
+ if (!output_stream)
+ {
+ fs_error (temp->filename);
+ return;
+ }
+
+ if (fwrite (delayed_buf, 1, temp->position, output_stream) != temp->position)
+ {
+ fs_error (temp->filename);
+ return;
+ }
+
+ {
+ int output_position_at_start = output_position;
+ int line_number_at_start = output_line_number;
+
+ /* In order to make warnings and errors
+ refer to the correct line number. */
+ input_filename = temp->input_filename;
+ line_number = temp->calling_line;
+
+ execute_string ("%s", temp->command);
+ flush_output ();
+
+ /* Since the output file is modified, following delayed writes
+ need to be updated by this amount. */
+ position_shift_amount = output_position - output_position_at_start;
+ line_number_shift_amount = output_line_number - line_number_at_start;
+ }
+
+ if (fwrite (delayed_buf + temp->position, 1,
+ input_text_length - temp->position, output_stream)
+ != input_text_length - temp->position
+ || fclose (output_stream) != 0)
+ fs_error (temp->filename);
+
+ /* Done with the buffer. */
+ free (delayed_buf);
+
+ /* Update positions in tag table for nodes that are defined after
+ the line this delayed write is registered. */
+ if (!html && !xml)
+ {
+ TAG_ENTRY *node;
+ for (node = tag_table; node; node = node->next_ent)
+ if (node->order > temp->node_order)
+ node->position += position_shift_amount;
+ }
+
+ /* Something similar for the line numbers in all of the defined
+ indices. */
+ {
+ int i;
+ for (i = 0; i < defined_indices; i++)
+ if (name_index_alist[i])
+ {
+ char *name = ((INDEX_ALIST *) name_index_alist[i])->name;
+ INDEX_ELT *index;
+ for (index = index_list (name); index; index = index->next)
+ if ((no_headers || STREQ (index->node, temp->node))
+ && index->entry_number > temp->index_order)
+ index->output_line += line_number_shift_amount;
+ }
+ }
+
+ /* Shift remaining delayed positions
+ by the length of this write. */
+ {
+ DELAYED_WRITE *future_write = temp->next;
+ while (future_write)
+ {
+ if (STREQ (temp->filename, future_write->filename))
+ future_write->position += position_shift_amount;
+ future_write = future_write->next;
+ }
+ }
+
+ temp = temp->next;
+ }
+}
diff --git a/contrib/texinfo/makeinfo/files.h b/contrib/texinfo/makeinfo/files.h
index 0e1cde3..0943663 100644
--- a/contrib/texinfo/makeinfo/files.h
+++ b/contrib/texinfo/makeinfo/files.h
@@ -1,7 +1,7 @@
/* files.h -- declarations for files.c.
- $Id: files.h,v 1.2 2003/03/06 14:05:30 karl Exp $
+ $Id: files.h,v 1.4 2004/07/27 00:06:31 karl Exp $
- Copyright (C) 1998, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 2002, 2004 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -34,14 +34,37 @@ typedef struct fstack
} FSTACK;
extern FSTACK *filestack;
-extern void pushfile (), popfile ();
-extern void flush_file_stack ();
-extern char *get_file_info_in_path ();
-extern char *find_and_load ();
-extern char *output_name_from_input_name ();
-extern char *expand_filename ();
-extern char *filename_part ();
-extern char *pathname_part ();
-extern char *normalize_filename ();
+extern void pushfile (void);
+extern void popfile (void);
+extern void flush_file_stack (void);
+extern char *get_file_info_in_path (char *filename, char *path,
+ struct stat *finfo);
+extern char *find_and_load (char *filename, int use_path);
+extern char *output_name_from_input_name (char *name);
+extern char *expand_filename (char *filename, char *input_name);
+extern char *filename_part (char *filename);
+extern char *pathname_part (char *filename);
+extern char *normalize_filename (char *fname);
+extern void append_to_include_path (char *path);
+extern void prepend_to_include_path (char *path);
+extern void pop_path_from_include_path (void);
+extern void register_delayed_write (char *delayed_command);
+extern void handle_delayed_writes (void);
+
+typedef struct delayed_write
+{
+ struct delayed_write *next;
+ char *command;
+ char *filename;
+ char *input_filename;
+ char *node;
+ int position;
+ int calling_line;
+
+ int node_order;
+ int index_order;
+} DELAYED_WRITE;
+
+extern int handling_delayed_writes;
#endif /* !FILES_H */
diff --git a/contrib/texinfo/makeinfo/float.c b/contrib/texinfo/makeinfo/float.c
new file mode 100644
index 0000000..b2c9a33
--- /dev/null
+++ b/contrib/texinfo/makeinfo/float.c
@@ -0,0 +1,430 @@
+/* float.c -- float environment functions.
+ $Id: float.c,v 1.8 2004/07/05 22:23:22 karl Exp $
+
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Originally written by Alper Ersoy <dirt@gtk.org>. */
+
+#include "system.h"
+#include "makeinfo.h"
+#include "cmds.h"
+#include "files.h"
+#include "float.h"
+#include "html.h"
+#include "sectioning.h"
+#include "xml.h"
+
+static FLOAT_ELT *float_stack = NULL;
+
+void
+add_new_float (char *id, char *title, char *shorttitle,
+ char *type, char *position)
+{
+ FLOAT_ELT *new = xmalloc (sizeof (FLOAT_ELT));
+ unsigned long num_len;
+
+ new->id = id;
+ new->type = type;
+ new->title = title;
+ new->shorttitle = shorttitle;
+ new->position = position;
+ new->title_used = 0;
+ new->defining_line = line_number - 1;
+
+ new->number = current_chapter_number ();
+ /* Append dot if not @unnumbered. */
+ num_len = strlen (new->number);
+ if (num_len > 0)
+ {
+ new->number = xrealloc (new->number, num_len + 1 + 1);
+ new->number[num_len] = '.';
+ new->number[num_len+1] = '\0';
+ }
+
+ { /* Append the current float number. */
+ unsigned len = strlen (new->number) + 21; /* that's 64 bits */
+ char *s = xmalloc (len + 1);
+
+ sprintf (s, "%s%d", new->number,
+ count_floats_of_type_in_chapter (text_expansion (type),
+ new->number) + 1);
+ free (new->number);
+ new->number = xstrdup (s);
+ }
+
+ /* Plain text output needs sectioning number and its title,
+ when listing floats. */
+ if (!html && !xml && no_headers)
+ {
+ new->section = current_sectioning_number ();
+ if (strlen (new->section) == 0)
+ new->section_name = current_sectioning_name ();
+ else
+ new->section_name = "";
+ }
+
+ new->next = float_stack;
+ float_stack = new;
+}
+
+int
+count_floats_of_type_in_chapter (char *type, char *chapter)
+{
+ int i = 0;
+ int l = strlen (chapter);
+ FLOAT_ELT *temp = float_stack;
+
+ while (temp && strncmp (temp->number, chapter, l) == 0)
+ {
+ if (strlen (temp->id) > 0 && STREQ (text_expansion (temp->type), type))
+ i++;
+ temp = temp->next;
+ }
+
+ return i;
+}
+
+char *
+current_float_title (void)
+{
+ return float_stack->title;
+}
+
+char *
+current_float_shorttitle (void)
+{
+ return float_stack->shorttitle;
+}
+
+char *
+current_float_type (void)
+{
+ return float_stack->type;
+}
+
+char *
+current_float_position (void)
+{
+ return float_stack->position;
+}
+
+char *
+current_float_number (void)
+{
+ return float_stack->number;
+}
+
+char *
+current_float_id (void)
+{
+ return float_stack->id;
+}
+
+char *
+get_float_ref (char *id)
+{
+ FLOAT_ELT *temp = float_stack;
+
+ while (temp)
+ {
+ if (STREQ (id, temp->id))
+ {
+ char *s = xmalloc (strlen (temp->type) + strlen (temp->number) + 2);
+ sprintf (s, "%s %s", temp->type, temp->number);
+ return s;
+ }
+ temp = temp->next;
+ }
+
+ return NULL;
+}
+
+static int
+float_type_exists (char *check_type)
+{
+ /* Check if the requested float_type exists in the floats stack. */
+ FLOAT_ELT *temp;
+
+ for (temp = float_stack; temp; temp = temp->next)
+ if (STREQ (temp->type, check_type) && temp->id && *temp->id)
+ return 1;
+
+ return 0;
+}
+
+void
+cm_listoffloats (void)
+{
+ char *float_type;
+ get_rest_of_line (1, &float_type);
+
+ /* get_rest_of_line increments the line number by one,
+ so to make warnings/errors point to the correct line,
+ we decrement the line_number again. */
+ if (!handling_delayed_writes)
+ line_number--;
+
+ if (handling_delayed_writes && !float_type_exists (float_type))
+ warning (_("Requested float type `%s' not previously used"), float_type);
+
+ if (xml)
+ {
+ xml_insert_element_with_attribute (LISTOFFLOATS, START,
+ "type=\"%s\"", text_expansion (float_type));
+ xml_insert_element (LISTOFFLOATS, END);
+ }
+ else if (!handling_delayed_writes)
+ {
+ int command_len = sizeof ("@ ") + strlen (command) + strlen (float_type);
+ char *list_command = xmalloc (command_len + 1);
+
+ /* These are for the text following @listoffloats command.
+ Handling them with delayed writes is too late. */
+ close_paragraph ();
+ cm_noindent ();
+
+ sprintf (list_command, "@%s %s", command, float_type);
+ register_delayed_write (list_command);
+ free (list_command);
+ }
+ else if (float_type_exists (float_type))
+ {
+ FLOAT_ELT *temp = (FLOAT_ELT *) reverse_list
+ ((GENERIC_LIST *) float_stack);
+ FLOAT_ELT *new_start = temp;
+
+ if (html)
+ insert_string ("<ul class=\"listoffloats\">\n");
+ else
+ {
+ if (!no_headers)
+ insert_string ("* Menu:\n\n");
+ }
+
+ while (temp)
+ {
+ if (strlen (temp->id) > 0 && STREQ (float_type, temp->type))
+ {
+ if (html)
+ {
+ /* A bit of space for HTML reabality. */
+ insert_string (" ");
+ add_html_block_elt ("<li>");
+
+ /* Simply relying on @ref command doesn't work here, because
+ commas in the caption may confuse the argument parsing. */
+ add_word ("<a href=\"");
+ add_anchor_name (temp->id, 1);
+ add_word ("\">");
+
+ if (strlen (float_type) > 0)
+ execute_string ("%s", float_type);
+
+ if (strlen (temp->id) > 0)
+ {
+ if (strlen (float_type) > 0)
+ add_char (' ');
+
+ add_word (temp->number);
+ }
+
+ if (strlen (temp->title) > 0)
+ {
+ if (strlen (float_type) > 0
+ || strlen (temp->id) > 0)
+ insert_string (": ");
+
+ execute_string ("%s", temp->title);
+ }
+
+ add_word ("</a>");
+
+ add_html_block_elt ("</li>\n");
+ }
+ else
+ {
+ char *entry;
+ char *raw_entry;
+ char *title = expansion (temp->title, 0);
+
+ int len;
+ int aux_chars_len; /* these are asterisk, colon, etc. */
+ int column_width; /* width of the first column in menus. */
+ int number_len; /* length of Figure X.Y: etc. */
+ int i = 0;
+
+ /* Chosen widths are to match what @printindex produces. */
+ if (no_headers)
+ {
+ column_width = 43;
+ /* We have only one auxiliary character, NULL. */
+ aux_chars_len = sizeof ("");
+ }
+ else
+ {
+ column_width = 37;
+ /* We'll be adding an asterisk, followed by a space
+ and then a colon after the title, to construct a
+ proper menu item. */
+ aux_chars_len = sizeof ("* :");
+ }
+
+ /* Allocate enough space for possible expansion later. */
+ raw_entry = (char *) xmalloc (strlen (float_type)
+ + strlen (temp->number) + strlen (title)
+ + sizeof (": "));
+
+ sprintf (raw_entry, "%s %s", float_type, temp->number);
+
+ if (strlen (title) > 0)
+ strcat (raw_entry, ": ");
+
+ number_len = strlen (raw_entry);
+
+ len = strlen (title) + strlen (raw_entry);
+
+ /* If we have a @shortcaption, try it if @caption is
+ too long to fit on a line. */
+ if (len + aux_chars_len > column_width
+ && strlen (temp->shorttitle) > 0)
+ title = expansion (temp->shorttitle, 0);
+
+ strcat (raw_entry, title);
+ len = strlen (raw_entry);
+
+ if (len + aux_chars_len > column_width)
+ { /* Shorten long titles by looking for a space before
+ column_width - strlen (" ..."). */
+ /* -1 is for NULL, which is already in aux_chars_len. */
+ aux_chars_len += sizeof ("...") - 1;
+ len = column_width - aux_chars_len;
+ while (raw_entry[len] != ' ' && len >= 0)
+ len--;
+
+ /* Advance to the whitespace. */
+ len++;
+
+ /* If we are at the end of, say, Figure X.Y:, but
+ we have a title, then this means title does not
+ contain any whitespaces. Or it may be that we
+ went as far as the beginning. Just print as much
+ as possible of the title. */
+ if (len == 0
+ || (len == number_len && strlen (title) > 0))
+ len = column_width - sizeof ("...");
+
+ /* Break here. */
+ raw_entry[len] = 0;
+
+ entry = xmalloc (len + aux_chars_len);
+
+ if (!no_headers)
+ strcpy (entry, "* ");
+ else
+ entry[0] = 0;
+
+ strcat (entry, raw_entry);
+ strcat (entry, "...");
+
+ if (!no_headers)
+ strcat (entry, ":");
+ }
+ else
+ {
+ entry = xmalloc (len + aux_chars_len);
+
+ if (!no_headers)
+ strcpy (entry, "* ");
+ else
+ entry[0] = 0;
+
+ strcat (entry, raw_entry);
+
+ if (!no_headers)
+ strcat (entry, ":");
+ }
+
+ insert_string (entry);
+
+ i = strlen (entry);
+ /* We insert space chars until ``column_width + four spaces''
+ is reached, to make the layout the same with what we produce
+ for @printindex. This is of course not obligatory, though
+ easier on the eye. -1 is for NULL. */
+ while (i < column_width + sizeof (" ") - 1)
+ {
+ insert (' ');
+ i++;
+ }
+
+ if (no_headers)
+ {
+ if (strlen (temp->section) > 0)
+ { /* We got your number. */
+ insert_string ((char *) _("See "));
+ insert_string (temp->section);
+ }
+ else
+ { /* Sigh, @float in an @unnumbered. :-\ */
+ insert_string ("\n ");
+ insert_string ((char *) _("See "));
+ insert_string ("``");
+ insert_string (expansion (temp->section_name, 0));
+ insert_string ("''");
+ }
+ }
+ else
+ insert_string (temp->id);
+
+ insert_string (".\n");
+
+ free (entry);
+ free (title);
+ }
+ }
+ temp = temp->next;
+ }
+
+ if (html)
+ {
+ inhibit_paragraph_indentation = 1;
+ insert_string ("</ul>\n\n");
+ }
+ else
+ insert ('\n');
+
+ /* Retain the original order of float stack. */
+ temp = new_start;
+ float_stack = (FLOAT_ELT *) reverse_list ((GENERIC_LIST *) temp);
+ }
+
+ free (float_type);
+ /* Re-increment the line number, because get_rest_of_line
+ left us looking at the next line after the command. */
+ line_number++;
+}
+
+int
+current_float_used_title (void)
+{
+ return float_stack->title_used;
+}
+
+void current_float_set_title_used (void)
+{
+ float_stack->title_used = 1;
+}
diff --git a/contrib/texinfo/makeinfo/float.h b/contrib/texinfo/makeinfo/float.h
new file mode 100644
index 0000000..be9deb5
--- /dev/null
+++ b/contrib/texinfo/makeinfo/float.h
@@ -0,0 +1,56 @@
+/* float.h -- declarations for the float environment.
+ $Id: float.h,v 1.5 2004/04/11 17:56:47 karl Exp $
+
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Written by Alper Ersoy <dirt@gtk.org>. */
+
+#ifndef FLOAT_H
+#define FLOAT_H
+
+typedef struct float_elt
+{
+ struct float_elt *next;
+ char *id;
+ char *type;
+ char *title;
+ char *shorttitle;
+ char *position;
+ char *number;
+ char *section;
+ char *section_name;
+ short title_used;
+ int defining_line;
+} FLOAT_ELT;
+
+extern void add_new_float (char *id, char *title, char *shorttitle,
+ char *type, char *position);
+extern void current_float_set_title_used (void);
+
+/* Information retrieval about the current float env. */
+extern char *current_float_id (void);
+extern char *current_float_title (void);
+extern char *current_float_shorttitle (void);
+extern char *current_float_type (void);
+extern char *current_float_position (void);
+extern char *current_float_number (void);
+extern char *get_float_ref (char *id);
+
+extern int count_floats_of_type_in_chapter (char *type, char *chapter);
+extern int current_float_used_title (void);
+
+#endif /* not FLOAT_H */
diff --git a/contrib/texinfo/makeinfo/footnote.c b/contrib/texinfo/makeinfo/footnote.c
index 5a11028..e5a7f4c 100644
--- a/contrib/texinfo/makeinfo/footnote.c
+++ b/contrib/texinfo/makeinfo/footnote.c
@@ -1,5 +1,5 @@
/* footnote.c -- footnotes for Texinfo.
- $Id: footnote.c,v 1.4 2002/11/05 03:04:26 karl Exp $
+ $Id: footnote.c,v 1.7 2004/04/11 17:56:47 karl Exp $
Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
@@ -21,7 +21,9 @@
#include "footnote.h"
#include "macro.h"
#include "makeinfo.h"
+#include "node.h"
#include "xml.h"
+#include "xref.h"
/* Nonzero means that the footnote style for this document was set on
the command line, which overrides any other settings. */
@@ -53,11 +55,10 @@ int already_outputting_pending_notes = 0;
int footnote_style = end_node;
int first_footnote_this_node = 1;
int footnote_count = 0;
-
+
/* Set the footnote style based on the style identifier in STRING. */
int
-set_footnote_style (string)
- char *string;
+set_footnote_style (char *string)
{
if (strcasecmp (string, "separate") == 0)
footnote_style = separate_node;
@@ -70,7 +71,7 @@ set_footnote_style (string)
}
void
-cm_footnotestyle ()
+cm_footnotestyle (void)
{
char *arg;
@@ -95,9 +96,8 @@ FN *pending_notes = NULL;
/* A method for remembering footnotes. Note that this list gets output
at the end of the current node. */
-void
-remember_note (marker, note)
- char *marker, *note;
+static void
+remember_note (char *marker, char *note)
{
FN *temp = xmalloc (sizeof (FN));
@@ -111,7 +111,7 @@ remember_note (marker, note)
/* How to get rid of existing footnotes. */
static void
-free_pending_notes ()
+free_pending_notes (void)
{
FN *temp;
@@ -133,7 +133,7 @@ free_pending_notes ()
footnote *{this is a footnote}
where "*" is the (optional) marker character for this note. */
void
-cm_footnote ()
+cm_footnote (void)
{
char *marker;
char *note;
@@ -237,9 +237,12 @@ cm_footnote ()
`fn-<n>', though that's unlikely. */
if (html)
{
+ /* Hyperlink also serves as an anchor (mnemonic: fnd is footnote
+ definition.) */
add_html_elt ("<a rel=\"footnote\" href=");
- add_word_args ("\"#fn-%d\"><sup>%s</sup></a>",
- current_footnote_number, marker);
+ add_word_args ("\"#fn-%d\" name=\"fnd-%d\"><sup>%s</sup></a>",
+ current_footnote_number, current_footnote_number,
+ marker);
}
else
/* Your method should at least insert MARKER. */
@@ -282,7 +285,7 @@ cm_footnote ()
/* Output the footnotes. We are at the end of the current node. */
void
-output_pending_notes ()
+output_pending_notes (void)
{
FN *footnote = pending_notes;
@@ -290,13 +293,13 @@ output_pending_notes ()
return;
if (html)
- { /* The type= attribute is used just in case some weirdo browser
- out there doesn't use numbers by default. Since we rely on the
- browser to produce the footnote numbers, we need to make sure
- they ARE indeed numbers. Pre-HTML4 browsers seem to not care. */
- add_word ("<div class=\"footnote\">\n<hr>\n<h4>");
- add_word (_("Footnotes"));
- add_word ("</h4>\n<ol type=\"1\">\n");
+ {
+ add_html_block_elt ("<div class=\"footnote\">\n<hr>\n");
+ /* We add an anchor here so @printindex can refer to this point
+ (as the node name) for entries defined in footnotes. */
+ if (!splitting)
+ add_word ("<a name=\"texinfo-footnotes-in-document\"></a>");
+ add_word_args ("<h4>%s</h4>", (char *) _("Footnotes"));
}
else
switch (footnote_style)
@@ -329,6 +332,7 @@ output_pending_notes ()
/* Handle the footnotes in reverse order. */
{
+ int save_in_fixed_width_font = in_fixed_width_font;
FN **array = xmalloc ((footnote_count + 1) * sizeof (FN *));
array[footnote_count] = NULL;
@@ -340,14 +344,18 @@ output_pending_notes ()
filling_enabled = 1;
indented_fill = 1;
+ in_fixed_width_font = 0;
while ((footnote = array[++footnote_count]))
{
if (html)
{
/* Make the text of every footnote begin a separate paragraph. */
- add_word_args ("<li><a name=\"fn-%d\"></a>\n<p>",
- footnote->number);
+ add_html_block_elt ("<p class=\"footnote\"><small>");
+ /* Make footnote number a link to its definition. */
+ add_word_args ("[<a name=\"fn-%d\" href=\"#fnd-%d\">%d</a>]",
+ footnote->number, footnote->number, footnote->number);
+ add_word ("</small> ");
already_outputting_pending_notes++;
execute_string ("%s", footnote->note);
already_outputting_pending_notes--;
@@ -372,10 +380,12 @@ output_pending_notes ()
}
if (html)
- add_word ("</ol><hr></div>");
+ add_word ("<hr></div>");
close_paragraph ();
free (array);
+
+ in_fixed_width_font = save_in_fixed_width_font;
}
-
+
free_pending_notes ();
}
diff --git a/contrib/texinfo/makeinfo/footnote.h b/contrib/texinfo/makeinfo/footnote.h
index ad6ac85..e4f9510 100644
--- a/contrib/texinfo/makeinfo/footnote.h
+++ b/contrib/texinfo/makeinfo/footnote.h
@@ -1,7 +1,8 @@
/* footnote.h -- declarations for footnote.c.
- $Id: footnote.h,v 1.1 2002/08/25 23:38:38 karl Exp $
+ $Id: footnote.h,v 1.2 2004/04/11 17:56:47 karl Exp $
- Copyright (C) 1998 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
+ Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -27,11 +28,11 @@ extern int number_footnotes;
extern int already_outputting_pending_notes;
/* The Texinfo @commands. */
-extern void cm_footnote ();
-extern void cm_footnotestyle ();
+extern void cm_footnote (void);
+extern void cm_footnotestyle (void);
-extern int set_footnote_style (); /* called for -s option */
+extern int set_footnote_style (char *string); /* called for -s option */
-extern void output_pending_notes (); /* called for output */
+extern void output_pending_notes (void); /* called for output */
#endif /* !FOOTNOTE_H */
diff --git a/contrib/texinfo/makeinfo/html.c b/contrib/texinfo/makeinfo/html.c
index 0c06c6c..be2c136 100644
--- a/contrib/texinfo/makeinfo/html.c
+++ b/contrib/texinfo/makeinfo/html.c
@@ -1,7 +1,8 @@
/* html.c -- html-related utilities.
- $Id: html.c,v 1.18 2003/06/02 12:32:29 karl Exp $
+ $Id: html.c,v 1.28 2004/12/06 01:13:06 karl Exp $
- Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software
+ Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -19,115 +20,13 @@
#include "system.h"
#include "cmds.h"
+#include "files.h"
#include "html.h"
#include "lang.h"
#include "makeinfo.h"
+#include "node.h"
#include "sectioning.h"
-HSTACK *htmlstack = NULL;
-
-static char *process_css_file (/* char * */);
-
-/* See html.h. */
-int html_output_head_p = 0;
-int html_title_written = 0;
-
-
-void
-html_output_head ()
-{
- static const char *html_title = NULL;
-
- if (html_output_head_p)
- return;
- html_output_head_p = 1;
-
- /* The <title> should not have markup, so use text_expansion. */
- if (!html_title)
- html_title = title ? text_expansion (title) : _("Untitled");
-
- add_word_args ("<html lang=\"%s\">\n<head>\n<title>%s</title>\n",
- language_table[language_code].abbrev, html_title);
-
- add_word ("<meta http-equiv=\"Content-Type\" content=\"text/html");
- if (document_encoding_code != no_encoding)
- add_word_args ("; charset=%s",
- encoding_table[document_encoding_code].encname);
- add_word ("\">\n");
-
- if (!document_description)
- document_description = html_title;
-
- add_word_args ("<meta name=\"description\" content=\"%s\">\n",
- document_description);
- add_word_args ("<meta name=\"generator\" content=\"makeinfo %s\">\n",
- VERSION);
-#if 0
- /* let's not do this now, since it causes mozilla to put up a
- navigation bar. */
- add_word ("<link href=\"http://www.gnu.org/software/texinfo/\" \
-rel=\"generator-home\">\n");
-#endif
-
- if (copying_text)
- { /* copying_text has already been fully expanded in
- begin_insertion (by full_expansion), so use insert_ rather than
- add_. It is not ideal that we include the html markup here within
- <head>, but the alternative is to have yet more and different
- expansions of the copying text. Yuck. */
- insert_string ("<!--\n");
- insert_string (copying_text);
- insert_string ("-->\n");
- }
-
- /* Put the style definitions in a comment for the sake of browsers
- that don't support <style>. */
- add_word ("<meta http-equiv=\"Content-Style-Type\" content=\"text/css\">\n");
- add_word ("<style type=\"text/css\"><!--\n");
-
- {
- char *css_inline = NULL;
-
- if (css_include)
- /* This writes out any @import commands from the --css-file,
- and returns any actual css code following the imports. */
- css_inline = process_css_file (css_include);
-
- /* This seems cleaner than adding <br>'s at the end of each line for
- these "roman" displays. It's hardly the end of the world if the
- browser doesn't do <style>s, in any case; they'll just come out in
- typewriter. */
-#define CSS_FONT_INHERIT "font-family:inherit"
- add_word_args (" pre.display { %s }\n", CSS_FONT_INHERIT);
- add_word_args (" pre.format { %s }\n", CSS_FONT_INHERIT);
-
- /* Alternatively, we could do <font size=-1> in insertion.c, but this
- way makes it easier to override. */
-#define CSS_FONT_SMALLER "font-size:smaller"
- add_word_args (" pre.smalldisplay { %s; %s }\n", CSS_FONT_INHERIT,
- CSS_FONT_SMALLER);
- add_word_args (" pre.smallformat { %s; %s }\n", CSS_FONT_INHERIT,
- CSS_FONT_SMALLER);
- add_word_args (" pre.smallexample { %s }\n", CSS_FONT_SMALLER);
- add_word_args (" pre.smalllisp { %s }\n", CSS_FONT_SMALLER);
-
- /* Write out any css code from the user's --css-file. */
- if (css_inline)
- add_word (css_inline);
-
- add_word ("--></style>\n");
- }
-
- add_word ("</head>\n<body>\n");
-
- if (title && !html_title_written && titlepage_cmd_present)
- {
- add_word_args ("<h1 class=\"settitle\">%s</h1>\n", html_title);
- html_title_written = 1;
- }
-}
-
-
/* Append CHAR to BUFFER, (re)allocating as necessary. We don't handle
null characters. */
@@ -139,9 +38,8 @@ typedef struct
char *buffer;
} buffer_type;
-
static buffer_type *
-init_buffer ()
+init_buffer (void)
{
buffer_type *buf = xmalloc (sizeof (buffer_type));
buf->length = 0;
@@ -151,11 +49,8 @@ init_buffer ()
return buf;
}
-
static void
-append_char (buf, c)
- buffer_type *buf;
- int c;
+append_char (buffer_type *buf, int c)
{
buf->length++;
if (buf->length >= buf->size)
@@ -167,17 +62,15 @@ append_char (buf, c)
buf->buffer[buf->length] = 0;
}
-
/* Read the cascading style-sheet file FILENAME. Write out any @import
commands, which must come first, by the definition of css. If the
file contains any actual css code following the @imports, return it;
else return NULL. */
-
static char *
-process_css_file (filename)
- char *filename;
+process_css_file (char *filename)
{
- int c, lastchar;
+ int c;
+ int lastchar = 0;
FILE *f;
buffer_type *import_text = init_buffer ();
buffer_type *inline_text = init_buffer ();
@@ -185,6 +78,8 @@ process_css_file (filename)
enum { null_state, comment_state, import_state, inline_state } state
= null_state, prev_state;
+ prev_state = null_state;
+
/* read from stdin if `-' is the filename. */
f = STREQ (filename, "-") ? stdin : fopen (filename, "r");
if (!f)
@@ -204,12 +99,22 @@ process_css_file (filename)
{
case null_state: /* between things */
if (c == '@')
- {
- /* If there's some other @command, just call it an
- import, it's all the same to us. So don't bother
- looking for the `import'. */
- append_char (import_text, c);
- state = import_state;
+ { /* Only @import and @charset should switch into
+ import_state, other @-commands, such as @media, should
+ put us into inline_state. I don't think any other css
+ @-commands start with `i' or `c', although of course
+ this will break when such a command is defined. */
+ int nextchar = getc (f);
+ if (nextchar == 'i' || nextchar == 'c')
+ {
+ append_char (import_text, c);
+ state = import_state;
+ }
+ else
+ {
+ ungetc (nextchar, f); /* wasn't an @import */
+ state = inline_state;
+ }
}
else if (c == '/')
{ /* possible start of a comment */
@@ -277,23 +182,176 @@ process_css_file (filename)
/* We're wasting the buffer struct memory, but so what. */
return inline_text->buffer;
}
+
+HSTACK *htmlstack = NULL;
+
+/* See html.h. */
+int html_output_head_p = 0;
+int html_title_written = 0;
+
+void
+html_output_head (void)
+{
+ static const char *html_title = NULL;
+ char *encoding;
+
+ if (html_output_head_p)
+ return;
+ html_output_head_p = 1;
+
+ encoding = current_document_encoding ();
+
+ /* The <title> should not have markup, so use text_expansion. */
+ if (!html_title)
+ html_title = escape_string (title ?
+ text_expansion (title) : (char *) _("Untitled"));
+
+ /* Make sure this is the very first string of the output document. */
+ output_paragraph_offset = 0;
+
+ add_html_block_elt_args ("<html lang=\"%s\">\n<head>\n",
+ language_table[language_code].abbrev);
+
+ /* When splitting, add current node's name to title if it's available and not
+ Top. */
+ if (splitting && current_node && !STREQ (current_node, "Top"))
+ add_word_args ("<title>%s - %s</title>\n",
+ escape_string (xstrdup (current_node)), html_title);
+ else
+ add_word_args ("<title>%s</title>\n", html_title);
+
+ add_word ("<meta http-equiv=\"Content-Type\" content=\"text/html");
+ if (encoding && *encoding)
+ add_word_args ("; charset=%s", encoding);
+
+ add_word ("\">\n");
+
+ if (!document_description)
+ document_description = html_title;
+
+ add_word_args ("<meta name=\"description\" content=\"%s\">\n",
+ document_description);
+ add_word_args ("<meta name=\"generator\" content=\"makeinfo %s\">\n",
+ VERSION);
+
+ /* Navigation bar links. */
+ if (!splitting)
+ add_word ("<link title=\"Top\" rel=\"top\" href=\"#Top\">\n");
+ else if (tag_table)
+ {
+ /* Always put a top link. */
+ add_word ("<link title=\"Top\" rel=\"start\" href=\"index.html#Top\">\n");
+
+ /* We already have a top link, avoid duplication. */
+ if (tag_table->up && !STREQ (tag_table->up, "Top"))
+ add_link (tag_table->up, "rel=\"up\"");
+
+ if (tag_table->prev)
+ add_link (tag_table->prev, "rel=\"prev\"");
+
+ if (tag_table->next)
+ add_link (tag_table->next, "rel=\"next\"");
+
+ /* fixxme: Look for a way to put links to various indices in the
+ document. Also possible candidates to be added here are First and
+ Last links. */
+ }
+ else
+ {
+ /* We are splitting, but we neither have a tag_table. So this must be
+ index.html. So put a link to Top. */
+ add_word ("<link title=\"Top\" rel=\"start\" href=\"#Top\">\n");
+ }
+
+ add_word ("<link href=\"http://www.gnu.org/software/texinfo/\" \
+rel=\"generator-home\" title=\"Texinfo Homepage\">\n");
+
+ if (copying_text)
+ { /* It is not ideal that we include the html markup here within
+ <head>, so we use text_expansion. */
+ insert_string ("<!--\n");
+ insert_string (text_expansion (copying_text));
+ insert_string ("-->\n");
+ }
+
+ /* Put the style definitions in a comment for the sake of browsers
+ that don't support <style>. */
+ add_word ("<meta http-equiv=\"Content-Style-Type\" content=\"text/css\">\n");
+ add_word ("<style type=\"text/css\"><!--\n");
+
+ {
+ char *css_inline = NULL;
+
+ if (css_include)
+ /* This writes out any @import commands from the --css-file,
+ and returns any actual css code following the imports. */
+ css_inline = process_css_file (css_include);
+
+ /* This seems cleaner than adding <br>'s at the end of each line for
+ these "roman" displays. It's hardly the end of the world if the
+ browser doesn't do <style>s, in any case; they'll just come out in
+ typewriter. */
+#define CSS_FONT_INHERIT "font-family:inherit"
+ add_word_args (" pre.display { %s }\n", CSS_FONT_INHERIT);
+ add_word_args (" pre.format { %s }\n", CSS_FONT_INHERIT);
+
+ /* Alternatively, we could do <font size=-1> in insertion.c, but this
+ way makes it easier to override. */
+#define CSS_FONT_SMALLER "font-size:smaller"
+ add_word_args (" pre.smalldisplay { %s; %s }\n", CSS_FONT_INHERIT,
+ CSS_FONT_SMALLER);
+ add_word_args (" pre.smallformat { %s; %s }\n", CSS_FONT_INHERIT,
+ CSS_FONT_SMALLER);
+ add_word_args (" pre.smallexample { %s }\n", CSS_FONT_SMALLER);
+ add_word_args (" pre.smalllisp { %s }\n", CSS_FONT_SMALLER);
+
+ /* Since HTML doesn't have a sc element, we use span with a bit of
+ CSS spice instead. */
+#define CSS_FONT_SMALL_CAPS "font-variant:small-caps"
+ add_word_args (" span.sc { %s }\n", CSS_FONT_SMALL_CAPS);
+ /* Roman (default) font class, closest we can come. */
+#define CSS_FONT_ROMAN "font-family:serif; font-weight:normal;"
+ add_word_args (" span.roman { %s } \n", CSS_FONT_ROMAN);
+ /* Sans serif font class. */
+#define CSS_FONT_SANSSERIF "font-family:sans-serif; font-weight:normal;"
+ add_word_args (" span.sansserif { %s } \n", CSS_FONT_SANSSERIF);
+
+ /* Write out any css code from the user's --css-file. */
+ if (css_inline)
+ insert_string (css_inline);
+
+ add_word ("--></style>\n");
+ }
+
+ add_word ("</head>\n<body>\n");
+
+ if (title && !html_title_written && titlepage_cmd_present)
+ {
+ add_word_args ("<h1 class=\"settitle\">%s</h1>\n", html_title);
+ html_title_written = 1;
+ }
+
+ free (encoding);
+}
/* Escape HTML special characters in the string if necessary,
returning a pointer to a possibly newly-allocated one. */
char *
-escape_string (string)
- char * string;
+escape_string (char *string)
{
- int i=0, newlen=0;
- char * newstring;
+ char *newstring;
+ int i = 0, newlen = 0;
do
{
/* Find how much to allocate. */
switch (string[i])
{
+ case '"':
+ newlen += 6; /* `&quot;' */
+ break;
case '&':
newlen += 5; /* `&amp;' */
break;
@@ -315,6 +373,10 @@ escape_string (string)
{
switch (string[i])
{
+ case '"':
+ strcpy (newstring, "&quot;");
+ newstring += 6;
+ break;
case '&':
strcpy (newstring, "&amp;");
newstring += 5;
@@ -336,24 +398,22 @@ escape_string (string)
free (string);
return newstring - newlen;
}
-
-
/* Save current tag. */
-void
-push_tag (tag)
- char *tag;
+static void
+push_tag (char *tag, char *attribs)
{
HSTACK *newstack = xmalloc (sizeof (HSTACK));
newstack->tag = tag;
+ newstack->attribs = xstrdup (attribs);
newstack->next = htmlstack;
htmlstack = newstack;
}
/* Get last tag. */
-void
-pop_tag ()
+static void
+pop_tag (void)
{
HSTACK *tos = htmlstack;
@@ -363,77 +423,162 @@ pop_tag ()
return;
}
+ free (htmlstack->attribs);
+
htmlstack = htmlstack->next;
free (tos);
}
+/* Check if tag is an empty or a whitespace only element.
+ If so, remove it, keeping whitespace intact. */
+int
+rollback_empty_tag (char *tag)
+{
+ int check_position = output_paragraph_offset;
+ int taglen = strlen (tag);
+ int rollback_happened = 0;
+ char *contents = "";
+ char *contents_canon_white = "";
+
+ /* If output_paragraph is empty, we cannot rollback :-\ */
+ if (output_paragraph_offset <= 0)
+ return 0;
+
+ /* Find the end of the previous tag. */
+ while (output_paragraph[check_position-1] != '>' && check_position > 0)
+ check_position--;
+
+ /* Save stuff between tag's end to output_paragraph's end. */
+ if (check_position != output_paragraph_offset)
+ {
+ contents = xmalloc (output_paragraph_offset - check_position + 1);
+ memcpy (contents, output_paragraph + check_position,
+ output_paragraph_offset - check_position);
+
+ contents[output_paragraph_offset - check_position] = '\0';
+
+ contents_canon_white = xstrdup (contents);
+ canon_white (contents_canon_white);
+ }
+
+ /* Find the start of the previous tag. */
+ while (output_paragraph[check_position-1] != '<' && check_position > 0)
+ check_position--;
+
+ /* Check to see if this is the tag. */
+ if (strncmp ((char *) output_paragraph + check_position, tag, taglen) == 0
+ && (whitespace (output_paragraph[check_position + taglen])
+ || output_paragraph[check_position + taglen] == '>'))
+ {
+ if (!contents_canon_white || !*contents_canon_white)
+ {
+ /* Empty content after whitespace removal, so roll it back. */
+ output_paragraph_offset = check_position - 1;
+ rollback_happened = 1;
+
+ /* Original contents may not be empty (whitespace.) */
+ if (contents && *contents)
+ {
+ insert_string (contents);
+ free (contents);
+ }
+ }
+ }
+
+ return rollback_happened;
+}
+
/* Open or close TAG according to START_OR_END. */
void
-insert_html_tag (start_or_end, tag)
+#if defined (VA_FPRINTF) && __STDC__
+insert_html_tag_with_attribute (int start_or_end, char *tag, char *format, ...)
+#else
+insert_html_tag_with_attribute (start_or_end, tag, format, va_alist)
int start_or_end;
char *tag;
+ char *format;
+ va_dcl
+#endif
{
char *old_tag = NULL;
+ char *old_attribs = NULL;
+ char formatted_attribs[2000]; /* xx no fixed limits */
int do_return = 0;
-
- if (!paragraph_is_open && (start_or_end == START))
- {
- /* Need to compensate for the <p> we are about to insert, or
- else cm_xxx functions that call us will get wrong text
- between START and END. */
- adjust_braces_following (output_paragraph_offset, 3);
- add_word ("<p>");
- }
+ extern int in_html_elt;
if (start_or_end != START)
pop_tag ();
if (htmlstack)
- old_tag = htmlstack->tag;
+ {
+ old_tag = htmlstack->tag;
+ old_attribs = htmlstack->attribs;
+ }
+
+ if (format)
+ {
+#ifdef VA_SPRINTF
+ va_list ap;
+#endif
+
+ VA_START (ap, format);
+#ifdef VA_SPRINTF
+ VA_SPRINTF (formatted_attribs, format, ap);
+#else
+ sprintf (formatted_attribs, format, a1, a2, a3, a4, a5, a6, a7, a8);
+#endif
+ va_end (ap);
+ }
+ else
+ formatted_attribs[0] = '\0';
+ /* Exception: can nest multiple spans. */
if (htmlstack
- && (strcmp (htmlstack->tag, tag) == 0))
+ && STREQ (htmlstack->tag, tag)
+ && !(STREQ (tag, "span") && STREQ (old_attribs, formatted_attribs)))
do_return = 1;
if (start_or_end == START)
- push_tag (tag);
+ push_tag (tag, formatted_attribs);
if (do_return)
return;
+ in_html_elt++;
+
/* texinfo.tex doesn't support more than one font attribute
at the same time. */
- if ((start_or_end == START) && old_tag && *old_tag)
- {
- add_word ("</");
- add_word (old_tag);
- add_char ('>');
- }
+ if ((start_or_end == START) && old_tag && *old_tag
+ && !rollback_empty_tag (old_tag))
+ add_word_args ("</%s>", old_tag);
if (*tag)
{
- add_char ('<');
- if (start_or_end != START)
- add_char ('/');
- add_word (tag);
- add_char ('>');
+ if (start_or_end == START)
+ add_word_args (format ? "<%s %s>" : "<%s>", tag, formatted_attribs);
+ else if (!rollback_empty_tag (tag))
+ /* Insert close tag only if we didn't rollback,
+ in which case the opening tag is removed. */
+ add_word_args ("</%s>", tag);
}
if ((start_or_end != START) && old_tag && *old_tag)
- {
- add_char ('<');
- add_word (old_tag);
- add_char ('>');
- }
-}
+ add_word_args (strlen (old_attribs) > 0 ? "<%s %s>" : "<%s>",
+ old_tag, old_attribs);
+ in_html_elt--;
+}
+void
+insert_html_tag (int start_or_end, char *tag)
+{
+ insert_html_tag_with_attribute (start_or_end, tag, NULL);
+}
/* Output an HTML <link> to the filename for NODE, including the
other string as extra attributes. */
void
-add_link (nodename, attributes)
- char *nodename, *attributes;
+add_link (char *nodename, char *attributes)
{
if (nodename)
{
@@ -441,39 +586,64 @@ add_link (nodename, attributes)
add_word_args ("%s", attributes);
add_word_args (" href=\"");
add_anchor_name (nodename, 1);
- add_word ("\">\n");
+ add_word_args ("\" title=\"%s\">\n", nodename);
}
}
/* Output NAME with characters escaped as appropriate for an anchor
- name, i.e., escape URL special characters as %<n>. */
+ name, i.e., escape URL special characters with our _00hh convention
+ if OLD is zero. (See the manual for details on the new scheme.)
+
+ If OLD is nonzero, generate the node name with the 4.6-and-earlier
+ convention of %hh (and more special characters output as-is, notably
+ - and *). This is only so that external references to old names can
+ still work with HTML generated by the new makeinfo; the gcc folks
+ needed this. Our own HTML does not refer to these names. */
+
void
-add_escaped_anchor_name (name)
- char *name;
+add_escaped_anchor_name (char *name, int old)
{
+ canon_white (name);
+
+ if (!old && !strchr ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
+ *name))
+ { /* XHTML does not allow anything but an ASCII letter to start an
+ identifier. Therefore kludge in this constant string if we
+ have a nonletter. */
+ add_word ("g_t");
+ }
+
for (; *name; name++)
{
- if (*name == '&')
- add_word ("&amp;");
- else if (! URL_SAFE_CHAR (*name))
+ if (cr_or_whitespace (*name))
+ add_char ('-');
+
+ else if (!old && !URL_SAFE_CHAR (*name))
/* Cast so characters with the high bit set are treated as >128,
for example o-umlaut should be 246, not -10. */
+ add_word_args ("_00%x", (unsigned char) *name);
+
+ else if (old && !URL_SAFE_CHAR (*name) && !OLD_URL_SAFE_CHAR (*name))
+ /* Different output convention, but still cast as above. */
add_word_args ("%%%x", (unsigned char) *name);
+
else
add_char (*name);
}
}
/* Insert the text for the name of a reference in an HTML anchor
- appropriate for NODENAME. If HREF is nonzero, it will be
- appropriate for a href= attribute, rather than name= i.e., including
- the `#' if it's an internal reference. */
+ appropriate for NODENAME.
+
+ If HREF is zero, generate text for name= in the new node name
+ conversion convention.
+ If HREF is negative, generate text for name= in the old convention.
+ If HREF is positive, generate the name for an href= attribute, i.e.,
+ including the `#' if it's an internal reference. */
void
-add_anchor_name (nodename, href)
- char *nodename;
- int href;
+add_anchor_name (char *nodename, int href)
{
- if (href)
+ if (href > 0)
{
if (splitting)
add_url_name (nodename, href);
@@ -486,38 +656,52 @@ add_anchor_name (nodename, href)
if (strcasecmp (nodename, "(dir)") == 0)
/* Strip the parens, but keep the original letter-case. */
add_word_args ("%.3s", nodename + 1);
+ else if (strcasecmp (nodename, "top") == 0)
+ add_word ("Top");
else
- add_escaped_anchor_name (nodename);
+ add_escaped_anchor_name (nodename, href < 0);
}
/* Insert the text for the name of a reference in an HTML url, aprropriate
for NODENAME */
void
-add_url_name (nodename, href)
- char *nodename;
- int href;
+add_url_name (char *nodename, int href)
{
add_nodename_to_filename (nodename, href);
}
-/* Only allow [-0-9a-zA-Z_.] when nodifying filenames. This may
- result in filename clashes; e.g.,
+/* Convert non [A-Za-z0-9] to _00xx, where xx means the hexadecimal
+ representation of the ASCII character. Also convert spaces and
+ newlines to dashes. */
+static void
+fix_filename (char *filename)
+{
+ int i;
+ int len = strlen (filename);
+ char *oldname = xstrdup (filename);
- @node Foo ],,,
- @node Foo [,,,
+ *filename = '\0';
- both map to Foo--.html. If that happens, cm_node will put all
- the nodes whose file names clash on the same file. */
-void
-fix_filename (filename)
- char *filename;
-{
- char *p;
- for (p = filename; *p; p++)
+ for (i = 0; i < len; i++)
{
- if (!(isalnum (*p) || strchr ("-._", *p)))
- *p = '-';
+ if (cr_or_whitespace (oldname[i]))
+ strcat (filename, "-");
+ else if (URL_SAFE_CHAR (oldname[i]))
+ strncat (filename, (char *) oldname + i, 1);
+ else
+ {
+ char *hexchar = xmalloc (6 * sizeof (char));
+ sprintf (hexchar, "_00%x", (unsigned char) oldname[i]);
+ strcat (filename, hexchar);
+ free (hexchar);
+ }
+
+ /* Check if we are nearing boundaries. */
+ if (strlen (filename) >= PATH_MAX - 20)
+ break;
}
+
+ free (oldname);
}
/* As we can't look-up a (forward-referenced) nodes' html filename
@@ -525,9 +709,7 @@ fix_filename (filename)
nodenames are unique, and generate the html filename from the
nodename, that's always known. */
static char *
-nodename_to_filename_1 (nodename, href)
- char *nodename;
- int href;
+nodename_to_filename_1 (char *nodename, int href)
{
char *p;
char *filename;
@@ -623,9 +805,7 @@ nodename_to_filename_1 (nodename, href)
/* If necessary, ie, if current filename != filename of node, output
the node name. */
void
-add_nodename_to_filename (nodename, href)
- char *nodename;
- int href;
+add_nodename_to_filename (char *nodename, int href)
{
/* for now, don't check: always output filename */
char *filename = nodename_to_filename_1 (nodename, href);
@@ -634,8 +814,7 @@ add_nodename_to_filename (nodename, href)
}
char *
-nodename_to_filename (nodename)
- char *nodename;
+nodename_to_filename (char *nodename)
{
/* The callers of nodename_to_filename use the result to produce
<a href=, so call nodename_to_filename_1 with last arg non-zero. */
diff --git a/contrib/texinfo/makeinfo/html.h b/contrib/texinfo/makeinfo/html.h
index 84960db..d2b5411 100644
--- a/contrib/texinfo/makeinfo/html.h
+++ b/contrib/texinfo/makeinfo/html.h
@@ -1,7 +1,7 @@
/* html.h -- declarations for html-related utilities.
- $Id: html.h,v 1.4 2002/10/31 22:08:23 karl Exp $
+ $Id: html.h,v 1.6 2004/11/30 02:03:23 karl Exp $
- Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -25,6 +25,7 @@ typedef struct hstack
{
struct hstack *next;
char *tag;
+ char *attribs;
} HSTACK;
/* Nonzero if we have output the <head>. */
@@ -34,24 +35,31 @@ extern int html_output_head_p;
extern int html_title_written;
/* Perform the <head> output. */
-extern void html_output_head ();
+extern void html_output_head (void);
/* Escape &<>. */
-extern char *escape_string (/* char * */);
+extern char *escape_string (char *);
/* Open or close TAG according to START_OR_END. */
-extern void insert_html_tag (/* int start_or_end, char *tag */);
+extern void insert_html_tag (int start_or_end, char *tag);
/* Output HTML <link> to NODE, plus extra ATTRIBUTES. */
-extern void add_link (/* char *node, char *attributes */);
+extern void add_link (char *nodename, char *attributes);
-/* Escape URL-special characters as %xy. */
-extern void add_escaped_anchor_name (/* char *name */);
+/* Escape URL-special characters. */
+extern void add_escaped_anchor_name (char *name, int old);
/* See html.c. */
-extern void add_anchor_name (/* nodename, href */);
-extern void add_url_name ( /* nodename, href */ );
-extern char* nodename_to_filename ( /* nodename */ );
-extern void add_nodename_to_filename ( /*nodename, href */ );
+extern void add_anchor_name (char *nodename, int href);
+extern void add_url_name (char *nodename, int href);
+extern void add_nodename_to_filename (char *nodename, int href);
+extern char *nodename_to_filename (char *nodename);
+extern int rollback_empty_tag (char *tag);
+
+#if defined (VA_FPRINTF) && __STDC__
+extern void insert_html_tag_with_attribute (int start_or_end, char *tag, char *format, ...);
+#else
+extern void insert_html_tag_with_attribute ();
+#endif
#endif /* !HTML_H */
diff --git a/contrib/texinfo/makeinfo/index.c b/contrib/texinfo/makeinfo/index.c
index ab6a53c..710e8b6 100644
--- a/contrib/texinfo/makeinfo/index.c
+++ b/contrib/texinfo/makeinfo/index.c
@@ -1,7 +1,8 @@
/* index.c -- indexing for Texinfo.
- $Id: index.c,v 1.8 2003/05/16 23:52:40 karl Exp $
+ $Id: index.c,v 1.17 2004/11/30 02:03:23 karl Exp $
- Copyright (C) 1998, 1999, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2002, 2003, 2004 Free Software Foundation,
+ Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,59 +19,16 @@
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "system.h"
+#include "files.h"
+#include "footnote.h"
+#include "html.h"
#include "index.h"
#include "lang.h"
#include "macro.h"
+#include "sectioning.h"
#include "toc.h"
#include "xml.h"
-/* An index element... */
-typedef struct index_elt
-{
- struct index_elt *next;
- char *entry; /* The index entry itself, after expansion. */
- char *entry_text; /* The original, non-expanded entry text. */
- char *node; /* The node from whence it came. */
- int code; /* Nonzero means add `@code{...}' when
- printing this element. */
- int defining_line; /* Line number where this entry was written. */
- char *defining_file; /* Source file for defining_line. */
-} INDEX_ELT;
-
-
-/* A list of short-names for each index.
- There are two indices into the the_indices array.
- * read_index is the index that points to the list of index
- entries that we will find if we ask for the list of entries for
- this name.
- * write_index is the index that points to the list of index entries
- that we will add new entries to.
-
- Initially, read_index and write_index are the same, but the
- @syncodeindex and @synindex commands can change the list we add
- entries to.
-
- For example, after the commands
- @cindex foo
- @defindex ii
- @synindex cp ii
- @cindex bar
-
- the cp index will contain the entry `foo', and the new ii
- index will contain the entry `bar'. This is consistent with the
- way texinfo.tex handles the same situation.
-
- In addition, for each index, it is remembered whether that index is
- a code index or not. Code indices have @code{} inserted around the
- first word when they are printed with printindex. */
-typedef struct
-{
- char *name;
- int read_index; /* index entries for `name' */
- int write_index; /* store index entries here, @synindex can change it */
- int code;
-} INDEX_ALIST;
-
INDEX_ALIST **name_index_alist = NULL;
/* An array of pointers. Each one is for a different index. The
@@ -81,18 +39,24 @@ INDEX_ELT **the_indices = NULL;
/* The number of defined indices. */
int defined_indices = 0;
+/* This is the order of the index. */
+int index_counter = 0;
+
/* Stuff for defining commands on the fly. */
COMMAND **user_command_array = NULL;
int user_command_array_len = 0;
/* How to compare index entries for sorting. May be set to strcoll. */
-int (*index_compare_fn) () = strcasecmp;
+int (*index_compare_fn) (const char *a, const char *b) = strcasecmp;
+
+/* Function to compare index entries for sorting. (Calls
+ `index_compare_fn' above.) */
+int index_element_compare (const void *element1, const void *element2);
/* Find which element in the known list of indices has this name.
Returns -1 if NAME isn't found. */
static int
-find_index_offset (name)
- char *name;
+find_index_offset (char *name)
{
int i;
for (i = 0; i < defined_indices; i++)
@@ -103,9 +67,8 @@ find_index_offset (name)
/* Return a pointer to the entry of (name . index) for this name.
Return NULL if the index doesn't exist. */
-INDEX_ALIST *
-find_index (name)
- char *name;
+static INDEX_ALIST *
+find_index (char *name)
{
int offset = find_index_offset (name);
if (offset > -1)
@@ -116,11 +79,8 @@ find_index (name)
/* User-defined commands, which happens only from user-defined indexes.
Used to initialize the builtin indices, too. */
-void
-define_user_command (name, proc, needs_braces_p)
- char *name;
- COMMAND_FUNCTION *proc;
- int needs_braces_p;
+static void
+define_user_command (char *name, COMMAND_FUNCTION (*proc), int needs_braces_p)
{
int slot = user_command_array_len;
user_command_array_len++;
@@ -139,8 +99,7 @@ define_user_command (name, proc, needs_braces_p)
/* Please release me, let me go... */
static void
-free_index (index)
- INDEX_ELT *index;
+free_index (INDEX_ELT *index)
{
INDEX_ELT *temp;
@@ -159,8 +118,7 @@ free_index (index)
/* Flush an index by name. This will delete the list of entries that
would be written by a @printindex command for this index. */
static void
-undefindex (name)
- char *name;
+undefindex (char *name)
{
int i;
int which = find_index_offset (name);
@@ -180,11 +138,9 @@ undefindex (name)
name_index_alist[which] = NULL;
}
-/* Add the arguments to the current index command to the index NAME.
- html fixxme generate specific html anchor */
+/* Add the arguments to the current index command to the index NAME. */
static void
-index_add_arg (name)
- char *name;
+index_add_arg (char *name)
{
int which;
char *index_entry;
@@ -216,17 +172,57 @@ index_add_arg (name)
else
{
INDEX_ELT *new = xmalloc (sizeof (INDEX_ELT));
+
+ index_counter++;
+
+ /* Get output line number updated before doing anything. */
+ if (!html && !xml)
+ flush_output ();
+
new->next = the_indices[which];
- new->entry_text = index_entry;
new->entry = NULL;
- new->node = current_node ? current_node : xstrdup ("");
+ new->entry_text = index_entry;
+ /* Since footnotes are handled at the very end of the document,
+ node name in the non-split HTML outputs always show the last
+ node. We artificially make it ``Footnotes''. */
+ if (html && !splitting && already_outputting_pending_notes)
+ new->node = xstrdup (_("Footnotes"));
+ else
+ new->node = current_node ? current_node : xstrdup ("");
+ if (!html && !xml && no_headers)
+ {
+ new->section = current_sectioning_number ();
+ if (strlen (new->section) == 0)
+ new->section_name = current_sectioning_name ();
+ else
+ new->section_name = "";
+ }
+ else
+ {
+ new->section = NULL;
+ new->section_name = NULL;
+ }
new->code = tem->code;
new->defining_line = line_number - 1;
+ new->output_line = no_headers ? output_line_number : node_line_number;
/* We need to make a copy since input_filename may point to
something that goes away, for example, inside a macro.
(see the findexerr test). */
new->defining_file = xstrdup (input_filename);
+
+ if (html && splitting)
+ {
+ if (current_output_filename && *current_output_filename)
+ new->output_file = filename_part (current_output_filename);
+ else
+ new->output_file = xstrdup ("");
+ }
+ else
+ new->output_file = NULL;
+
+ new->entry_number = index_counter;
the_indices[which] = new;
+
#if 0
/* The index breaks if there are colons in the entry.
-- This is true, but it's too painful to force changing index
@@ -238,14 +234,36 @@ index_add_arg (name)
warning (_("Info cannot handle `:' in index entry `%s'"),
new->entry_text);
#endif
+
+ if (html)
+ {
+ /* Anchor. */
+ int removed_empty_elt = 0;
+
+ /* We must put the anchor outside the <dl> and <ul> blocks. */
+ if (rollback_empty_tag ("dl"))
+ removed_empty_elt = 1;
+ else if (rollback_empty_tag ("ul"))
+ removed_empty_elt = 2;
+
+ add_word ("<a name=\"index-");
+ add_escaped_anchor_name (index_entry, 0);
+ add_word_args ("-%d\"></a>", index_counter);
+
+ if (removed_empty_elt == 1)
+ add_html_block_elt_args ("\n<dl>");
+ else if (removed_empty_elt == 2)
+ add_html_block_elt_args ("\n<ul>");
+ }
}
+
if (xml)
xml_insert_indexterm (index_entry, name);
}
/* The function which user defined index commands call. */
static void
-gen_index ()
+gen_index (void)
{
char *name = xstrdup (command);
if (strlen (name) >= strlen ("index"))
@@ -257,9 +275,7 @@ gen_index ()
/* Define an index known as NAME. We assign the slot number.
If CODE is nonzero, make this a code index. */
static void
-defindex (name, code)
- char *name;
- int code;
+defindex (char *name, int code)
{
int i, slot;
@@ -299,9 +315,7 @@ defindex (name, code)
/* Define an index NAME, implicitly @code if CODE is nonzero. */
static void
-top_defindex (name, code)
- char *name;
- int code;
+top_defindex (char *name, int code)
{
char *temp;
@@ -314,7 +328,7 @@ top_defindex (name, code)
/* Set up predefined indices. */
void
-init_indices ()
+init_indices (void)
{
int i;
@@ -364,9 +378,8 @@ init_indices ()
/* Given an index name, return the offset in the_indices of this index,
or -1 if there is no such index. */
-int
-translate_index (name)
- char *name;
+static int
+translate_index (char *name)
{
INDEX_ALIST *which = find_index (name);
@@ -378,8 +391,7 @@ translate_index (name)
/* Return the index list which belongs to NAME. */
INDEX_ELT *
-index_list (name)
- char *name;
+index_list (char *name)
{
int which = translate_index (name);
if (which < 0)
@@ -390,8 +402,7 @@ index_list (name)
/* Define a new index command. Arg is name of index. */
static void
-gen_defindex (code)
- int code;
+gen_defindex (int code)
{
char *name;
get_rest_of_line (0, &name);
@@ -413,13 +424,13 @@ gen_defindex (code)
}
void
-cm_defindex ()
+cm_defindex (void)
{
gen_defindex (0);
}
void
-cm_defcodeindex ()
+cm_defcodeindex (void)
{
gen_defindex (1);
}
@@ -428,7 +439,7 @@ cm_defcodeindex ()
Make the first one be a synonym for the second one, i.e. make the
first one have the same index as the second one. */
void
-cm_synindex ()
+cm_synindex (void)
{
int source, target;
char *abbrev1, *abbrev2;
@@ -446,8 +457,11 @@ cm_synindex ()
}
else
{
- name_index_alist[target]->write_index
- = name_index_alist[source]->write_index;
+ if (xml && !docbook)
+ xml_synindex (abbrev1, abbrev2);
+ else
+ name_index_alist[target]->write_index
+ = name_index_alist[source]->write_index;
}
free (abbrev1);
@@ -455,53 +469,53 @@ cm_synindex ()
}
void
-cm_pindex () /* Pinhead index. */
+cm_pindex (void) /* Pinhead index. */
{
index_add_arg ("pg");
}
void
-cm_vindex () /* Variable index. */
+cm_vindex (void) /* Variable index. */
{
index_add_arg ("vr");
}
void
-cm_kindex () /* Key index. */
+cm_kindex (void) /* Key index. */
{
index_add_arg ("ky");
}
void
-cm_cindex () /* Concept index. */
+cm_cindex (void) /* Concept index. */
{
index_add_arg ("cp");
}
void
-cm_findex () /* Function index. */
+cm_findex (void) /* Function index. */
{
index_add_arg ("fn");
}
void
-cm_tindex () /* Data Type index. */
+cm_tindex (void) /* Data Type index. */
{
index_add_arg ("tp");
}
int
-index_element_compare (element1, element2)
- INDEX_ELT **element1, **element2;
+index_element_compare (const void *element1, const void *element2)
{
- return index_compare_fn ((*element1)->entry, (*element2)->entry);
+ INDEX_ELT **elt1 = (INDEX_ELT **) element1;
+ INDEX_ELT **elt2 = (INDEX_ELT **) element2;
+
+ return index_compare_fn ((*elt1)->entry, (*elt2)->entry);
}
/* Force all index entries to be unique. */
-void
-make_index_entries_unique (array, count)
- INDEX_ELT **array;
- int count;
+static void
+make_index_entries_unique (INDEX_ELT **array, int count)
{
int i, j;
INDEX_ELT **copy;
@@ -560,9 +574,8 @@ make_index_entries_unique (array, count)
/* Sort the index passed in INDEX, returning an array of pointers to
elements. The array is terminated with a NULL pointer. */
-INDEX_ELT **
-sort_index (index)
- INDEX_ELT *index;
+static INDEX_ELT **
+sort_index (INDEX_ELT *index)
{
INDEX_ELT **array;
INDEX_ELT *temp;
@@ -641,38 +654,95 @@ sort_index (index)
return array;
}
+static void
+insert_index_output_line_no (int line_number, int output_line_number_len)
+{
+ int last_column;
+ int str_size = output_line_number_len + strlen (_("(line )"))
+ + sizeof (NULL);
+ char *out_line_no_str = (char *) xmalloc (str_size + 1);
+
+ /* Do not translate ``(line NNN)'' below for !no_headers case (Info output),
+ because it's something like the ``* Menu'' strings. For plaintext output
+ it should be translated though. */
+ sprintf (out_line_no_str,
+ no_headers ? _("(line %*d)") : "(line %*d)",
+ output_line_number_len, line_number);
+
+ {
+ int i = output_paragraph_offset;
+ while (0 < i && output_paragraph[i-1] != '\n')
+ i--;
+ last_column = output_paragraph_offset - i;
+ }
+
+ if (last_column + strlen (out_line_no_str) > fill_column)
+ {
+ insert ('\n');
+ last_column = 0;
+ }
+
+ while (last_column + strlen (out_line_no_str) < fill_column)
+ {
+ insert (' ');
+ last_column++;
+ }
+
+ insert_string (out_line_no_str);
+ insert ('\n');
+
+ free (out_line_no_str);
+}
+
/* Nonzero means that we are in the middle of printing an index. */
int printing_index = 0;
/* Takes one arg, a short name of an index to print.
Outputs a menu of the sorted elements of the index. */
void
-cm_printindex ()
+cm_printindex (void)
{
+ char *index_name;
+ get_rest_of_line (0, &index_name);
+
+ /* get_rest_of_line increments the line number by one,
+ so to make warnings/errors point to the correct line,
+ we decrement the line_number again. */
+ if (!handling_delayed_writes)
+ line_number--;
+
if (xml && !docbook)
{
- char *index_name;
- get_rest_of_line (0, &index_name);
xml_insert_element (PRINTINDEX, START);
insert_string (index_name);
xml_insert_element (PRINTINDEX, END);
}
+ else if (!handling_delayed_writes)
+ {
+ int command_len = sizeof ("@ ") + strlen (command) + strlen (index_name);
+ char *index_command = xmalloc (command_len + 1);
+
+ close_paragraph ();
+ if (docbook)
+ xml_begin_index ();
+
+ sprintf (index_command, "@%s %s", command, index_name);
+ register_delayed_write (index_command);
+ free (index_command);
+ }
else
{
int item;
INDEX_ELT *index;
INDEX_ELT *last_index = 0;
INDEX_ELT **array;
- char *index_name;
unsigned line_length;
char *line;
int saved_inhibit_paragraph_indentation = inhibit_paragraph_indentation;
int saved_filling_enabled = filling_enabled;
int saved_line_number = line_number;
char *saved_input_filename = input_filename;
-
- close_paragraph ();
- get_rest_of_line (0, &index_name);
+ unsigned output_line_number_len;
index = index_list (index_name);
if (index == (INDEX_ELT *)-1)
@@ -696,9 +766,17 @@ cm_printindex ()
xml_sort_index = 0;
close_paragraph ();
if (html)
- add_word_args ("<ul class=\"index-%s\" compact>", index_name);
+ add_html_block_elt_args ("<ul class=\"index-%s\" compact>",
+ index_name);
else if (!no_headers && !docbook)
- add_word ("* Menu:\n\n");
+ { /* Info. Add magic cookie for info readers (to treat this
+ menu differently), and the usual start-of-menu. */
+ add_char ('\0');
+ add_word ("\010[index");
+ add_char ('\0');
+ add_word ("\010]\n");
+ add_word ("* Menu:\n\n");
+ }
me_inhibit_expansion++;
@@ -706,11 +784,29 @@ cm_printindex ()
line_length = 100;
line = xmalloc (line_length);
+ {
+ char *max_output_line_number = (char *) xmalloc (25 * sizeof (char));
+
+ if (no_headers)
+ sprintf (max_output_line_number, "%d", output_line_number);
+ else
+ {
+ INDEX_ELT *tmp_entry = index;
+ unsigned tmp = 0;
+ for (tmp_entry = index; tmp_entry; tmp_entry = tmp_entry->next)
+ tmp = tmp_entry->output_line > tmp ? tmp_entry->output_line : tmp;
+ sprintf (max_output_line_number, "%d", tmp);
+ }
+
+ output_line_number_len = strlen (max_output_line_number);
+ free (max_output_line_number);
+ }
+
for (item = 0; (index = array[item]); item++)
{
/* A pathological document might have an index entry outside of any
node. Don't crash; try using the section name instead. */
- const char *index_node = index->node;
+ char *index_node = index->node;
line_number = index->defining_line;
input_filename = index->defining_file;
@@ -723,44 +819,39 @@ cm_printindex ()
line_error (_("Entry for index `%s' outside of any node"),
index_name);
if (html || !no_headers)
- index_node = _("(outside of any node)");
+ index_node = (char *) _("(outside of any node)");
}
if (html)
- /* fixme: html: we should use specific index anchors pointing
- to the actual location of the indexed position (but then we
- have to find something to wrap the anchor around). */
{
- if (last_index
- && STREQ (last_index->entry_text, index->entry_text))
- add_word (", "); /* Don't repeat the previous entry. */
- else
- {
- /* In the HTML case, the expanded index entry is not
- good for us, since it was expanded for non-HTML mode
- inside sort_index. So we need to HTML-escape and
- expand the original entry text here. */
- char *escaped_entry = xstrdup (index->entry_text);
- char *expanded_entry;
-
- /* expansion() doesn't HTML-escape the argument, so need
- to do it separately. */
- escaped_entry = escape_string (escaped_entry);
- expanded_entry = expansion (escaped_entry, index->code);
- add_word_args ("\n<li>%s: ", expanded_entry);
- free (escaped_entry);
- free (expanded_entry);
- }
+ /* For HTML, we need to expand and HTML-escape the
+ original entry text, at the same time. Consider
+ @cindex J@"urgen. We want J&uuml;urgen. We can't
+ expand and then escape since we'll end up with
+ J&amp;uuml;rgen. We can't escape and then expand
+ because then `expansion' will see J@&quot;urgen, and
+ @&quot;urgen is not a command. */
+ char *html_entry =
+ maybe_escaped_expansion (index->entry_text, index->code, 1);
+
+ add_html_block_elt_args ("\n<li><a href=\"%s#index-",
+ (splitting && index->output_file) ? index->output_file : "");
+ add_escaped_anchor_name (index->entry_text, 0);
+ add_word_args ("-%d\">%s</a>: ", index->entry_number,
+ html_entry);
+ free (html_entry);
+
add_word ("<a href=\"");
if (index->node && *index->node)
{
- /* Make sure any non-macros in the node name are expanded. */
+ /* Ensure any non-macros in the node name are expanded. */
char *expanded_index;
in_fixed_width_font++;
expanded_index = expansion (index_node, 0);
in_fixed_width_font--;
add_anchor_name (expanded_index, 1);
+ expanded_index = escape_string (expanded_index);
add_word_args ("\">%s</a>", expanded_index);
free (expanded_index);
}
@@ -773,6 +864,8 @@ cm_printindex ()
/* If we use the section instead of the (missing) node, then
index_node already includes all we need except the #. */
add_word_args ("#%s</a>", index_node);
+
+ add_html_block_elt ("</li>");
}
else if (xml && docbook)
{
@@ -806,7 +899,9 @@ cm_printindex ()
insert_string (line);
/* Make sure any non-macros in the node name are expanded. */
in_fixed_width_font++;
- execute_string ("%s.\n", index_node);
+ execute_string ("%s. ", index_node);
+ insert_index_output_line_no (index->output_line,
+ output_line_number_len);
in_fixed_width_font--;
}
else
@@ -815,40 +910,27 @@ cm_printindex ()
there's little sense in referring to them in the
index. Instead, output the number or name of the
section that corresponds to that node. */
- char *section_name = toc_find_section_of_node (index_node);
-
- sprintf (line, "%-*s ", number_sections ? 50 : 1, index->entry);
+ sprintf (line, "%-*s ", number_sections ? 46 : 1, index->entry);
line[strlen (index->entry)] = ':';
insert_string (line);
- if (section_name)
- {
- int idx = 0;
- unsigned ref_len = strlen (section_name) + 30;
-
- if (ref_len > line_length)
- {
- line_length = ref_len;
- line = xrealloc (line, line_length);
- }
-
- if (number_sections)
- {
- while (section_name[idx]
- && (isdigit (section_name[idx])
- || (idx && section_name[idx] == '.')))
- idx++;
- }
- if (idx)
- sprintf (line, " See %.*s.\n", idx, section_name);
- else
- sprintf (line, "\n See ``%s''.\n", section_name);
- insert_string (line);
+
+ if (strlen (index->section) > 0)
+ { /* We got your number. */
+ insert_string ((char *) _("See "));
+ insert_string (index->section);
}
else
- {
- insert_string (" "); /* force a blank */
- execute_string ("See node %s.\n", index_node);
+ { /* Sigh, index in an @unnumbered. :-\ */
+ insert_string ("\n ");
+ insert_string ((char *) _("See "));
+ insert_string ("``");
+ insert_string (expansion (index->section_name, 0));
+ insert_string ("''");
}
+
+ insert_string (". ");
+ insert_index_output_line_no (index->output_line,
+ output_line_number_len);
}
}
@@ -859,7 +941,6 @@ cm_printindex ()
}
free (line);
- free (index_name);
me_inhibit_expansion--;
printing_index = 0;
@@ -871,8 +952,13 @@ cm_printindex ()
line_number = saved_line_number;
if (html)
- add_word ("</ul>");
+ add_html_block_elt ("</ul>");
else if (xml && docbook)
xml_end_index ();
}
+
+ free (index_name);
+ /* Re-increment the line number, because get_rest_of_line
+ left us looking at the next line after the command. */
+ line_number++;
}
diff --git a/contrib/texinfo/makeinfo/index.h b/contrib/texinfo/makeinfo/index.h
index 3279a24..3ff723d 100644
--- a/contrib/texinfo/makeinfo/index.h
+++ b/contrib/texinfo/makeinfo/index.h
@@ -1,5 +1,5 @@
/* index.h -- declarations for index.c.
- $Id: index.h,v 1.1 2002/08/25 23:38:38 karl Exp $
+ $Id: index.h,v 1.2 2004/04/11 17:56:47 karl Exp $
Copyright (C) 1998, 99 Free Software Foundation, Inc.
@@ -27,10 +27,67 @@
extern COMMAND **user_command_array;
extern int user_command_array_len;
+/* An index element... */
+typedef struct index_elt
+{
+ struct index_elt *next;
+ char *entry; /* The index entry itself, after expansion. */
+ char *entry_text; /* The original, non-expanded entry text. */
+ char *node; /* The node from whence it came. */
+ char *section; /* Current section number we are in, */
+ char *section_name; /* ... and its title. */
+ int code; /* Nonzero means add `@code{...}' when
+ printing this element. */
+ int defining_line; /* Line number where this entry was written. */
+ int output_line; /* And line number where it is in the output. */
+ char *defining_file; /* Source file for defining_line. */
+ char *output_file; /* Output file for output_line. */
+ int entry_number; /* Entry number. */
+} INDEX_ELT;
+
+
+/* A list of short-names for each index.
+ There are two indices into the the_indices array.
+ * read_index is the index that points to the list of index
+ entries that we will find if we ask for the list of entries for
+ this name.
+ * write_index is the index that points to the list of index entries
+ that we will add new entries to.
+
+ Initially, read_index and write_index are the same, but the
+ @syncodeindex and @synindex commands can change the list we add
+ entries to.
+
+ For example, after the commands
+ @cindex foo
+ @defindex ii
+ @synindex cp ii
+ @cindex bar
+
+ the cp index will contain the entry `foo', and the new ii
+ index will contain the entry `bar'. This is consistent with the
+ way texinfo.tex handles the same situation.
+
+ In addition, for each index, it is remembered whether that index is
+ a code index or not. Code indices have @code{} inserted around the
+ first word when they are printed with printindex. */
+typedef struct
+{
+ char *name;
+ int read_index; /* index entries for `name' */
+ int write_index; /* store index entries here, @synindex can change it */
+ int code;
+} INDEX_ALIST;
+
+extern INDEX_ALIST **name_index_alist;
+
/* Initialize all indices. */
-extern void init_indices ();
+extern void init_indices (void);
+
+extern int defined_indices;
+extern int printing_index;
+extern int index_counter;
-/* Function to compare index entries for sorting. */
-extern int (*index_compare_fn) ();
+INDEX_ELT *index_list (char *name);
#endif /* !INDEX_H */
diff --git a/contrib/texinfo/makeinfo/insertion.c b/contrib/texinfo/makeinfo/insertion.c
index 95c0be2..05a2044 100644
--- a/contrib/texinfo/makeinfo/insertion.c
+++ b/contrib/texinfo/makeinfo/insertion.c
@@ -1,7 +1,7 @@
/* insertion.c -- insertions for Texinfo.
- $Id: insertion.c,v 1.21 2003/04/01 14:34:18 karl Exp $
+ $Id: insertion.c,v 1.55 2004/11/11 18:34:28 karl Exp $
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
Foundation, Inc.
This program is free software; you can redistribute it and/or modify
@@ -21,25 +21,29 @@
#include "system.h"
#include "cmds.h"
#include "defun.h"
+#include "float.h"
+#include "html.h"
#include "insertion.h"
#include "macro.h"
#include "makeinfo.h"
+#include "multi.h"
#include "xml.h"
/* Must match list in insertion.h. */
static char *insertion_type_names[] =
{
"cartouche", "copying", "defcv", "deffn", "defivar", "defmac",
- "defmethod", "defop", "defopt", "defspec", "deftp", "deftypefn",
- "deftypefun", "deftypeivar", "deftypemethod", "deftypeop",
- "deftypevar", "deftypevr", "defun", "defvar", "defvr", "detailmenu",
- "direntry", "display", "documentdescription", "enumerate", "example",
- "flushleft", "flushright", "format", "ftable", "group", "ifclear",
- "ifhtml", "ifinfo", "ifnothtml", "ifnotinfo", "ifnotplaintext", "ifnottex", "ifnotxml",
- "ifplaintext", "ifset", "iftex", "ifxml", "itemize", "lisp", "menu",
- "multitable", "quotation", "rawhtml", "rawtex", "smalldisplay",
- "smallexample", "smallformat", "smalllisp", "verbatim", "table",
- "tex", "vtable", "bad_type"
+ "defmethod", "defop", "defopt", "defspec", "deftp", "deftypecv",
+ "deftypefn", "deftypefun", "deftypeivar", "deftypemethod",
+ "deftypeop", "deftypevar", "deftypevr", "defun", "defvar", "defvr",
+ "detailmenu", "direntry", "display", "documentdescription",
+ "enumerate", "example", "float", "flushleft", "flushright", "format",
+ "ftable", "group", "ifclear", "ifdocbook", "ifhtml", "ifinfo",
+ "ifnotdocbook", "ifnothtml", "ifnotinfo", "ifnotplaintext", "ifnottex",
+ "ifnotxml", "ifplaintext", "ifset", "iftex", "ifxml", "itemize", "lisp",
+ "menu", "multitable", "quotation", "rawdocbook", "rawhtml", "rawtex",
+ "rawxml", "smalldisplay", "smallexample", "smallformat", "smalllisp",
+ "verbatim", "table", "tex", "vtable", "titlepage", "bad_type"
};
/* All nested environments. */
@@ -62,19 +66,29 @@ int in_menu = 0;
Used for menu and itemize. */
int in_paragraph = 0;
-static const char dl_tag[] = "<dl>\n";
-extern void cm_insert_copying ();
+/* Since an insertion is already in the stack before we reach the switch
+ statement, we cannot use is_in_insertion_of_type (always returns true.) Also
+ making it return the level found, and comparing it with the current level is
+ no use, due to the order of stack. */
+static int float_active = 0;
+/* Unsetting escape_html blindly causes text inside @html/etc. to be escaped if
+ used within a rmacro. */
+static int raw_output_block = 0;
+
+/* Non-zero if a <dl> element has a <dt> element in it. We use this when
+ deciding whether to insert a <br> or not. */
+static int html_deflist_has_term = 0;
void
-init_insertion_stack ()
+init_insertion_stack (void)
{
insertion_stack = NULL;
}
/* Return the type of the current insertion. */
static enum insertion_type
-current_insertion_type ()
+current_insertion_type (void)
{
return insertion_level ? insertion_stack->insertion : bad_type;
}
@@ -82,7 +96,7 @@ current_insertion_type ()
/* Return the string which is the function to wrap around items, or NULL
if we're not in an environment where @item is ok. */
static char *
-current_item_function ()
+current_item_function (void)
{
int done = 0;
INSERTION_ELT *elt = insertion_stack;
@@ -106,7 +120,9 @@ current_item_function ()
case ifset:
case iftex:
case ifxml:
+ case rawdocbook:
case rawhtml:
+ case rawxml:
case rawtex:
case tex:
case cartouche:
@@ -126,8 +142,8 @@ current_item_function ()
change it to "@ ", since "@" by itself is not a command. This makes
"@ ", "@\t", and "@\n" all the same, but their default meanings are
the same anyway, and let's not worry about supporting redefining them. */
-char *
-get_item_function ()
+static char *
+get_item_function (void)
{
char *item_function;
char *item_loc;
@@ -161,10 +177,8 @@ get_item_function ()
}
/* Push the state of the current insertion on the stack. */
-void
-push_insertion (type, item_function)
- enum insertion_type type;
- char *item_function;
+static void
+push_insertion (enum insertion_type type, char *item_function)
{
INSERTION_ELT *new = xmalloc (sizeof (INSERTION_ELT));
@@ -184,7 +198,7 @@ push_insertion (type, item_function)
/* Pop the value on top of the insertion stack into the
global variables. */
void
-pop_insertion ()
+pop_insertion (void)
{
INSERTION_ELT *temp = insertion_stack;
@@ -204,12 +218,22 @@ pop_insertion ()
/* Return a pointer to the print name of this
enumerated type. */
-const char *
-insertion_type_pname (type)
- enum insertion_type type;
+static const char *
+insertion_type_pname (enum insertion_type type)
{
if ((int) type < (int) bad_type)
- return insertion_type_names[(int) type];
+ {
+ if (type == rawdocbook)
+ return "docbook";
+ else if (type == rawhtml)
+ return "html";
+ else if (type == rawxml)
+ return "xml";
+ else if (type == rawtex)
+ return "tex";
+ else
+ return insertion_type_names[(int) type];
+ }
else
return _("Broken-Type in insertion_type_pname");
}
@@ -217,18 +241,19 @@ insertion_type_pname (type)
/* Return the insertion_type associated with NAME.
If the type is not one of the known ones, return BAD_TYPE. */
enum insertion_type
-find_type_from_name (name)
- char *name;
+find_type_from_name (char *name)
{
int index = 0;
while (index < (int) bad_type)
{
if (STREQ (name, insertion_type_names[index]))
return (enum insertion_type) index;
+ if (index == rawdocbook && STREQ (name, "docbook"))
+ return rawdocbook;
if (index == rawhtml && STREQ (name, "html"))
return rawhtml;
- if (index == rawhtml && STREQ (name, "xml"))
- return rawhtml;
+ if (index == rawxml && STREQ (name, "xml"))
+ return rawxml;
if (index == rawtex && STREQ (name, "tex"))
return rawtex;
index++;
@@ -236,9 +261,29 @@ find_type_from_name (name)
return bad_type;
}
+/* Simple function to query insertion_stack to see if we are inside a given
+ insertion type. */
int
-defun_insertion (type)
- enum insertion_type type;
+is_in_insertion_of_type (int type)
+{
+ INSERTION_ELT *temp = insertion_stack;
+
+ if (!insertion_level)
+ return 0;
+
+ while (temp)
+ {
+ if (temp->insertion == type)
+ return 1;
+ temp = temp->next;
+ }
+
+ return 0;
+}
+
+
+static int
+defun_insertion (enum insertion_type type)
{
return 0
|| (type == defcv)
@@ -250,6 +295,7 @@ defun_insertion (type)
|| (type == defopt)
|| (type == defspec)
|| (type == deftp)
+ || (type == deftypecv)
|| (type == deftypefn)
|| (type == deftypefun)
|| (type == deftypeivar)
@@ -280,9 +326,8 @@ int current_enumval = 1;
int current_enumtype = ENUM_DIGITS;
char *enumeration_arg = NULL;
-void
-start_enumerating (at, type)
- int at, type;
+static void
+start_enumerating (int at, int type)
{
if ((enumstack_offset + 1) == max_stack_depth)
{
@@ -296,8 +341,8 @@ start_enumerating (at, type)
current_enumtype = type;
}
-void
-stop_enumerating ()
+static void
+stop_enumerating (void)
{
--enumstack_offset;
if (enumstack_offset < 0)
@@ -308,8 +353,8 @@ stop_enumerating ()
}
/* Place a letter or digits into the output stream. */
-void
-enumerate_item ()
+static void
+enumerate_item (void)
{
char temp[10];
@@ -331,7 +376,7 @@ enumerate_item ()
}
static void
-enum_html ()
+enum_html (void)
{
char type;
int start;
@@ -352,12 +397,12 @@ enum_html ()
start = *enumeration_arg - 'a' + 1;
}
- add_word_args ("<ol type=%c start=%d>\n", type, start);
+ add_html_block_elt_args ("<ol type=%c start=%d>\n", type, start);
}
/* Conditionally parse based on the current command name. */
void
-command_name_condition ()
+command_name_condition (void)
{
char *discarder = xmalloc (8 + strlen (command));
@@ -372,8 +417,7 @@ command_name_condition ()
commands is done. A huge switch statement handles the
various setups, and generic code is on both sides. */
void
-begin_insertion (type)
- enum insertion_type type;
+begin_insertion (enum insertion_type type)
{
int no_discard = 0;
@@ -405,10 +449,11 @@ begin_insertion (type)
if (xml)
xml_insert_element (MENU, START);
+ else
+ in_fixed_width_font++;
next_menu_item_number = 1;
in_menu++;
- in_fixed_width_font++;
no_discard++;
break;
@@ -424,7 +469,14 @@ begin_insertion (type)
no_discard++;
}
- in_fixed_width_font++;
+ if (xml)
+ {
+ xml_insert_element (DETAILMENU, START);
+ skip_whitespace_and_newlines();
+ }
+ else
+ in_fixed_width_font++;
+
in_detailmenu++;
break;
@@ -455,32 +507,15 @@ begin_insertion (type)
break;
case copying:
- {
/* Save the copying text away for @insertcopying,
typically used on the back of the @titlepage (for TeX) and
the Top node (for info/html). */
- char *text;
- int start_of_end;
- int save_paragraph_indentation;
-
+ if (input_text[input_text_offset] != '\n')
discard_until ("\n"); /* ignore remainder of @copying line */
- start_of_end = get_until ("\n@end copying", &text);
-
- /* include all the output-format-specific markup. */
- if (docbook)
- {
- save_paragraph_indentation = inhibit_paragraph_indentation;
- inhibit_paragraph_indentation = 1;
- }
- copying_text = full_expansion (text, 0);
- free (text);
-
- if (docbook)
- inhibit_paragraph_indentation = save_paragraph_indentation;
-
- input_text_offset = start_of_end; /* go back to the @end to match */
- }
-
+
+ input_text_offset = get_until ("\n@end copying", &copying_text);
+ canon_white (copying_text);
+
/* For info, output the copying text right away, so it will end up
in the header of the Info file, before the first node, and thus
get copied automatically to all the split files. For xml, also
@@ -495,25 +530,21 @@ begin_insertion (type)
xml_insert_element (BOOKINFO, START);
xml_in_bookinfo = 1;
}
- if (!xml_in_abstract)
- {
- xml_insert_element (ABSTRACT, START);
- xml_in_abstract = 1;
- }
+ xml_insert_element (LEGALNOTICE, START);
}
+
if (!html && !no_headers)
cm_insert_copying ();
- if (docbook && xml_in_abstract)
- {
- xml_insert_element (ABSTRACT, END);
- xml_in_abstract = 0;
- }
+
+ if (docbook)
+ xml_insert_element (LEGALNOTICE, END);
+
break;
-
+
case quotation:
/* @quotation does filling (@display doesn't). */
if (html)
- add_word ("<blockquote>\n");
+ add_html_block_elt ("<blockquote>\n");
else
{
/* with close_single_paragraph, we get no blank line above
@@ -524,32 +555,39 @@ begin_insertion (type)
inhibit_paragraph_indentation = 1;
}
current_indent += default_indentation_increment;
+ if (xml)
+ xml_insert_quotation (insertion_stack->item_function, START);
+ else if (strlen(insertion_stack->item_function))
+ execute_string ("@b{%s:} ", insertion_stack->item_function);
break;
- case display:
- case smalldisplay:
case example:
case smallexample:
case lisp:
case smalllisp:
+ in_fixed_width_font++;
+ /* fall through */
+
+ /* Like @example but no fixed width font. */
+ case display:
+ case smalldisplay:
/* Like @display but without indentation. */
case smallformat:
case format:
close_single_paragraph ();
inhibit_paragraph_indentation = 1;
- in_fixed_width_font++;
filling_enabled = 0;
last_char_was_newline = 0;
if (html)
- /* Kludge alert: if <pre> is followed by a newline, IE3
- renders an extra blank line before the pre-formatted block.
- Other browsers seem to not mind one way or the other. */
- add_word_args ("<pre class=\"%s\">", command);
+ /* Kludge alert: if <pre> is followed by a newline, IE3,
+ mozilla, maybe others render an extra blank line before the
+ pre-formatted block. So don't output a newline. */
+ add_html_block_elt_args ("<pre class=\"%s\">", command);
if (type != format && type != smallformat)
{
- current_indent += default_indentation_increment;
+ current_indent += example_indentation_increment;
if (html)
{
/* Since we didn't put \n after <pre>, we need to insert
@@ -559,7 +597,6 @@ begin_insertion (type)
add_char (' ');
}
}
-
break;
case multitable:
@@ -599,14 +636,26 @@ begin_insertion (type)
{
if (type == itemize)
{
- add_word ("<ul>\n");
+ add_html_block_elt ("<ul>\n");
in_paragraph = 0;
}
else
- add_word (dl_tag);
+ { /* We are just starting, so this <dl>
+ has no <dt> children yet. */
+ html_deflist_has_term = 0;
+ add_html_block_elt ("<dl>\n");
+ }
}
if (xml)
xml_begin_table (type, insertion_stack->item_function);
+
+ while (input_text[input_text_offset] == '\n'
+ && input_text[input_text_offset+1] == '\n')
+ {
+ line_number++;
+ input_text_offset++;
+ }
+
break;
case enumerate:
@@ -636,7 +685,7 @@ begin_insertion (type)
start_enumerating (*enumeration_arg, ENUM_ALPHA);
break;
- /* @group does nothing special in makeinfo. */
+ /* @group produces no output in info. */
case group:
/* Only close the paragraph if we are not inside of an
@example-like environment. */
@@ -658,15 +707,157 @@ begin_insertion (type)
case cartouche:
if (html)
- add_word ("<table class=\"cartouche\" border=1><tr><td>\n");
+ add_html_block_elt ("<p><table class=\"cartouche\" summary=\"cartouche\" border=\"1\"><tr><td>\n");
if (in_menu)
no_discard++;
break;
+ case floatenv:
+ /* Cannot nest floats, so complain. */
+ if (float_active)
+ {
+ line_error (_("%cfloat environments cannot be nested"), COMMAND_PREFIX);
+ pop_insertion ();
+ break;
+ }
+
+ float_active++;
+
+ { /* Collect data about this float. */
+ /* Example: @float [FLOATTYPE][,XREFLABEL][,POSITION] */
+ char floattype[200] = "";
+ char xreflabel[200] = "";
+ char position[200] = "";
+ char *text;
+ char *caption;
+ char *shortcaption;
+ int start_of_end;
+ int save_line_number = line_number;
+ int save_input_text_offset = input_text_offset;
+ int i;
+
+ if (strlen (insertion_stack->item_function) > 0)
+ {
+ int i = 0, t = 0, c = 0;
+ while (insertion_stack->item_function[i])
+ {
+ if (insertion_stack->item_function[i] == ',')
+ {
+ switch (t)
+ {
+ case 0:
+ floattype[c] = '\0';
+ break;
+ case 1:
+ xreflabel[c] = '\0';
+ break;
+ case 2:
+ position[c] = '\0';
+ break;
+ }
+ c = 0;
+ t++;
+ i++;
+ continue;
+ }
+
+ switch (t)
+ {
+ case 0:
+ floattype[c] = insertion_stack->item_function[i];
+ break;
+ case 1:
+ xreflabel[c] = insertion_stack->item_function[i];
+ break;
+ case 2:
+ position[c] = insertion_stack->item_function[i];
+ break;
+ }
+ c++;
+ i++;
+ }
+ }
+
+ skip_whitespace_and_newlines ();
+
+ start_of_end = get_until ("\n@end float", &text);
+
+ /* Get also the @caption. */
+ i = search_forward_until_pos ("\n@caption{",
+ save_input_text_offset, start_of_end);
+ if (i > -1)
+ {
+ input_text_offset = i + sizeof ("\n@caption{") - 1;
+ get_until_in_braces ("\n@end float", &caption);
+ input_text_offset = save_input_text_offset;
+ }
+ else
+ caption = "";
+
+ /* ... and the @shortcaption. */
+ i = search_forward_until_pos ("\n@shortcaption{",
+ save_input_text_offset, start_of_end);
+ if (i > -1)
+ {
+ input_text_offset = i + sizeof ("\n@shortcaption{") - 1;
+ get_until_in_braces ("\n@end float", &shortcaption);
+ input_text_offset = save_input_text_offset;
+ }
+ else
+ shortcaption = "";
+
+ canon_white (xreflabel);
+ canon_white (floattype);
+ canon_white (position);
+ canon_white (caption);
+ canon_white (shortcaption);
+
+ add_new_float (xstrdup (xreflabel),
+ xstrdup (caption), xstrdup (shortcaption),
+ xstrdup (floattype), xstrdup (position));
+
+ /* Move to the start of the @float so the contents get processed as
+ usual. */
+ input_text_offset = save_input_text_offset;
+ line_number = save_line_number;
+ }
+
+ if (html)
+ add_html_block_elt ("<div class=\"float\">\n");
+ else if (docbook)
+ xml_insert_element (FLOAT, START);
+ else if (xml)
+ {
+ xml_insert_element_with_attribute (FLOAT, START,
+ "name=\"%s\"", current_float_id ());
+
+ xml_insert_element (FLOATTYPE, START);
+ execute_string ("%s", current_float_type ());
+ xml_insert_element (FLOATTYPE, END);
+
+ xml_insert_element (FLOATPOS, START);
+ execute_string ("%s", current_float_position ());
+ xml_insert_element (FLOATPOS, END);
+ }
+ else
+ { /* Info */
+ close_single_paragraph ();
+ inhibit_paragraph_indentation = 1;
+ }
+
+ /* Anchor now. Note that XML documents get their
+ anchors with <float name="anchor"> tag. */
+ if ((!xml || docbook) && strlen (current_float_id ()) > 0)
+ execute_string ("@anchor{%s}", current_float_id ());
+
+ break;
+
/* Insertions that are no-ops in info, but do something in TeX. */
case ifclear:
+ case ifdocbook:
case ifhtml:
case ifinfo:
+ case ifnotdocbook:
case ifnothtml:
case ifnotinfo:
case ifnotplaintext:
@@ -681,8 +872,25 @@ begin_insertion (type)
no_discard++;
break;
+ case rawdocbook:
case rawhtml:
- escape_html = 0;
+ case rawxml:
+ raw_output_block++;
+
+ if (raw_output_block > 0)
+ {
+ xml_no_para = 1;
+ escape_html = 0;
+ xml_keep_space++;
+ }
+
+ {
+ /* Some deuglification for improved readability. */
+ extern int xml_in_para;
+ if (xml && !xml_in_para && xml_indentation_increment > 0)
+ add_char ('\n');
+ }
+
break;
case defcv:
@@ -694,6 +902,7 @@ begin_insertion (type)
case defopt:
case defspec:
case deftp:
+ case deftypecv:
case deftypefn:
case deftypefun:
case deftypeivar:
@@ -708,6 +917,8 @@ begin_insertion (type)
filling_enabled = indented_fill = 1;
current_indent += default_indentation_increment;
no_indent = 0;
+ if (xml)
+ xml_begin_definition ();
break;
case flushleft:
@@ -715,7 +926,7 @@ begin_insertion (type)
inhibit_paragraph_indentation = 1;
filling_enabled = indented_fill = no_indent = 0;
if (html)
- add_word ("<div align=\"left\">");
+ add_html_block_elt ("<div align=\"left\">");
break;
case flushright:
@@ -724,12 +935,15 @@ begin_insertion (type)
inhibit_paragraph_indentation = 1;
force_flush_right++;
if (html)
- add_word ("<div align=\"right\">");
+ add_html_block_elt ("<div align=\"right\">");
+ break;
+
+ case titlepage:
+ xml_insert_element (TITLEPAGE, START);
break;
default:
line_error ("begin_insertion internal error: type=%d", type);
-
}
if (!no_discard)
@@ -740,11 +954,10 @@ begin_insertion (type)
`bad_type', TYPE gets translated to match the value currently on top
of the stack. Otherwise, if TYPE doesn't match the top of the
insertion stack, give error. */
-void
-end_insertion (type)
- enum insertion_type type;
+static void
+end_insertion (int type)
{
- enum insertion_type temp_type;
+ int temp_type;
if (!insertion_level)
return;
@@ -771,23 +984,28 @@ end_insertion (type)
case ifinfo:
case documentdescription:
break;
- case copying:
- xml_insert_element (COPYING, END);
- break;
case quotation:
- xml_insert_element (QUOTATION, END);
+ xml_insert_quotation ("", END);
break;
case example:
xml_insert_element (EXAMPLE, END);
+ if (docbook && current_insertion_type () == floatenv)
+ xml_insert_element (FLOATEXAMPLE, END);
break;
case smallexample:
xml_insert_element (SMALLEXAMPLE, END);
+ if (docbook && current_insertion_type () == floatenv)
+ xml_insert_element (FLOATEXAMPLE, END);
break;
case lisp:
xml_insert_element (LISP, END);
+ if (docbook && current_insertion_type () == floatenv)
+ xml_insert_element (FLOATEXAMPLE, END);
break;
case smalllisp:
xml_insert_element (SMALLLISP, END);
+ if (docbook && current_insertion_type () == floatenv)
+ xml_insert_element (FLOATEXAMPLE, END);
break;
case cartouche:
xml_insert_element (CARTOUCHE, END);
@@ -817,21 +1035,28 @@ end_insertion (type)
xml_end_table (type);
break;
case enumerate:
- xml_end_enumerate (type);
+ xml_end_enumerate ();
break;
case group:
xml_insert_element (GROUP, END);
break;
+ case titlepage:
+ xml_insert_element (TITLEPAGE, END);
+ break;
}
}
switch (type)
{
/* Insertions which have no effect on paragraph formatting. */
case copying:
- case documentdescription:
+ line_number--;
+ break;
+
case ifclear:
+ case ifdocbook:
case ifinfo:
case ifhtml:
+ case ifnotdocbook:
case ifnothtml:
case ifnotinfo:
case ifnotplaintext:
@@ -842,13 +1067,29 @@ end_insertion (type)
case iftex:
case ifxml:
case rawtex:
+ case titlepage:
break;
+ case rawdocbook:
case rawhtml:
- escape_html = 1;
+ case rawxml:
+ raw_output_block--;
+
+ if (raw_output_block <= 0)
+ {
+ xml_no_para = 0;
+ escape_html = 1;
+ xml_keep_space--;
+ }
+
+ if ((xml || html) && output_paragraph[output_paragraph_offset-1] == '\n')
+ output_paragraph_offset--;
break;
case detailmenu:
+ if (xml)
+ xml_insert_element (DETAILMENU, END);
+
in_detailmenu--; /* No longer hacking menus. */
if (!in_menu)
{
@@ -862,11 +1103,17 @@ end_insertion (type)
close_insertion_paragraph ();
break;
+ case documentdescription:
+ if (xml)
+ insert_string (document_description);
+ xml_insert_element (DOCUMENTDESCRIPTION, END);
+ break;
+
case menu:
in_menu--; /* No longer hacking menus. */
if (html && !no_headers)
- add_word ("</ul>\n");
- else if (!no_headers)
+ add_html_block_elt ("</ul>\n");
+ else if (!no_headers && !xml)
close_insertion_paragraph ();
break;
@@ -879,23 +1126,76 @@ end_insertion (type)
close_insertion_paragraph ();
current_indent -= default_indentation_increment;
if (html)
- add_word ("</ol>\n");
+ add_html_block_elt ("</ol>\n");
break;
case flushleft:
if (html)
- add_word ("</div>\n");
+ add_html_block_elt ("</div>\n");
close_insertion_paragraph ();
break;
case cartouche:
if (html)
- add_word ("</td></tr></table>\n");
+ add_html_block_elt ("</td></tr></table>\n");
close_insertion_paragraph ();
break;
case group:
- close_insertion_paragraph ();
+ if (!xml || docbook)
+ close_insertion_paragraph ();
+ break;
+
+ case floatenv:
+ if (xml)
+ xml_insert_element (FLOAT, END);
+ else
+ {
+ if (html)
+ add_html_block_elt ("<p><strong class=\"float-caption\">");
+ else
+ close_paragraph ();
+
+ no_indent = 1;
+
+ /* Legend:
+ 1) @float Foo,lbl & no caption: Foo 1.1
+ 2) @float Foo & no caption: Foo
+ 3) @float ,lbl & no caption: 1.1
+ 4) @float & no caption: */
+
+ if (!xml && !html)
+ indent (current_indent);
+
+ if (strlen (current_float_type ()))
+ execute_string ("%s", current_float_type ());
+
+ if (strlen (current_float_id ()) > 0)
+ {
+ if (strlen (current_float_type ()) > 0)
+ add_char (' ');
+
+ add_word (current_float_number ());
+ }
+
+ if (strlen (current_float_title ()) > 0)
+ {
+ if (strlen (current_float_type ()) > 0
+ || strlen (current_float_id ()) > 0)
+ insert_string (": ");
+
+ execute_string ("%s", current_float_title ());
+ }
+
+ /* Indent the following paragraph. */
+ inhibit_paragraph_indentation = 0;
+
+ if (html)
+ add_word ("</strong></p></div>\n");
+ else
+ close_paragraph ();
+ }
+ float_active--;
break;
case format:
@@ -909,15 +1209,30 @@ end_insertion (type)
case quotation:
/* @format and @smallformat are the only fixed_width insertion
without a change in indentation. */
- if (type != format && type != smallformat)
+ if (type != format && type != smallformat && type != quotation)
+ current_indent -= example_indentation_increment;
+ else if (type == quotation)
current_indent -= default_indentation_increment;
if (html)
- add_word (type == quotation ? "</blockquote>\n" : "</pre>\n");
+ { /* The complex code in close_paragraph that kills whitespace
+ does not function here, since we've inserted non-whitespace
+ (the </whatever>) before it. The indentation already got
+ inserted at the end of the last example line, so we have to
+ delete it, or browsers wind up showing an extra blank line. */
+ kill_self_indent (default_indentation_increment);
+ add_html_block_elt (type == quotation
+ ? "</blockquote>\n" : "</pre>\n");
+ }
/* The ending of one of these insertions always marks the
- start of a new paragraph. */
- close_insertion_paragraph ();
+ start of a new paragraph, except for the XML output. */
+ if (!xml || docbook)
+ close_insertion_paragraph ();
+
+ /* </pre> closes paragraph without messing with </p>. */
+ if (html && type != quotation)
+ paragraph_is_open = 0;
break;
case table:
@@ -925,28 +1240,28 @@ end_insertion (type)
case vtable:
current_indent -= default_indentation_increment;
if (html)
- add_word ("</dl>\n");
+ add_html_block_elt ("</dl>\n");
close_insertion_paragraph ();
break;
case itemize:
current_indent -= default_indentation_increment;
if (html)
- add_word ("</ul>\n");
+ add_html_block_elt ("</ul>\n");
close_insertion_paragraph ();
break;
case flushright:
force_flush_right--;
if (html)
- add_word ("</div>\n");
+ add_html_block_elt ("</div>\n");
close_insertion_paragraph ();
break;
/* Handle the @defun insertions with this default clause. */
default:
{
- enum insertion_type base_type;
+ int base_type;
if (type < defcv || type > defvr)
line_error ("end_insertion internal error: type=%d", type);
@@ -957,6 +1272,7 @@ end_insertion (type)
case deffn:
case defvr:
case deftp:
+ case deftypecv:
case deftypefn:
case deftypevr:
case defcv:
@@ -965,8 +1281,16 @@ end_insertion (type)
case deftypeop:
case deftypeivar:
if (html)
- /* close the tables which has been opened in defun.c */
- add_word ("</td></tr>\n</table>\n");
+ {
+ if (paragraph_is_open)
+ add_html_block_elt ("</p>");
+ /* close the div and blockquote which has been opened in defun.c */
+ if (!rollback_empty_tag ("blockquote"))
+ add_html_block_elt ("</blockquote>");
+ add_html_block_elt ("</div>\n");
+ }
+ if (xml)
+ xml_end_definition ();
break;
} /* switch (base_type)... */
@@ -991,8 +1315,7 @@ end_insertion (type)
@if... conditionals, otherwise not. This is because conditionals can
cross node boundaries. Always happens with the @top node, for example. */
void
-discard_insertions (specials_ok)
- int specials_ok;
+discard_insertions (int specials_ok)
{
int real_line_number = line_number;
while (insertion_stack)
@@ -1000,7 +1323,9 @@ discard_insertions (specials_ok)
if (specials_ok
&& ((ifclear <= insertion_stack->insertion
&& insertion_stack->insertion <= iftex)
+ || insertion_stack->insertion == rawdocbook
|| insertion_stack->insertion == rawhtml
+ || insertion_stack->insertion == rawxml
|| insertion_stack->insertion == rawtex))
break;
else
@@ -1020,71 +1345,125 @@ discard_insertions (specials_ok)
/* Insertion (environment) commands. */
void
-cm_quotation ()
+cm_quotation (void)
{
- if (xml)
- xml_insert_element (QUOTATION, START);
+ /* We start the blockquote element in the insertion. */
begin_insertion (quotation);
}
void
-cm_example ()
+cm_example (void)
{
+ if (docbook && current_insertion_type () == floatenv)
+ xml_begin_docbook_float (FLOATEXAMPLE);
+
if (xml)
- xml_insert_element (EXAMPLE, START);
+ {
+ /* Rollback previous newlines. These occur between
+ </para> and <example>. */
+ if (output_paragraph[output_paragraph_offset-1] == '\n')
+ output_paragraph_offset--;
+
+ xml_insert_element (EXAMPLE, START);
+
+ /* Make sure example text is starting on a new line
+ for improved readability. */
+ if (docbook)
+ add_char ('\n');
+ }
+
begin_insertion (example);
}
void
-cm_smallexample ()
+cm_smallexample (void)
{
+ if (docbook && current_insertion_type () == floatenv)
+ xml_begin_docbook_float (FLOATEXAMPLE);
+
if (xml)
- xml_insert_element (SMALLEXAMPLE, START);
+ {
+ /* See cm_example comments about newlines. */
+ if (output_paragraph[output_paragraph_offset-1] == '\n')
+ output_paragraph_offset--;
+ xml_insert_element (SMALLEXAMPLE, START);
+ if (docbook)
+ add_char ('\n');
+ }
+
begin_insertion (smallexample);
}
void
-cm_lisp ()
+cm_lisp (void)
{
+ if (docbook && current_insertion_type () == floatenv)
+ xml_begin_docbook_float (FLOATEXAMPLE);
+
if (xml)
- xml_insert_element (LISP, START);
+ {
+ /* See cm_example comments about newlines. */
+ if (output_paragraph[output_paragraph_offset-1] == '\n')
+ output_paragraph_offset--;
+ xml_insert_element (LISP, START);
+ if (docbook)
+ add_char ('\n');
+ }
+
begin_insertion (lisp);
}
void
-cm_smalllisp ()
+cm_smalllisp (void)
{
+ if (docbook && current_insertion_type () == floatenv)
+ xml_begin_docbook_float (FLOATEXAMPLE);
+
if (xml)
- xml_insert_element (SMALLLISP, START);
+ {
+ /* See cm_example comments about newlines. */
+ if (output_paragraph[output_paragraph_offset-1] == '\n')
+ output_paragraph_offset--;
+ xml_insert_element (SMALLLISP, START);
+ if (docbook)
+ add_char ('\n');
+ }
+
begin_insertion (smalllisp);
}
void
-cm_cartouche ()
+cm_cartouche (void)
{
+ if (docbook && current_insertion_type () == floatenv)
+ xml_begin_docbook_float (CARTOUCHE);
+
if (xml)
xml_insert_element (CARTOUCHE, START);
begin_insertion (cartouche);
}
void
-cm_copying ()
+cm_copying (void)
{
- if (xml)
- xml_insert_element (COPYING, START);
begin_insertion (copying);
}
/* Not an insertion, despite the name, but it goes with cm_copying. */
void
-cm_insert_copying ()
+cm_insert_copying (void)
{
- if (copying_text)
- { /* insert_string rather than add_word because we've already done
- full expansion on copying_text when we saved it. */
- insert_string (copying_text);
- insert ('\n');
-
+ if (!copying_text)
+ {
+ warning ("@copying not used before %s", command);
+ return;
+ }
+
+ execute_string ("%s", copying_text);
+
+ if (!xml && !html)
+ {
+ add_word ("\n\n");
/* Update output_position so that the node positions in the tag
tables will take account of the copying text. */
flush_output ();
@@ -1092,7 +1471,7 @@ cm_insert_copying ()
}
void
-cm_format ()
+cm_format (void)
{
if (xml)
{
@@ -1102,56 +1481,94 @@ cm_format ()
xml_in_abstract = 1;
}
else
- xml_insert_element (FORMAT, START);
+ {
+ /* See cm_example comments about newlines. */
+ if (output_paragraph[output_paragraph_offset-1] == '\n')
+ output_paragraph_offset--;
+ xml_insert_element (FORMAT, START);
+ if (docbook)
+ add_char ('\n');
+ }
}
begin_insertion (format);
}
void
-cm_smallformat ()
+cm_smallformat (void)
{
if (xml)
- xml_insert_element (SMALLFORMAT, START);
+ {
+ /* See cm_example comments about newlines. */
+ if (output_paragraph[output_paragraph_offset-1] == '\n')
+ output_paragraph_offset--;
+ xml_insert_element (SMALLFORMAT, START);
+ if (docbook)
+ add_char ('\n');
+ }
+
begin_insertion (smallformat);
}
void
-cm_display ()
+cm_display (void)
{
if (xml)
- xml_insert_element (DISPLAY, START);
+ {
+ /* See cm_example comments about newlines. */
+ if (output_paragraph[output_paragraph_offset-1] == '\n')
+ output_paragraph_offset--;
+ xml_insert_element (DISPLAY, START);
+ if (docbook)
+ add_char ('\n');
+ }
+
begin_insertion (display);
}
void
-cm_smalldisplay ()
+cm_smalldisplay (void)
{
if (xml)
- xml_insert_element (SMALLDISPLAY, START);
+ {
+ /* See cm_example comments about newlines. */
+ if (output_paragraph[output_paragraph_offset-1] == '\n')
+ output_paragraph_offset--;
+ xml_insert_element (SMALLDISPLAY, START);
+ if (docbook)
+ add_char ('\n');
+ }
+
begin_insertion (smalldisplay);
}
void
-cm_direntry ()
+cm_direntry (void)
{
- if (html || xml)
+ if (html || xml || no_headers)
command_name_condition ();
else
begin_insertion (direntry);
}
void
-cm_documentdescription ()
+cm_documentdescription (void)
{
- if (html || xml)
+ if (html)
begin_insertion (documentdescription);
+
+ else if (xml)
+ {
+ xml_insert_element (DOCUMENTDESCRIPTION, START);
+ begin_insertion (documentdescription);
+ }
+
else
command_name_condition ();
}
void
-cm_itemize ()
+cm_itemize (void)
{
begin_insertion (itemize);
}
@@ -1159,9 +1576,7 @@ cm_itemize ()
/* Start an enumeration insertion of type TYPE. If the user supplied
no argument on the line, then use DEFAULT_STRING as the initial string. */
static void
-do_enumeration (type, default_string)
- int type;
- char *default_string;
+do_enumeration (int type, char *default_string)
{
get_until_in_line (0, ".", &enumeration_arg);
canon_white (enumeration_arg);
@@ -1188,7 +1603,7 @@ do_enumeration (type, default_string)
}
void
-cm_enumerate ()
+cm_enumerate (void)
{
do_enumeration (enumerate, "1");
}
@@ -1202,15 +1617,16 @@ cm_enumerate ()
verbatim environment may be encapsulated in an @example environment,
for example. */
void
-handle_verbatim_environment (find_end_verbatim)
- int find_end_verbatim;
+handle_verbatim_environment (int find_end_verbatim)
{
int character;
int seen_end = 0;
int save_filling_enabled = filling_enabled;
int save_inhibit_paragraph_indentation = inhibit_paragraph_indentation;
+ int save_escape_html = escape_html;
- close_single_paragraph ();
+ if (!insertion_stack)
+ close_single_paragraph (); /* no blank lines if not at outer level */
inhibit_paragraph_indentation = 1;
filling_enabled = 0;
in_fixed_width_font++;
@@ -1222,7 +1638,22 @@ handle_verbatim_environment (find_end_verbatim)
*/
if (html)
- add_word ("<pre class=\"verbatim\">");
+ { /* If inside @example, we'll be preceded by the indentation
+ already. Browsers will ignore those spaces because we're about
+ to start another <pre> (don't ask me). So, wipe them out for
+ cleanliness, and re-insert. */
+ int i;
+ kill_self_indent (default_indentation_increment);
+ add_html_block_elt ("<pre class=\"verbatim\">");
+ for (i = current_indent; i > 0; i--)
+ add_char (' ');
+ }
+ else if (xml)
+ {
+ xml_insert_element (VERBATIM, START);
+ escape_html = 0;
+ add_word ("<![CDATA[");
+ }
while (input_text_offset < input_text_length)
{
@@ -1230,9 +1661,8 @@ handle_verbatim_environment (find_end_verbatim)
if (character == '\n')
line_number++;
- /*
- Assume no newlines in END_VERBATIM
- */
+
+ /* Assume no newlines in END_VERBATIM. */
else if (find_end_verbatim && (character == COMMAND_PREFIX) /* @ */
&& (input_text_length - input_text_offset > sizeof (END_VERBATIM))
&& !strncmp (&input_text[input_text_offset+1], END_VERBATIM,
@@ -1257,7 +1687,16 @@ handle_verbatim_environment (find_end_verbatim)
warning (_("end of file inside verbatim block"));
if (html)
- add_word ("</pre>");
+ { /* See comments in example case above. */
+ kill_self_indent (default_indentation_increment);
+ add_word ("</pre>");
+ }
+ else if (xml)
+ {
+ add_word ("]]>");
+ xml_insert_element (VERBATIM, END);
+ escape_html = save_escape_html;
+ }
in_fixed_width_font--;
filling_enabled = save_filling_enabled;
@@ -1265,53 +1704,89 @@ handle_verbatim_environment (find_end_verbatim)
}
void
-cm_verbatim ()
+cm_verbatim (void)
{
handle_verbatim_environment (1);
}
void
-cm_table ()
+cm_table (void)
{
begin_insertion (table);
}
void
-cm_multitable ()
+cm_multitable (void)
{
begin_insertion (multitable); /* @@ */
}
void
-cm_ftable ()
+cm_ftable (void)
{
begin_insertion (ftable);
}
void
-cm_vtable ()
+cm_vtable (void)
{
begin_insertion (vtable);
}
void
-cm_group ()
+cm_group (void)
{
begin_insertion (group);
}
/* Insert raw HTML (no escaping of `<' etc.). */
void
-cm_html ()
+cm_html (int arg)
{
- if (process_html || process_xml)
+ if (process_html)
begin_insertion (rawhtml);
else
command_name_condition ();
}
void
-cm_ifhtml ()
+cm_xml (int arg)
+{
+ if (process_xml)
+ begin_insertion (rawxml);
+ else
+ command_name_condition ();
+}
+
+void
+cm_docbook (int arg)
+{
+ if (process_docbook)
+ begin_insertion (rawdocbook);
+ else
+ command_name_condition ();
+}
+
+void
+cm_ifdocbook (void)
+{
+ if (process_docbook)
+ begin_insertion (ifdocbook);
+ else
+ command_name_condition ();
+}
+
+void
+cm_ifnotdocbook (void)
+{
+ if (!process_docbook)
+ begin_insertion (ifnotdocbook);
+ else
+ command_name_condition ();
+}
+
+void
+cm_ifhtml (void)
{
if (process_html)
begin_insertion (ifhtml);
@@ -1320,7 +1795,7 @@ cm_ifhtml ()
}
void
-cm_ifnothtml ()
+cm_ifnothtml (void)
{
if (!process_html)
begin_insertion (ifnothtml);
@@ -1330,7 +1805,7 @@ cm_ifnothtml ()
void
-cm_ifinfo ()
+cm_ifinfo (void)
{
if (process_info)
begin_insertion (ifinfo);
@@ -1339,7 +1814,7 @@ cm_ifinfo ()
}
void
-cm_ifnotinfo ()
+cm_ifnotinfo (void)
{
if (!process_info)
begin_insertion (ifnotinfo);
@@ -1349,7 +1824,7 @@ cm_ifnotinfo ()
void
-cm_ifplaintext ()
+cm_ifplaintext (void)
{
if (process_plaintext)
begin_insertion (ifplaintext);
@@ -1358,7 +1833,7 @@ cm_ifplaintext ()
}
void
-cm_ifnotplaintext ()
+cm_ifnotplaintext (void)
{
if (!process_plaintext)
begin_insertion (ifnotplaintext);
@@ -1368,7 +1843,7 @@ cm_ifnotplaintext ()
void
-cm_tex ()
+cm_tex (void)
{
if (process_tex)
begin_insertion (rawtex);
@@ -1377,7 +1852,7 @@ cm_tex ()
}
void
-cm_iftex ()
+cm_iftex (void)
{
if (process_tex)
begin_insertion (iftex);
@@ -1386,7 +1861,7 @@ cm_iftex ()
}
void
-cm_ifnottex ()
+cm_ifnottex (void)
{
if (!process_tex)
begin_insertion (ifnottex);
@@ -1395,7 +1870,7 @@ cm_ifnottex ()
}
void
-cm_ifxml ()
+cm_ifxml (void)
{
if (process_xml)
begin_insertion (ifxml);
@@ -1404,7 +1879,7 @@ cm_ifxml ()
}
void
-cm_ifnotxml ()
+cm_ifnotxml (void)
{
if (!process_xml)
begin_insertion (ifnotxml);
@@ -1413,9 +1888,47 @@ cm_ifnotxml ()
}
+/* Generic xrefable block with a caption. */
+void
+cm_float (void)
+{
+ begin_insertion (floatenv);
+}
+
+void
+cm_caption (int arg)
+{
+ char *temp;
+
+ /* This is a no_op command for most formats, as we handle it during @float
+ insertion. For XML though, we handle it here to keep document structure
+ as close as possible, to the Texinfo source. */
+
+ /* Everything is already handled at START. */
+ if (arg == END)
+ return;
+
+ /* Check if it's mislocated. */
+ if (current_insertion_type () != floatenv)
+ line_error (_("@%s not meaningful outside `@float' environment"), command);
+
+ get_until_in_braces ("\n@end float", &temp);
+
+ if (xml)
+ {
+ int elt = STREQ (command, "shortcaption") ? SHORTCAPTION : CAPTION;
+ xml_insert_element (elt, START);
+ if (!docbook)
+ execute_string ("%s", temp);
+ xml_insert_element (elt, END);
+ }
+
+ free (temp);
+}
+
/* Begin an insertion where the lines are not filled or indented. */
void
-cm_flushleft ()
+cm_flushleft (void)
{
begin_insertion (flushleft);
}
@@ -1423,15 +1936,15 @@ cm_flushleft ()
/* Begin an insertion where the lines are not filled, and each line is
forced to the right-hand side of the page. */
void
-cm_flushright ()
+cm_flushright (void)
{
begin_insertion (flushright);
}
void
-cm_menu ()
+cm_menu (void)
{
- if (current_node == NULL)
+ if (current_node == NULL && !macro_expansion_output_stream)
{
warning (_("@menu seen before first @node, creating `Top' node"));
warning (_("perhaps your @top node should be wrapped in @ifnottex rather than @ifinfo?"));
@@ -1442,22 +1955,108 @@ cm_menu ()
}
void
-cm_detailmenu ()
+cm_detailmenu (void)
{
- if (current_node == NULL)
+ if (current_node == NULL && !macro_expansion_output_stream)
{ /* Problems anyway, @detailmenu should always be inside @menu. */
warning (_("@detailmenu seen before first node, creating `Top' node"));
execute_string ("@node top\n@top Top\n");
}
begin_insertion (detailmenu);
}
+
+/* Title page commands. */
+
+void
+cm_titlepage (void)
+{
+ titlepage_cmd_present = 1;
+ if (xml && !docbook)
+ begin_insertion (titlepage);
+ else
+ command_name_condition ();
+}
+
+void
+cm_author (void)
+{
+ char *rest;
+ get_rest_of_line (1, &rest);
+
+ if (is_in_insertion_of_type (quotation))
+ {
+ if (html)
+ add_word_args ("&mdash; %s", rest);
+ else if (docbook)
+ {
+ /* FIXME Ideally, we should use an attribution element,
+ but they are supposed to be at the start of quotation
+ blocks. So to avoid looking ahead mess, let's just
+ use mdash like HTML for now. */
+ xml_insert_entity ("mdash");
+ add_word (rest);
+ }
+ else if (xml)
+ {
+ xml_insert_element (AUTHOR, START);
+ add_word (rest);
+ xml_insert_element (AUTHOR, END);
+ }
+ else
+ add_word_args ("-- %s", rest);
+ }
+ else if (is_in_insertion_of_type (titlepage))
+ {
+ if (xml && !docbook)
+ {
+ xml_insert_element (AUTHOR, START);
+ add_word (rest);
+ xml_insert_element (AUTHOR, END);
+ }
+ }
+ else
+ line_error (_("@%s not meaningful outside `@titlepage' and `@quotation' environments"),
+ command);
+
+ free (rest);
+}
+
+void
+cm_titlepage_cmds (void)
+{
+ char *rest;
+
+ get_rest_of_line (1, &rest);
+
+ if (!is_in_insertion_of_type (titlepage))
+ line_error (_("@%s not meaningful outside `@titlepage' environment"),
+ command);
+
+ if (xml && !docbook)
+ {
+ int elt = 0;
+
+ if (STREQ (command, "title"))
+ elt = BOOKTITLE;
+ else if (STREQ (command, "subtitle"))
+ elt = BOOKSUBTITLE;
+
+ xml_insert_element (elt, START);
+ add_word (rest);
+ xml_insert_element (elt, END);
+ }
+
+ free (rest);
+}
/* End existing insertion block. */
void
-cm_end ()
+cm_end (void)
{
char *temp;
- enum insertion_type type;
+ int type;
+
+ get_rest_of_line (0, &temp);
if (!insertion_level)
{
@@ -1465,8 +2064,6 @@ cm_end ()
return;
}
- get_rest_of_line (0, &temp);
-
if (temp[0] == 0)
line_error (_("`%c%s' needs something after it"), COMMAND_PREFIX, command);
@@ -1474,8 +2071,8 @@ cm_end ()
if (type == bad_type)
{
- line_error (_("Bad argument to `%s', `%s', using `%s'"),
- command, temp, insertion_type_pname (current_insertion_type ()));
+ line_error (_("Bad argument `%s' to `@%s', using `%s'"),
+ temp, command, insertion_type_pname (current_insertion_type ()));
}
if (xml && type == menu) /* fixme */
{
@@ -1490,9 +2087,8 @@ cm_end ()
static int itemx_flag = 0;
/* Return whether CMD takes a brace-delimited {arg}. */
-/*static */int
-command_needs_braces (cmd)
- char *cmd;
+int
+command_needs_braces (char *cmd)
{
int i;
for (i = 0; command_table[i].name; i++)
@@ -1506,7 +2102,7 @@ command_needs_braces (cmd)
void
-cm_item ()
+cm_item (void)
{
char *rest_of_line, *item_func;
@@ -1548,7 +2144,9 @@ cm_item ()
case ifset:
case iftex:
case ifxml:
+ case rawdocbook:
case rawhtml:
+ case rawxml:
case rawtex:
case tex:
case cartouche:
@@ -1585,14 +2183,7 @@ cm_item ()
else
{
if (html)
- {
- if (in_paragraph)
- {
- add_word ("</p>");
- in_paragraph = 0;
- }
- add_word ("<li>");
- }
+ add_html_block_elt ("<li>");
else if (xml)
xml_begin_item ();
else
@@ -1646,17 +2237,11 @@ cm_item ()
case ftable:
case vtable:
if (html)
- {
- static int last_html_output_position = 0;
-
- /* If nothing has been output since the last <dd>,
+ { /* If nothing has been output since the last <dd>,
remove the empty <dd> element. Some browsers render
an extra empty line for <dd><dt>, which makes @itemx
conversion look ugly. */
- if (last_html_output_position == output_position
- && strncmp ((char *) output_paragraph, "<dd>",
- output_paragraph_offset) == 0)
- output_paragraph_offset = 0;
+ rollback_empty_tag ("dd");
/* Force the browser to render one blank line before
each new @item in a table. But don't do that if
@@ -1666,14 +2251,14 @@ cm_item ()
Note that there are some browsers which ignore <br>
in this context, but I cannot find any way to force
them all render exactly one blank line. */
- if (!itemx_flag
- && ((output_paragraph_offset < sizeof (dl_tag) + 1)
- || strncmp ((char *) output_paragraph
- + output_paragraph_offset - sizeof (dl_tag) + 1,
- dl_tag, sizeof (dl_tag) - 1) != 0))
- add_word ("<br>");
+ if (!itemx_flag && html_deflist_has_term)
+ add_html_block_elt ("<br>");
+
+ /* We are about to insert a <dt>, so this <dl> has a term.
+ Feel free to insert a <br> next time. :) */
+ html_deflist_has_term = 1;
- add_word ("<dt>");
+ add_html_block_elt ("<dt>");
if (item_func && *item_func)
execute_string ("%s{%s}", item_func, rest_of_line);
else
@@ -1684,15 +2269,19 @@ cm_item ()
if (current_insertion_type () == vtable)
execute_string ("%cvindex %s\n", COMMAND_PREFIX, rest_of_line);
- /* Make sure output_position is updated, so we could
- remember it. */
- close_single_paragraph ();
- last_html_output_position = output_position;
- add_word ("<dd>");
+
+ add_html_block_elt ("<dd>");
}
else if (xml) /* && docbook)*/ /* 05-08 */
{
xml_begin_table_item ();
+
+ if (!docbook && current_insertion_type () == ftable)
+ execute_string ("%cfindex %s\n", COMMAND_PREFIX, rest_of_line);
+
+ if (!docbook && current_insertion_type () == vtable)
+ execute_string ("%cvindex %s\n", COMMAND_PREFIX, rest_of_line);
+
if (item_func && *item_func)
execute_string ("%s{%s}", item_func, rest_of_line);
else
@@ -1770,9 +2359,18 @@ cm_item ()
}
void
-cm_itemx ()
+cm_itemx (void)
{
itemx_flag++;
cm_item ();
itemx_flag--;
}
+
+int headitem_flag = 0;
+
+void
+cm_headitem (void)
+{
+ headitem_flag = 1;
+ cm_item ();
+}
diff --git a/contrib/texinfo/makeinfo/insertion.h b/contrib/texinfo/makeinfo/insertion.h
index 17916e7..ace5571 100644
--- a/contrib/texinfo/makeinfo/insertion.h
+++ b/contrib/texinfo/makeinfo/insertion.h
@@ -1,7 +1,7 @@
/* insertion.h -- declarations for insertion.c.
- $Id: insertion.h,v 1.2 2002/09/29 19:15:20 karl Exp $
+ $Id: insertion.h,v 1.10 2004/04/11 17:56:47 karl Exp $
- Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -24,14 +24,15 @@
enum insertion_type
{
cartouche, copying, defcv, deffn, defivar, defmac, defmethod, defop,
- defopt, defspec, deftp, deftypefn, deftypefun, deftypeivar,
+ defopt, defspec, deftp, deftypecv, deftypefn, deftypefun, deftypeivar,
deftypemethod, deftypeop, deftypevar, deftypevr, defun, defvar, defvr,
detailmenu, direntry, display, documentdescription, enumerate,
- example, flushleft, flushright, format, ftable, group, ifclear,
- ifhtml, ifinfo, ifnothtml, ifnotinfo, ifnotplaintext, ifnottex, ifnotxml,
- ifplaintext, ifset, iftex, ifxml, itemize, lisp, menu, multitable, quotation,
- rawhtml, rawtex, smalldisplay, smallexample, smallformat, smalllisp,
- verbatim, table, tex, vtable, bad_type
+ example, floatenv, flushleft, flushright, format, ftable, group,
+ ifclear, ifdocbook, ifhtml, ifinfo, ifnotdocbook, ifnothtml, ifnotinfo,
+ ifnotplaintext, ifnottex, ifnotxml, ifplaintext, ifset, iftex, ifxml,
+ itemize, lisp, menu, multitable, quotation, rawdocbook, rawhtml, rawtex,
+ rawxml, smalldisplay, smallexample, smallformat, smalllisp, verbatim,
+ table, tex, vtable, titlepage, bad_type
};
typedef struct istack_elt
@@ -42,12 +43,11 @@ typedef struct istack_elt
int line_number;
int filling_enabled;
int indented_fill;
- enum insertion_type insertion;
+ int insertion;
int inhibited;
int in_fixed_width_font;
} INSERTION_ELT;
-
extern int insertion_level;
extern INSERTION_ELT *insertion_stack;
extern int in_menu;
@@ -55,10 +55,24 @@ extern int in_detailmenu;
extern int had_menu_commentary;
extern int in_paragraph;
-extern void command_name_condition ();
-extern void cm_ifhtml (), cm_ifnothtml(), cm_html ();
-extern void cm_ifinfo (), cm_ifnotinfo ();
-extern void cm_ifplaintext (), cm_ifnotplaintext();
-extern void cm_iftex (), cm_ifnottex (), cm_tex ();
-extern void cm_ifxml (), cm_ifnotxml ();
+extern int headitem_flag;
+extern int after_headitem;
+
+extern void init_insertion_stack (void);
+extern void command_name_condition (void);
+extern void cm_ifdocbook (void), cm_ifnotdocbook(void), cm_docbook (int arg);
+extern void cm_ifhtml (void), cm_ifnothtml(void), cm_html (int arg);
+extern void cm_ifinfo (void), cm_ifnotinfo (void);
+extern void cm_ifplaintext (void), cm_ifnotplaintext(void);
+extern void cm_iftex (void), cm_ifnottex (void), cm_tex (void);
+extern void cm_ifxml (void), cm_ifnotxml (void), cm_xml (int arg);
+extern void handle_verbatim_environment (int find_end_verbatim);
+extern void begin_insertion (enum insertion_type type);
+extern void pop_insertion (void);
+extern void discard_insertions (int specials_ok);
+
+extern int is_in_insertion_of_type (int type);
+extern int command_needs_braces (char *cmd);
+
+extern enum insertion_type find_type_from_name (char *name);
#endif /* !INSERTION_H */
diff --git a/contrib/texinfo/makeinfo/lang.c b/contrib/texinfo/makeinfo/lang.c
index 2938196..c72e8db 100644
--- a/contrib/texinfo/makeinfo/lang.c
+++ b/contrib/texinfo/makeinfo/lang.c
@@ -1,7 +1,8 @@
/* lang.c -- language-dependent support.
- $Id: lang.c,v 1.8 2003/05/01 00:05:27 karl Exp $
+ $Id: lang.c,v 1.14 2004/11/22 23:57:33 karl Exp $
- Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software
+ Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,6 +22,7 @@
#include "system.h"
#include "cmds.h"
+#include "files.h"
#include "lang.h"
#include "makeinfo.h"
#include "xml.h"
@@ -31,6 +33,9 @@ encoding_code_type document_encoding_code = no_encoding;
/* Current language code; default is English. */
language_code_type language_code = en;
+/* By default, unsupported encoding is an empty string. */
+char *unknown_encoding = NULL;
+
static iso_map_type us_ascii_map [] = {{NULL, 0, 0}}; /* ASCII map is trivial */
/* Translation table between HTML and ISO Codes. The last item is
@@ -137,6 +142,126 @@ static iso_map_type iso8859_1_map [] = {
{ NULL, 0, 0 }
};
+
+/* ISO 8859-15, also known as Latin 9, differs from Latin 1 in only a
+ few positions. http://www.cs.tut.fi/~jkorpela/latin9.html has a good
+ explanation and listing, summarized here. The names are abbreviated
+ from the official Unicode names, to fit in a decent line length.
+
+ code position
+ dec oct hex latin1 latin1 name latin9 latin9 name
+
+ 164 0244 0xA4 U+00A4 currency symbol U+20AC euro sign
+ 166 0246 0xA6 U+00A6 broken bar U+0160 S with caron
+ 168 0250 0xA8 U+00A8 diaeresis U+0161 s with caron
+ 180 0264 0xB4 U+00B4 acute accent U+017D Z with caron
+ 184 0270 0xB8 U+00B8 cedilla U+017E z with caron
+ 188 0274 0xBC U+00BC fraction 1/4 U+0152 ligature OE
+ 189 0275 0xBD U+00BD fraction 1/2 U+0153 ligature oe
+ 190 0276 0xBE U+00BE fraction 3/4 U+0178 Y with diaeresis
+*/
+
+static iso_map_type iso8859_15_map [] = {
+ { "nbsp", 0xA0, 0x00A0 },
+ { "iexcl", 0xA1, 0x00A1 },
+ { "cent", 0xA2, 0x00A2 },
+ { "pound", 0xA3, 0x00A3 },
+ { "euro", 0xA4, 0x20AC },
+ { "yen", 0xA5, 0x00A5 },
+ { "Scaron", 0xA6, 0x0160 },
+ { "sect", 0xA7, 0x00A7 },
+ { "scaron", 0xA8, 0x0161 },
+ { "copy", 0xA9, 0x00A9 },
+ { "ordf", 0xAA, 0x00AA },
+ { "laquo", 0xAB, 0x00AB },
+ { "not", 0xAC, 0x00AC },
+ { "shy", 0xAD, 0x00AD },
+ { "reg", 0xAE, 0x00AE },
+ { "hibar", 0xAF, 0x00AF },
+ { "deg", 0xB0, 0x00B0 },
+ { "plusmn", 0xB1, 0x00B1 },
+ { "sup2", 0xB2, 0x00B2 },
+ { "sup3", 0xB3, 0x00B3 },
+ { "Zcaron", 0xB4, 0x017D },
+ { "micro", 0xB5, 0x00B5 },
+ { "para", 0xB6, 0x00B6 },
+ { "middot", 0xB7, 0x00B7 },
+ { "zcaron", 0xB8, 0x017E },
+ { "sup1", 0xB9, 0x00B9 },
+ { "ordm", 0xBA, 0x00BA },
+ { "raquo", 0xBB, 0x00BB },
+ { "OElig", 0xBC, 0x0152 },
+ { "oelig", 0xBD, 0x0153 },
+ { "Yuml", 0xBE, 0x0178 },
+ { "iquest", 0xBF, 0x00BF },
+ { "Agrave", 0xC0, 0x00C0 },
+ { "Aacute", 0xC1, 0x00C1 },
+ { "Acirc", 0xC2, 0x00C2 },
+ { "Atilde", 0xC3, 0x00C3 },
+ { "Auml", 0xC4, 0x00C4 },
+ { "Aring", 0xC5, 0x00C5 },
+ { "AElig", 0xC6, 0x00C6 },
+ { "Ccedil", 0xC7, 0x00C7 },
+ { "Ccedil", 0xC7, 0x00C7 },
+ { "Egrave", 0xC8, 0x00C8 },
+ { "Eacute", 0xC9, 0x00C9 },
+ { "Ecirc", 0xCA, 0x00CA },
+ { "Euml", 0xCB, 0x00CB },
+ { "Igrave", 0xCC, 0x00CC },
+ { "Iacute", 0xCD, 0x00CD },
+ { "Icirc", 0xCE, 0x00CE },
+ { "Iuml", 0xCF, 0x00CF },
+ { "ETH", 0xD0, 0x00D0 },
+ { "Ntilde", 0xD1, 0x00D1 },
+ { "Ograve", 0xD2, 0x00D2 },
+ { "Oacute", 0xD3, 0x00D3 },
+ { "Ocirc", 0xD4, 0x00D4 },
+ { "Otilde", 0xD5, 0x00D5 },
+ { "Ouml", 0xD6, 0x00D6 },
+ { "times", 0xD7, 0x00D7 },
+ { "Oslash", 0xD8, 0x00D8 },
+ { "Ugrave", 0xD9, 0x00D9 },
+ { "Uacute", 0xDA, 0x00DA },
+ { "Ucirc", 0xDB, 0x00DB },
+ { "Uuml", 0xDC, 0x00DC },
+ { "Yacute", 0xDD, 0x00DD },
+ { "THORN", 0xDE, 0x00DE },
+ { "szlig", 0xDF, 0x00DF },
+ { "agrave", 0xE0, 0x00E0 },
+ { "aacute", 0xE1, 0x00E1 },
+ { "acirc", 0xE2, 0x00E2 },
+ { "atilde", 0xE3, 0x00E3 },
+ { "auml", 0xE4, 0x00E4 },
+ { "aring", 0xE5, 0x00E5 },
+ { "aelig", 0xE6, 0x00E6 },
+ { "ccedil", 0xE7, 0x00E7 },
+ { "egrave", 0xE8, 0x00E8 },
+ { "eacute", 0xE9, 0x00E9 },
+ { "ecirc", 0xEA, 0x00EA },
+ { "euml", 0xEB, 0x00EB },
+ { "igrave", 0xEC, 0x00EC },
+ { "iacute", 0xED, 0x00ED },
+ { "icirc", 0xEE, 0x00EE },
+ { "iuml", 0xEF, 0x00EF },
+ { "eth", 0xF0, 0x00F0 },
+ { "ntilde", 0xF1, 0x00F1 },
+ { "ograve", 0xF2, 0x00F2 },
+ { "oacute", 0xF3, 0x00F3 },
+ { "ocirc", 0xF4, 0x00F4 },
+ { "otilde", 0xF5, 0x00F5 },
+ { "ouml", 0xF6, 0x00F6 },
+ { "divide", 0xF7, 0x00F7 },
+ { "oslash", 0xF8, 0x00F8 },
+ { "ugrave", 0xF9, 0x00F9 },
+ { "uacute", 0xFA, 0x00FA },
+ { "ucirc", 0xFB, 0x00FB },
+ { "uuml", 0xFC, 0x00FC },
+ { "yacute", 0xFD, 0x00FD },
+ { "thorn", 0xFE, 0x00FE },
+ { "yuml", 0xFF, 0x00FF },
+ { NULL, 0, 0 }
+};
+
/* Date: Mon, 31 Mar 2003 00:19:28 +0200
@@ -262,21 +387,21 @@ static iso_map_type iso8859_2_map [] = {
encoding_type encoding_table[] = {
{ no_encoding, "(no encoding)", NULL },
{ US_ASCII, "US-ASCII", us_ascii_map },
- { ISO_8859_1, "ISO-8859-1", (iso_map_type *) iso8859_1_map },
- { ISO_8859_2, "ISO-8859-2", (iso_map_type *) iso8859_2_map },
- { ISO_8859_3, "ISO-8859-3", NULL },
- { ISO_8859_4, "ISO-8859-4", NULL },
- { ISO_8859_5, "ISO-8859-5", NULL },
- { ISO_8859_6, "ISO-8859-6", NULL },
- { ISO_8859_7, "ISO-8859-7", NULL },
- { ISO_8859_8, "ISO-8859-8", NULL },
- { ISO_8859_9, "ISO-8859-9", NULL },
- { ISO_8859_10, "ISO-8859-10", NULL },
- { ISO_8859_11, "ISO-8859-11", NULL },
- { ISO_8859_12, "ISO-8859-12", NULL },
- { ISO_8859_13, "ISO-8859-13", NULL },
- { ISO_8859_14, "ISO-8859-14", NULL },
- { ISO_8859_15, "ISO-8859-15", NULL },
+ { ISO_8859_1, "iso-8859-1", (iso_map_type *) iso8859_1_map },
+ { ISO_8859_2, "iso-8859-2", (iso_map_type *) iso8859_2_map },
+ { ISO_8859_3, "iso-8859-3", NULL },
+ { ISO_8859_4, "iso-8859-4", NULL },
+ { ISO_8859_5, "iso-8859-5", NULL },
+ { ISO_8859_6, "iso-8859-6", NULL },
+ { ISO_8859_7, "iso-8859-7", NULL },
+ { ISO_8859_8, "iso-8859-8", NULL },
+ { ISO_8859_9, "iso-8859-9", NULL },
+ { ISO_8859_10, "iso-8859-10", NULL },
+ { ISO_8859_11, "iso-8859-11", NULL },
+ { ISO_8859_12, "iso-8859-12", NULL },
+ { ISO_8859_13, "iso-8859-13", NULL },
+ { ISO_8859_14, "iso-8859-14", NULL },
+ { ISO_8859_15, "iso-8859-15", (iso_map_type *) iso8859_15_map },
{ last_encoding_code, NULL, NULL }
};
@@ -423,13 +548,16 @@ language_type language_table[] = {
{ zu, "zu", "Zulu" },
{ last_language_code, NULL, NULL }
};
-
-
/* @documentlanguage. Maybe we'll do something useful with this in the
future. For now, we just recognize it. */
+
+/* XML documents can make use of this data. Unfortunately, it clashes with
+ the structure currently used. So instead of enclosing content into
+ a language block, we just output an empty element. Anyways, a stream based
+ parser can make good use of it. */
void
-cm_documentlanguage ()
+cm_documentlanguage (void)
{
language_code_type c;
char *lang_arg;
@@ -451,6 +579,12 @@ cm_documentlanguage ()
if (c == last_language_code)
warning (_("%s is not a valid ISO 639 language code"), lang_arg);
+ if (xml && !docbook)
+ {
+ xml_insert_element_with_attribute (DOCUMENTLANGUAGE, START, "xml:lang=\"%s\"", lang_arg);
+ xml_insert_element (DOCUMENTLANGUAGE, END);
+ }
+
free (lang_arg);
}
@@ -460,8 +594,7 @@ cm_documentlanguage ()
its equivalent. */
static int
-cm_search_iso_map (html)
- char *html;
+cm_search_iso_map (char *html)
{
int i;
iso_map_type *iso = encoding_table[document_encoding_code].isotab;
@@ -483,43 +616,88 @@ cm_search_iso_map (html)
/* @documentencoding. Set the translation table. */
void
-cm_documentencoding ()
+cm_documentencoding (void)
{
- encoding_code_type enc;
- char *enc_arg;
-
- get_rest_of_line (1, &enc_arg);
-
- /* See if we have this encoding. */
- for (enc = no_encoding+1; enc != last_encoding_code; enc++)
+ if (!handling_delayed_writes)
{
- if (strcasecmp (enc_arg, encoding_table[enc].encname) == 0)
+ encoding_code_type enc;
+ char *enc_arg;
+
+ /* This is ugly and probably needs to apply to other commands'
+ argument parsing as well. When we're doing @documentencoding,
+ we're generally in the frontmatter of the document, and so the.
+ expansion in html/xml/docbook would generally be the empty string.
+ (Because those modes wait until the first normal text of the
+ document to start outputting.) The result would thus be a warning
+ "unrecognized encoding name `'". Sigh. */
+ int save_html = html;
+ int save_xml = xml;
+
+ html = 0;
+ xml = 0;
+ get_rest_of_line (1, &enc_arg);
+ html = save_html;
+ xml = save_xml;
+
+ /* See if we have this encoding. */
+ for (enc = no_encoding+1; enc != last_encoding_code; enc++)
{
- document_encoding_code = enc;
- break;
+ if (strcasecmp (enc_arg, encoding_table[enc].encname) == 0)
+ {
+ document_encoding_code = enc;
+ break;
+ }
+ }
+
+ /* If we didn't find this code, complain. */
+ if (enc == last_encoding_code)
+ {
+ warning (_("unrecognized encoding name `%s'"), enc_arg);
+ /* Let the previous one go. */
+ if (unknown_encoding && *unknown_encoding)
+ free (unknown_encoding);
+ unknown_encoding = xstrdup (enc_arg);
}
+
+ else if (encoding_table[document_encoding_code].isotab == NULL)
+ warning (_("sorry, encoding `%s' not supported"), enc_arg);
+
+ free (enc_arg);
}
+ else if (xml)
+ {
+ char *encoding = current_document_encoding ();
- /* If we didn't find this code, complain. */
- if (enc == last_encoding_code)
- warning (_("unrecognized encoding name `%s'"), enc_arg);
+ if (encoding && *encoding)
+ {
+ insert_string (" encoding=\"");
+ insert_string (encoding);
+ insert_string ("\"");
+ }
- else if (encoding_table[document_encoding_code].isotab == NULL)
- warning (_("sorry, encoding `%s' not supported"), enc_arg);
+ free (encoding);
+ }
+}
- free (enc_arg);
+char *
+current_document_encoding (void)
+{
+ if (document_encoding_code != no_encoding)
+ return xstrdup (encoding_table[document_encoding_code].encname);
+ else if (unknown_encoding && *unknown_encoding)
+ return xstrdup (unknown_encoding);
+ else
+ return xstrdup ("");
}
-/* If html or xml output, add HTML_STR to the output. If not html and
+/* If html or xml output, add &HTML_STR; to the output. If not html and
the user requested encoded output, add the real 8-bit character
corresponding to HTML_STR from the translation tables. Otherwise,
add INFO_STR. */
-void
-add_encoded_char (html_str, info_str)
- char *html_str;
- char *info_str;
+static void
+add_encoded_char (char *html_str, char *info_str)
{
if (html)
add_word_args ("&%s;", html_str);
@@ -547,13 +725,8 @@ add_encoded_char (html_str, info_str)
/* Output an accent for HTML or XML. */
static void
-cm_accent_generic_html (arg, start, end, html_supported, single,
- html_solo_standalone, html_solo)
- int arg, start, end;
- char *html_supported;
- int single;
- int html_solo_standalone;
- char *html_solo;
+cm_accent_generic_html (int arg, int start, int end, char *html_supported,
+ int single, int html_solo_standalone, char *html_solo)
{
static int valid_html_accent; /* yikes */
@@ -569,20 +742,39 @@ cm_accent_generic_html (arg, start, end, html_supported, single,
escape_html = saved_escape_html;
}
else
- {
- valid_html_accent = 0;
- if (html_solo_standalone)
- { /* No special HTML support, so produce standalone char. */
- if (xml)
- xml_insert_entity (html_solo);
+ { /* @dotless{i} is not listed in html_supported but HTML entities
+ starting with `i' can be used, such as &icirc;. */
+ int save_input_text_offset = input_text_offset;
+ char *accent_contents;
+
+ get_until_in_braces ("\n", &accent_contents);
+ canon_white (accent_contents);
+
+ if (strstr (accent_contents, "@dotless{i"))
+ {
+ add_word_args ("&%c", accent_contents[9]);
+ valid_html_accent = 1;
+ }
+ else
+ {
+ /* Search for @dotless{} wasn't successful, so rewind. */
+ input_text_offset = save_input_text_offset;
+ valid_html_accent = 0;
+ if (html_solo_standalone)
+ { /* No special HTML support, so produce standalone char. */
+ if (xml)
+ xml_insert_entity (html_solo);
+ else
+ add_word_args ("&%s;", html_solo);
+ }
else
- add_word_args ("&%s;", html_solo);
- }
- else
- /* If the html_solo does not exist as standalone character
- (namely &circ; &grave; &tilde;), then we use
- the single character version instead. */
- add_char (single);
+ /* If the html_solo does not exist as standalone character
+ (namely &circ; &grave; &tilde;), then we use
+ the single character version instead. */
+ add_char (single);
+ }
+
+ free (accent_contents);
}
}
else if (arg == END)
@@ -598,10 +790,8 @@ cm_accent_generic_html (arg, start, end, html_supported, single,
static void
-cm_accent_generic_no_headers (arg, start, end, single, html_solo)
- int arg, start, end;
- int single;
- char *html_solo;
+cm_accent_generic_no_headers (int arg, int start, int end, int single,
+ char *html_solo)
{
if (arg == END)
{
@@ -628,8 +818,11 @@ cm_accent_generic_no_headers (arg, start, end, single, html_solo)
{ /* If we didn't find a translation for this character,
put the single instead. E.g., &Xuml; does not exist so X&uml;
should be produced. */
- warning (_("%s is an invalid ISO code, using %c"),
- buffer, single);
+ /* When the below warning is issued, an author has nothing
+ wrong in their document, let alone anything ``fixable''
+ on their side. So it is commented out for now. */
+ /* warning (_("%s is an invalid ISO code, using %c"),
+ buffer, single); */
add_char (single);
}
@@ -644,8 +837,7 @@ cm_accent_generic_no_headers (arg, start, end, single, html_solo)
special HTML support. */
void
-cm_accent (arg)
- int arg;
+cm_accent (int arg)
{
int old_escape_html = escape_html;
escape_html = 0;
@@ -687,14 +879,14 @@ cm_accent (arg)
exists as valid standalone character in HTML, e.g., &uml;. */
static void
-cm_accent_generic (arg, start, end, html_supported, single,
- html_solo_standalone, html_solo)
- int arg, start, end;
- char *html_supported;
- int single;
- int html_solo_standalone;
- char *html_solo;
+cm_accent_generic (int arg, int start, int end, char *html_supported,
+ int single, int html_solo_standalone, char *html_solo)
{
+ /* Accentuating space characters makes no sense, so issue a warning. */
+ if (arg == START && isspace (input_text[input_text_offset]))
+ warning ("Accent command `@%s' must not be followed by whitespace",
+ command);
+
if (html || xml)
cm_accent_generic_html (arg, start, end, html_supported,
single, html_solo_standalone, html_solo);
@@ -712,43 +904,37 @@ cm_accent_generic (arg, start, end, html_supported, single,
}
void
-cm_accent_umlaut (arg, start, end)
- int arg, start, end;
+cm_accent_umlaut (int arg, int start, int end)
{
cm_accent_generic (arg, start, end, "aouAOUEeIiy", '"', 1, "uml");
}
void
-cm_accent_acute (arg, start, end)
- int arg, start, end;
+cm_accent_acute (int arg, int start, int end)
{
cm_accent_generic (arg, start, end, "AEIOUYaeiouy", '\'', 1, "acute");
}
void
-cm_accent_cedilla (arg, start, end)
- int arg, start, end;
+cm_accent_cedilla (int arg, int start, int end)
{
cm_accent_generic (arg, start, end, "Cc", ',', 1, "cedil");
}
void
-cm_accent_hat (arg, start, end)
- int arg, start, end;
+cm_accent_hat (int arg, int start, int end)
{
cm_accent_generic (arg, start, end, "AEIOUaeiou", '^', 0, "circ");
}
void
-cm_accent_grave (arg, start, end)
- int arg, start, end;
+cm_accent_grave (int arg, int start, int end)
{
cm_accent_generic (arg, start, end, "AEIOUaeiou", '`', 0, "grave");
}
void
-cm_accent_tilde (arg, start, end)
- int arg, start, end;
+cm_accent_tilde (int arg, int start, int end)
{
cm_accent_generic (arg, start, end, "ANOano", '~', 0, "tilde");
}
@@ -757,7 +943,7 @@ cm_accent_tilde (arg, start, end)
/* Non-English letters/characters that don't insert themselves. */
void
-cm_special_char (arg)
+cm_special_char (int arg)
{
int old_escape_html = escape_html;
escape_html = 0;
@@ -769,27 +955,35 @@ cm_special_char (arg)
&& command[1] == 0)
{ /* Lslash lslash Oslash oslash.
Lslash and lslash aren't supported in HTML. */
- if ((html || xml) && command[0] == 'O')
+ if (command[0] == 'O')
add_encoded_char ("Oslash", "/O");
- else if ((html || xml) && command[0] == 'o')
+ else if (command[0] == 'o')
add_encoded_char ("oslash", "/o");
else
add_word_args ("/%c", command[0]);
}
else if (strcmp (command, "exclamdown") == 0)
add_encoded_char ("iexcl", "!");
- else if (strcmp (command, "pounds") == 0)
- add_encoded_char ("pound" , "#");
else if (strcmp (command, "questiondown") == 0)
add_encoded_char ("iquest", "?");
+ else if (strcmp (command, "euro") == 0)
+ /* http://www.cs.tut.fi/~jkorpela/html/euro.html suggests that
+ &euro; degrades best in old browsers. */
+ add_encoded_char ("euro", "Euro ");
+ else if (strcmp (command, "pounds") == 0)
+ add_encoded_char ("pound" , "#");
+ else if (strcmp (command, "ordf") == 0)
+ add_encoded_char ("ordf" , "a");
+ else if (strcmp (command, "ordm") == 0)
+ add_encoded_char ("ordm" , "o");
else if (strcmp (command, "AE") == 0)
add_encoded_char ("AElig", command);
else if (strcmp (command, "ae") == 0)
add_encoded_char ("aelig", command);
else if (strcmp (command, "OE") == 0)
- add_encoded_char ("#140", command);
+ add_encoded_char ("OElig", command);
else if (strcmp (command, "oe") == 0)
- add_encoded_char ("#156", command);
+ add_encoded_char ("oelig", command);
else if (strcmp (command, "AA") == 0)
add_encoded_char ("Aring", command);
else if (strcmp (command, "aa") == 0)
@@ -804,8 +998,7 @@ cm_special_char (arg)
/* Dotless i or j. */
void
-cm_dotless (arg, start, end)
- int arg, start, end;
+cm_dotless (int arg, int start, int end)
{
if (arg == END)
{
diff --git a/contrib/texinfo/makeinfo/lang.h b/contrib/texinfo/makeinfo/lang.h
index a1e9489..b231455 100644
--- a/contrib/texinfo/makeinfo/lang.h
+++ b/contrib/texinfo/makeinfo/lang.h
@@ -1,5 +1,5 @@
/* lang.h -- declarations for language codes etc.
- $Id: lang.h,v 1.4 2003/05/01 00:05:27 karl Exp $
+ $Id: lang.h,v 1.6 2004/04/11 17:56:47 karl Exp $
Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
@@ -73,34 +73,35 @@ extern language_type language_table[];
-/* The document encoding. This is usefull if we working e.g.
- * with german Texinfo so we can produce correct german umlaut
- * while creating output (--no-headers ASCII like).
- */
+/* The document encoding. This is useful to produce true 8-bit
+ characters according to the @documentencoding. */
+
typedef enum {
- no_encoding,
- US_ASCII,
- ISO_8859_1,
- ISO_8859_2,
- ISO_8859_3, /* this and none of the rest are supported. */
- ISO_8859_4,
- ISO_8859_5,
- ISO_8859_6,
- ISO_8859_7,
- ISO_8859_8,
- ISO_8859_9,
- ISO_8859_10,
- ISO_8859_11,
- ISO_8859_12,
- ISO_8859_13,
- ISO_8859_14,
- ISO_8859_15,
- last_encoding_code
+ no_encoding,
+ US_ASCII,
+ ISO_8859_1,
+ ISO_8859_2,
+ ISO_8859_3, /* this and none of the rest are supported. */
+ ISO_8859_4,
+ ISO_8859_5,
+ ISO_8859_6,
+ ISO_8859_7,
+ ISO_8859_8,
+ ISO_8859_9,
+ ISO_8859_10,
+ ISO_8859_11,
+ ISO_8859_12,
+ ISO_8859_13,
+ ISO_8859_14,
+ ISO_8859_15,
+ last_encoding_code
} encoding_code_type;
/* The current document encoding, or null if not set. */
extern encoding_code_type document_encoding_code;
+/* If an encoding is not supported, just keep it as a string. */
+extern char *unknown_encoding;
/* Maps an HTML abbreviation to ISO and Unicode codes for a given code. */
@@ -118,7 +119,8 @@ typedef struct
typedef struct
{
encoding_code_type ec; /* document encoding type (see above enum) */
- char *encname; /* encoding name like "ISO-8859-1", valid in Emacs */
+ char *encname; /* encoding name like "iso-8859-1", valid in
+ HTML and Emacs */
iso_map_type *isotab; /* address of ISO translation table */
} encoding_type;
@@ -127,12 +129,20 @@ extern encoding_type encoding_table[];
/* The commands. */
-extern void cm_documentlanguage (), cm_documentencoding ();
+extern void cm_documentlanguage (void),
+ cm_documentencoding (void);
/* Accents, other non-English characters. */
-void cm_accent (), cm_special_char (), cm_dotless ();
+void cm_accent (int arg), cm_special_char (int arg),
+ cm_dotless (int arg, int start, int end);
+
+extern void cm_accent_umlaut (int arg, int start, int end),
+ cm_accent_acute (int arg, int start, int end),
+ cm_accent_cedilla (int arg, int start, int end),
+ cm_accent_hat (int arg, int start, int end),
+ cm_accent_grave (int arg, int start, int end),
+ cm_accent_tilde (int arg, int start, int end);
-extern void cm_accent_umlaut (), cm_accent_acute (), cm_accent_cedilla (),
- cm_accent_hat (), cm_accent_grave (), cm_accent_tilde ();
+extern char *current_document_encoding (void);
#endif /* not LANG_H */
diff --git a/contrib/texinfo/makeinfo/macro.c b/contrib/texinfo/makeinfo/macro.c
index ef33a53..65ac0da 100644
--- a/contrib/texinfo/makeinfo/macro.c
+++ b/contrib/texinfo/makeinfo/macro.c
@@ -1,5 +1,5 @@
/* macro.c -- user-defined macros for Texinfo.
- $Id: macro.c,v 1.2 2003/06/01 23:41:23 karl Exp $
+ $Id: macro.c,v 1.6 2004/04/11 17:56:47 karl Exp $
Copyright (C) 1998, 1999, 2002, 2003 Free Software Foundation, Inc.
@@ -19,6 +19,7 @@
#include "system.h"
#include "cmds.h"
+#include "files.h"
#include "macro.h"
#include "makeinfo.h"
#include "insertion.h"
@@ -54,8 +55,7 @@ int macro_list_size = 0; /* Number of slots in total. */
/* Return the length of the array in ARRAY. */
int
-array_len (array)
- char **array;
+array_len (char **array)
{
int i = 0;
@@ -66,8 +66,7 @@ array_len (array)
}
void
-free_array (array)
- char **array;
+free_array (char **array)
{
if (array)
{
@@ -81,8 +80,7 @@ free_array (array)
/* Return the macro definition of NAME or NULL if NAME is not defined. */
MACRO_DEF *
-find_macro (name)
- char *name;
+find_macro (char *name)
{
int i;
MACRO_DEF *def;
@@ -101,13 +99,9 @@ find_macro (name)
and SOURCE_LINENO is the line number within that file. If a macro already
exists with NAME, then a warning is produced, and that previous
definition is overwritten. */
-void
-add_macro (name, arglist, body, source_file, source_lineno, flags)
- char *name;
- char **arglist;
- char *body;
- char *source_file;
- int source_lineno, flags;
+static void
+add_macro (char *name, char **arglist, char *body, char *source_file,
+ int source_lineno, int flags)
{
MACRO_DEF *def;
@@ -163,8 +157,7 @@ add_macro (name, arglist, body, source_file, source_lineno, flags)
char **
-get_brace_args (quote_single)
- int quote_single;
+get_brace_args (int quote_single)
{
char **arglist, *word;
int arglist_index, arglist_size;
@@ -243,9 +236,8 @@ get_brace_args (quote_single)
return arglist;
}
-char **
-get_macro_args (def)
- MACRO_DEF *def;
+static char **
+get_macro_args (MACRO_DEF *def)
{
int i;
char *word;
@@ -298,9 +290,8 @@ get_macro_args (def)
/* Substitute actual parameters for named parameters in body.
The named parameters which appear in BODY must by surrounded
reverse slashes, as in \foo\. */
-char *
-apply (named, actuals, body)
- char **named, **actuals, *body;
+static char *
+apply (char **named, char **actuals, char *body)
{
int i;
int new_body_index, new_body_size;
@@ -391,8 +382,7 @@ apply (named, actuals, body)
/* Expand macro passed in DEF, a pointer to a MACRO_DEF, and
return its expansion as a string. */
char *
-expand_macro (def)
- MACRO_DEF *def;
+expand_macro (MACRO_DEF *def)
{
char **arglist;
int num_args;
@@ -422,8 +412,7 @@ expand_macro (def)
/* Execute the macro passed in DEF, a pointer to a MACRO_DEF. */
void
-execute_macro (def)
- MACRO_DEF *def;
+execute_macro (MACRO_DEF *def)
{
char *execution_string;
int start_line = line_number, end_line;
@@ -444,7 +433,8 @@ execute_macro (def)
end_line = line_number;
line_number = start_line;
- if (macro_expansion_output_stream && !executing_string && !me_inhibit_expansion)
+ if (macro_expansion_output_stream
+ && !executing_string && !me_inhibit_expansion)
{
remember_itext (input_text, input_text_offset);
me_execute_string (execution_string);
@@ -462,21 +452,17 @@ execute_macro (def)
set the ME_RECURSE flag. MACTYPE is either "macro" or "rmacro", and
tells us what the matching @end should be. */
static void
-define_macro (mactype, recursive)
- char *mactype;
- int recursive;
+define_macro (char *mactype, int recursive)
{
- int i;
- char *name, **arglist, *body, *line, *last_end;
- int body_size, body_index;
+ int i, start;
+ char *name, *line;
+ char *last_end = NULL;
+ char *body = NULL;
+ char **arglist = NULL;
+ int body_size = 0, body_index = 0;
int depth = 1;
- int defining_line = line_number;
int flags = 0;
-
- arglist = NULL;
- body = NULL;
- body_size = 0;
- body_index = 0;
+ int defining_line = line_number;
if (macro_expansion_output_stream && !executing_string)
me_append_before_this_command ();
@@ -485,15 +471,13 @@ define_macro (mactype, recursive)
/* Get the name of the macro. This is the set of characters which are
not whitespace and are not `{' immediately following the @macro. */
+ start = input_text_offset;
{
- int start = input_text_offset;
int len;
- for (i = start;
- (i < input_text_length) &&
- (input_text[i] != '{') &&
- (!cr_or_whitespace (input_text[i]));
- i++);
+ for (i = start; i < input_text_length && input_text[i] != '{'
+ && !cr_or_whitespace (input_text[i]);
+ i++) ;
len = i - start;
name = xmalloc (1 + len);
@@ -653,7 +637,7 @@ define_macro (mactype, recursive)
depth--;
last_end = "macro";
}
- if (*line == COMMAND_PREFIX && strncmp (line + 1, "end rmacro", 9) == 0)
+ if (*line == COMMAND_PREFIX && strncmp (line + 1, "end rmacro", 10) == 0)
{
depth--;
last_end = "rmacro";
@@ -697,17 +681,32 @@ define_macro (mactype, recursive)
add_macro (name, arglist, body, input_filename, defining_line, flags);
if (macro_expansion_output_stream && !executing_string)
- remember_itext (input_text, input_text_offset);
+ {
+ /* Remember text for future expansions. */
+ remember_itext (input_text, input_text_offset);
+
+ /* Bizarrely, output the @macro itself. This is so texinfo.tex
+ will have a chance to read it when texi2dvi calls makeinfo -E.
+ The problem is that we don't really expand macros in all
+ contexts; a @table's @item is one. And a fix is not obvious to
+ me, since it appears virtually identical to any other internal
+ expansion. Just setting a variable in cm_item caused other
+ strange expansion problems. */
+ write_region_to_macro_output ("@", 0, 1);
+ write_region_to_macro_output (mactype, 0, strlen (mactype));
+ write_region_to_macro_output (" ", 0, 1);
+ write_region_to_macro_output (input_text, start, input_text_offset);
+ }
}
void
-cm_macro ()
+cm_macro (void)
{
define_macro ("macro", 0);
}
void
-cm_rmacro ()
+cm_rmacro (void)
{
define_macro ("rmacro", 1);
}
@@ -717,8 +716,7 @@ cm_rmacro ()
returned. */
static MACRO_DEF *
-delete_macro (name)
- char *name;
+delete_macro (char *name)
{
int i;
MACRO_DEF *def;
@@ -737,7 +735,7 @@ delete_macro (name)
}
void
-cm_unmacro ()
+cm_unmacro (void)
{
int i;
char *line, *name;
@@ -785,9 +783,7 @@ cm_unmacro ()
/* Set the value of POINTER's offset to OFFSET. */
ITEXT *
-remember_itext (pointer, offset)
- char *pointer;
- int offset;
+remember_itext (char *pointer, int offset)
{
int i;
ITEXT *itext = NULL;
@@ -841,8 +837,7 @@ remember_itext (pointer, offset)
/* Forget the input text associated with POINTER. */
void
-forget_itext (pointer)
- char *pointer;
+forget_itext (char *pointer)
{
int i;
@@ -858,7 +853,7 @@ forget_itext (pointer)
/* Append the text which appeared in input_text from the last offset to
the character just before the command that we are currently executing. */
void
-me_append_before_this_command ()
+me_append_before_this_command (void)
{
int i;
@@ -870,8 +865,7 @@ me_append_before_this_command ()
/* Similar to execute_string, but only takes a single string argument,
and remembers the input text location, etc. */
void
-me_execute_string (execution_string)
- char *execution_string;
+me_execute_string (char *execution_string)
{
int saved_escape_html = escape_html;
int saved_in_paragraph = in_paragraph;
@@ -903,8 +897,7 @@ me_execute_string (execution_string)
when we need to produce macro-expanded output for input which
leaves no traces in the Info output. */
void
-me_execute_string_keep_state (execution_string, append_string)
- char *execution_string, *append_string;
+me_execute_string_keep_state (char *execution_string, char *append_string)
{
int op_orig, opcol_orig, popen_orig;
int fill_orig, newline_orig, indent_orig, meta_pos_orig;
@@ -934,8 +927,7 @@ me_execute_string_keep_state (execution_string, append_string)
/* Append the text which appears in input_text from the last offset to
the current OFFSET. */
void
-append_to_expansion_output (offset)
- int offset;
+append_to_expansion_output (int offset)
{
int i;
ITEXT *itext = NULL;
@@ -959,9 +951,7 @@ append_to_expansion_output (offset)
/* Only write this input text iff it appears in our itext list. */
void
-maybe_write_itext (pointer, offset)
- char *pointer;
- int offset;
+maybe_write_itext (char *pointer, int offset)
{
int i;
ITEXT *itext = NULL;
@@ -981,9 +971,7 @@ maybe_write_itext (pointer, offset)
}
void
-write_region_to_macro_output (string, start, end)
- char *string;
- int start, end;
+write_region_to_macro_output (char *string, int start, int end)
{
if (macro_expansion_output_stream)
fwrite (string + start, 1, end - start, macro_expansion_output_stream);
@@ -1000,14 +988,15 @@ typedef struct alias_struct
static alias_type *aliases;
-/* @alias */
+/* @alias aname = cmdname */
+
void
-cm_alias ()
+cm_alias (void)
{
alias_type *a = xmalloc (sizeof (alias_type));
skip_whitespace ();
- get_until_in_line (1, "=", &(a->alias));
+ get_until_in_line (0, "=", &(a->alias));
canon_white (a->alias);
discard_until ("=");
@@ -1020,8 +1009,7 @@ cm_alias ()
/* Perform an alias expansion. Called from read_command. */
char *
-alias_expand (tok)
- char *tok;
+alias_expand (char *tok)
{
alias_type *findit = aliases;
@@ -1062,7 +1050,7 @@ static enclosure_stack_type *enclosure_stack;
/* @definfoenclose */
void
-cm_definfoenclose ()
+cm_definfoenclose (void)
{
enclosure_type *e = xmalloc (sizeof (enclosure_type));
@@ -1081,8 +1069,7 @@ cm_definfoenclose ()
return 1. Else return 0. */
int
-enclosure_command (tok)
- char *tok;
+enclosure_command (char *tok)
{
enclosure_type *findit = enclosures;
@@ -1104,8 +1091,7 @@ enclosure_command (tok)
/* actually perform the enclosure expansion */
void
-enclosure_expand (arg, start, end)
- int arg, start, end;
+enclosure_expand (int arg, int start, int end)
{
if (arg == START)
add_word (enclosure_stack->current->before);
diff --git a/contrib/texinfo/makeinfo/macro.h b/contrib/texinfo/makeinfo/macro.h
index 5161084..fbc0e59 100644
--- a/contrib/texinfo/makeinfo/macro.h
+++ b/contrib/texinfo/makeinfo/macro.h
@@ -1,5 +1,5 @@
/* macro.h -- declarations for macro.c.
- $Id: macro.h,v 1.1 2002/08/25 23:38:38 karl Exp $
+ $Id: macro.h,v 1.2 2004/04/11 17:56:47 karl Exp $
Copyright (C) 1998, 99 Free Software Foundation, Inc.
@@ -48,24 +48,30 @@ typedef struct {
#define ME_RECURSE 0x01
#define ME_QUOTE_ARG 0x02
-extern void execute_macro ();
-extern MACRO_DEF *find_macro ();
-extern char *expand_macro ();
+extern void execute_macro (MACRO_DEF *def);
+extern MACRO_DEF *find_macro (char *name);
+extern char *expand_macro (MACRO_DEF *def);
-extern ITEXT *remember_itext ();
-extern void forget_itext ();
-extern void maybe_write_itext ();
-extern void write_region_to_macro_output ();
-extern void append_to_expansion_output ();
-extern void me_append_before_this_command ();
-extern void me_execute_string ();
+extern ITEXT *remember_itext (char *pointer, int offset);
+extern void forget_itext (char *pointer);
+extern void maybe_write_itext (char *pointer, int offset);
+extern void write_region_to_macro_output (char *string, int start, int end);
+extern void append_to_expansion_output (int offset);
+extern void me_append_before_this_command (void);
+extern void me_execute_string (char *execution_string);
+extern void me_execute_string_keep_state (char *execution_string,
+ char *append_string);
-extern char *alias_expand ();
-extern int enclosure_command ();
-extern void enclosure_expand ();
+extern char *alias_expand (char *tok);
+extern int enclosure_command (char *tok);
+extern void enclosure_expand (int arg, int start, int end);
/* The @commands. */
-extern void cm_macro (), cm_rmacro (), cm_unmacro ();
-extern void cm_alias (), cm_definfoenclose ();
+extern void cm_macro (void), cm_rmacro (void), cm_unmacro (void);
+extern void cm_alias (void), cm_definfoenclose (void);
+
+extern int array_len (char **array);
+extern void free_array (char **array);
+extern char **get_brace_args (int quote_single);
#endif /* not MACRO_H */
diff --git a/contrib/texinfo/makeinfo/makeinfo.c b/contrib/texinfo/makeinfo/makeinfo.c
index a5e63fc..22ed4c4 100644
--- a/contrib/texinfo/makeinfo/makeinfo.c
+++ b/contrib/texinfo/makeinfo/makeinfo.c
@@ -1,8 +1,8 @@
/* makeinfo -- convert Texinfo source into other formats.
- $Id: makeinfo.c,v 1.34 2003/06/02 12:32:29 karl Exp $
+ $Id: makeinfo.c,v 1.74 2004/12/19 17:15:42 karl Exp $
Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- Makeinfo was authored by Brian Fox (bfox@ai.mit.edu). */
+ Original author of makeinfo: Brian Fox (bfox@ai.mit.edu). */
#include "system.h"
#include "getopt.h"
@@ -27,6 +27,7 @@
#include "makeinfo.h"
#include "cmds.h"
#include "files.h"
+#include "float.h"
#include "footnote.h"
#include "html.h"
#include "index.h"
@@ -34,6 +35,7 @@
#include "lang.h"
#include "macro.h"
#include "node.h"
+#include "sectioning.h"
#include "toc.h"
#include "xml.h"
@@ -69,10 +71,6 @@ char *output_filename = NULL;
char *command_output_filename = NULL;
static char *save_command_output_filename = NULL;
-/* Flags which control initial output string for xrefs. */
-int px_ref_flag = 0;
-int ref_flag = 0;
-
#define INITIAL_PARAGRAPH_SPACE 5000
int paragraph_buffer_len = INITIAL_PARAGRAPH_SPACE;
@@ -135,9 +133,16 @@ int do_justification = 0;
/* Nonzero means don't replace whitespace with &nbsp; in HTML mode. */
int in_html_elt = 0;
+/* Nonzero means we are inserting a block level HTML element that must not be
+ enclosed in a <p>, such as <ul>, <ol> and <h?>. */
+int in_html_block_level_elt = 0;
+
/* True when expanding a macro definition. */
static int executing_macro = 0;
+/* True when we are inside a <li> block of a menu. */
+static int in_menu_item = 0;
+
typedef struct brace_element
{
struct brace_element *next;
@@ -149,64 +154,44 @@ typedef struct brace_element
BRACE_ELEMENT *brace_stack = NULL;
-extern void do_multitable (), end_multitable ();
-
-void push_node_filename (), pop_node_filename ();
-void remember_error ();
-void convert_from_stream (), convert_from_file (), convert_from_loaded_file ();
-void init_internals (), init_paragraph (), init_brace_stack ();
-void init_insertion_stack (), init_indices ();
-void init_tag_table (), write_tag_table (), write_tag_table_internal ();
-void validate_file (), validate_other_references (), split_file ();
-void free_node_references (), handle_variable ();
-void handle_variable_internal ();
-void normalize_node_name ();
-void add_anchor_name ();
-void free_node_node_references (), remember_node_node_reference ();
-
-char **get_brace_args ();
-int array_len ();
-void free_array ();
-static int end_of_sentence_p ();
-void reader_loop ();
-void remember_brace (), remember_brace_1 ();
-void pop_and_call_brace (), discard_braces ();
-void add_word (), add_char (), insert (), flush_output ();
-void insert_string ();
-void close_paragraph ();
-void ignore_blank_line ();
-void do_flush_right_indentation (), discard_insertions ();
-void start_paragraph (), indent ();
-void inhibit_output_flushing (), uninhibit_output_flushing ();
-int set_paragraph_indent ();
-int self_delimiting (), search_forward ();
-int multitable_item (), number_of_node ();
-
-void me_execute_string_keep_state ();
-void maybe_update_execution_strings ();
-
-extern char *escape_string ();
-extern void insert_html_tag ();
-extern void sectioning_html ();
-
-#if defined (VA_FPRINTF) && __STDC__
-/* Unfortunately we must use prototypes if we are to use <stdarg.h>. */
-void add_word_args (const char *, ...);
-void execute_string (char *, ...);
-#else
-void add_word_args ();
-void execute_string ();
-#endif /* no prototypes */
+static void convert_from_file (char *name);
+static void convert_from_loaded_file (char *name);
+static void convert_from_stream (FILE *stream, char *name);
+static void do_flush_right_indentation (void);
+static void handle_variable (int action);
+static void handle_variable_internal (int action, char *name);
+static void init_brace_stack (void);
+static void init_internals (void);
+static void pop_and_call_brace (void);
+static void remember_brace (COMMAND_FUNCTION (*proc));
+static int end_of_sentence_p (void);
+
+void maybe_update_execution_strings (char **text, unsigned int new_len);
/* Error handling. */
/* Number of errors encountered. */
int errors_printed = 0;
+/* Remember that an error has been printed. If more than
+ max_error_level have been printed, then exit the program. */
+static void
+remember_error (void)
+{
+ errors_printed++;
+ if (max_error_level && (errors_printed > max_error_level))
+ {
+ fprintf (stderr, _("Too many errors! Gave up.\n"));
+ flush_file_stack ();
+ if (errors_printed - max_error_level < 2)
+ cm_bye ();
+ xexit (1);
+ }
+}
+
/* Print the last error gotten from the file system. */
int
-fs_error (filename)
- char *filename;
+fs_error (char *filename)
{
remember_error ();
perror (filename);
@@ -329,24 +314,9 @@ warning (format, va_alist)
}
-/* Remember that an error has been printed. If more than
- max_error_level have been printed, then exit the program. */
-void
-remember_error ()
-{
- errors_printed++;
- if (max_error_level && (errors_printed > max_error_level))
- {
- fprintf (stderr, _("Too many errors! Gave up.\n"));
- flush_file_stack ();
- cm_bye ();
- xexit (1);
- }
-}
-
/* The other side of a malformed expression. */
-void
-misplaced_brace ()
+static void
+misplaced_brace (void)
{
line_error (_("Misplaced %c"), '}');
}
@@ -355,7 +325,7 @@ misplaced_brace ()
/* Display the version info of this invocation of Makeinfo. */
static void
-print_version_info ()
+print_version_info (void)
{
printf ("makeinfo (GNU %s) %s\n", PACKAGE, VERSION);
}
@@ -364,8 +334,7 @@ print_version_info ()
Otherwise, just say to use --help for more info.
Then exit with EXIT_VALUE. */
static void
-usage (exit_value)
- int exit_value;
+usage (int exit_value)
{
if (exit_value != 0)
fprintf (stderr, _("Try `%s --help' for more information.\n"), progname);
@@ -389,14 +358,15 @@ General options:\n\
-v, --verbose explain what is being done.\n\
--version display version information and exit.\n"),
max_error_level, reference_warning_limit);
- puts ("\n");
+ puts ("");
/* xgettext: no-wrap */
puts (_("\
Output format selection (default is to produce Info):\n\
- --docbook output DocBook XML rather than Info.\n\
+ --docbook output Docbook XML rather than Info.\n\
--html output HTML rather than Info.\n\
--xml output Texinfo XML rather than Info.\n\
+ --plaintext output plain text rather than Info.\n\
"));
puts (_("\
@@ -428,7 +398,7 @@ Options for Info and plain text:\n\
--split-size=NUM split Info files at size NUM (default %d).\n"),
fill_column, paragraph_start_indent,
DEFAULT_SPLIT_SIZE);
- puts ("\n");
+ puts ("");
puts (_("\
Options for HTML:\n\
@@ -436,6 +406,13 @@ Options for HTML:\n\
read stdin if FILE is -.\n\
"));
+ printf (_("\
+Options for XML and Docbook:\n\
+ --output-indent=VAL indent XML elements by VAL spaces (default %d).\n\
+ If VAL is 0, ignorable whitespace is dropped.\n\
+"), xml_indentation_increment);
+ puts ("");
+
puts (_("\
Input file options:\n\
--commands-in-node-names allow @ commands in node names.\n\
@@ -447,16 +424,21 @@ Input file options:\n\
puts (_("\
Conditional processing in input:\n\
+ --ifdocbook process @ifdocbook and @docbook even if\n\
+ not generating Docbook.\n\
--ifhtml process @ifhtml and @html even if not generating HTML.\n\
--ifinfo process @ifinfo even if not generating Info.\n\
--ifplaintext process @ifplaintext even if not generating plain text.\n\
--iftex process @iftex and @tex; implies --no-split.\n\
--ifxml process @ifxml and @xml.\n\
+ --no-ifdocbook do not process @ifdocbook and @docbook text.\n\
--no-ifhtml do not process @ifhtml and @html text.\n\
--no-ifinfo do not process @ifinfo text.\n\
--no-ifplaintext do not process @ifplaintext text.\n\
--no-iftex do not process @iftex and @tex text.\n\
--no-ifxml do not process @ifxml and @xml text.\n\
+\n\
+ Also, for the --no-ifFORMAT options, do process @ifnotFORMAT text.\n\
"));
puts (_("\
@@ -502,6 +484,7 @@ struct option long_options[] =
{ "force", 0, &force, 1 },
{ "help", 0, 0, 'h' },
{ "html", 0, 0, 'w' },
+ { "ifdocbook", 0, &process_docbook, 1 },
{ "ifhtml", 0, &process_html, 1 },
{ "ifinfo", 0, &process_info, 1 },
{ "ifplaintext", 0, &process_plaintext, 1 },
@@ -509,6 +492,7 @@ struct option long_options[] =
{ "ifxml", 0, &process_xml, 1 },
{ "macro-expand", 1, 0, 'E' },
{ "no-headers", 0, &no_headers, 1 },
+ { "no-ifdocbook", 0, &process_docbook, 0 },
{ "no-ifhtml", 0, &process_html, 0 },
{ "no-ifinfo", 0, &process_info, 0 },
{ "no-ifplaintext", 0, &process_plaintext, 0 },
@@ -523,7 +507,9 @@ struct option long_options[] =
{ "number-footnotes", 0, &number_footnotes, 1 },
{ "number-sections", 0, &number_sections, 1 },
{ "output", 1, 0, 'o' },
+ { "output-indent", 1, 0, 'i' },
{ "paragraph-indent", 1, 0, 'p' },
+ { "plaintext", 0, 0, 't' },
{ "reference-limit", 1, 0, 'r' },
{ "split-size", 1, 0, 'S'},
{ "verbose", 0, &verbose_mode, 1 },
@@ -532,14 +518,24 @@ struct option long_options[] =
{NULL, 0, NULL, 0}
};
+/* We use handle_variable_internal for -D and -U, and it depends on
+ execute_string, which depends on input_filename, which is not defined
+ while we are handling options. :-\ So we save these defines in this
+ struct, and handle them later. */
+typedef struct command_line_define
+{
+ struct command_line_define *next;
+ int action;
+ char *define;
+} COMMAND_LINE_DEFINE;
+
+static COMMAND_LINE_DEFINE *command_line_defines = NULL;
+
/* For each file mentioned in the command line, process it, turning
Texinfo commands into wonderfully formatted output text. */
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
- extern int errors_printed;
int c, ind;
int reading_from_stdin = 0;
@@ -547,17 +543,69 @@ main (argc, argv)
/* Do not use LC_ALL, because LC_NUMERIC screws up the scanf parsing
of the argument to @multicolumn. */
setlocale (LC_TIME, "");
+#ifdef LC_MESSAGES /* ultrix */
setlocale (LC_MESSAGES, "");
+#endif
setlocale (LC_CTYPE, "");
setlocale (LC_COLLATE, "");
#endif
+#ifdef ENABLE_NLS
/* Set the text message domain. */
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
+#endif
+
+ /* If TEXINFO_OUTPUT_FORMAT envvar is set, use it to set default output.
+ Can be overridden with one of the output options. */
+ if (getenv ("TEXINFO_OUTPUT_FORMAT") != NULL)
+ {
+ if (STREQ (getenv ("TEXINFO_OUTPUT_FORMAT"), "docbook"))
+ {
+ splitting = 0;
+ html = 0;
+ docbook = 1;
+ xml = 1;
+ process_docbook = 1;
+ }
+ else if (STREQ (getenv ("TEXINFO_OUTPUT_FORMAT"), "html"))
+ {
+ html = 1;
+ docbook = 0;
+ xml = 0;
+ process_html = 1;
+ }
+ else if (STREQ (getenv ("TEXINFO_OUTPUT_FORMAT"), "info"))
+ {
+ html = 0;
+ docbook = 0;
+ xml = 0;
+ }
+ else if (STREQ (getenv ("TEXINFO_OUTPUT_FORMAT"), "plaintext"))
+ {
+ splitting = 0;
+ no_headers = 1;
+ html = 0;
+ docbook = 0;
+ xml = 0;
+ process_plaintext = 1;
+ }
+ else if (STREQ (getenv ("TEXINFO_OUTPUT_FORMAT"), "xml"))
+ {
+ splitting = 0;
+ html = 0;
+ docbook = 0;
+ xml = 1;
+ process_xml = 1;
+ }
+ else
+ fprintf (stderr,
+ _("%s: Ignoring unrecognized TEXINFO_OUTPUT_FORMAT value `%s'.\n"),
+ progname, getenv ("TEXINFO_OUTPUT_FORMAT"));
+ }
/* Parse argument flags from the input line. */
- while ((c = getopt_long (argc, argv, "D:de:E:f:hI:o:p:P:r:s:U:vV:wx",
+ while ((c = getopt_long (argc, argv, "D:de:E:f:hI:i:o:p:P:r:s:t:U:vV:wx",
long_options, &ind)) != EOF)
{
if (c == 0 && long_options[ind].flag == 0)
@@ -572,13 +620,24 @@ main (argc, argv)
case 'D':
case 'U':
/* User specified variable to set or clear. */
- handle_variable_internal ((c == 'D') ? SET : CLEAR, optarg);
+ if (xml && !docbook)
+ {
+ COMMAND_LINE_DEFINE *new = xmalloc (sizeof (COMMAND_LINE_DEFINE));
+ new->action = (c == 'D') ? SET : CLEAR;
+ new->define = xstrdup (optarg);
+ new->next = command_line_defines;
+ command_line_defines = new;
+ }
+ else
+ handle_variable_internal ((c == 'D' ? SET : CLEAR), optarg);
break;
case 'd': /* --docbook */
splitting = 0;
xml = 1;
docbook = 1;
+ html = 0;
+ process_docbook = 1;
break;
case 'e': /* --error-limit */
@@ -586,7 +645,7 @@ main (argc, argv)
{
fprintf (stderr,
_("%s: %s arg must be numeric, not `%s'.\n"),
- "--error-limit", progname, optarg);
+ progname, "--error-limit", optarg);
usage (1);
}
break;
@@ -598,10 +657,13 @@ main (argc, argv)
macro_expansion_output_stream
= strcmp (optarg, "-") == 0 ? stdout : fopen (optarg, "w");
if (!macro_expansion_output_stream)
- error (_("Couldn't open macro expansion output `%s'"), optarg);
+ error (_("%s: could not open macro expansion output `%s'"),
+ progname, optarg);
}
else
- error (_("Cannot specify more than one macro expansion output"));
+ fprintf (stderr,
+ _("%s: ignoring second macro expansion output `%s'.\n"),
+ progname, optarg);
break;
case 'f': /* --fill-column */
@@ -609,7 +671,7 @@ main (argc, argv)
{
fprintf (stderr,
_("%s: %s arg must be numeric, not `%s'.\n"),
- "--fill-column", progname, optarg);
+ progname, "--fill-column", optarg);
usage (1);
}
break;
@@ -620,14 +682,17 @@ main (argc, argv)
case 'I':
/* Append user-specified dir to include file path. */
- if (!include_files_path)
- include_files_path = xstrdup (".");
-
- include_files_path = (char *)
- xrealloc (include_files_path,
- 2 + strlen (include_files_path) + strlen (optarg));
- strcat (include_files_path, PATH_SEP);
- strcat (include_files_path, optarg);
+ append_to_include_path (optarg);
+ break;
+
+ case 'i':
+ if (sscanf (optarg, "%d", &xml_indentation_increment) != 1)
+ {
+ fprintf (stderr,
+ _("%s: %s arg must be numeric, not `%s'.\n"),
+ progname, "--output-indent", optarg);
+ usage (1);
+ }
break;
case 'o': /* --output */
@@ -647,23 +712,7 @@ main (argc, argv)
case 'P':
/* Prepend user-specified include dir to include path. */
- if (!include_files_path)
- {
- include_files_path = xstrdup (optarg);
- include_files_path = xrealloc (include_files_path,
- strlen (include_files_path) + 3); /* 3 for ":.\0" */
- strcat (strcat (include_files_path, PATH_SEP), ".");
- }
- else
- {
- char *tmp = xstrdup (include_files_path);
- include_files_path = xrealloc (include_files_path,
- strlen (include_files_path) + strlen (optarg) + 2); /* 2 for ":\0" */
- strcpy (include_files_path, optarg);
- strcat (include_files_path, ":");
- strcat (include_files_path, tmp);
- free (tmp);
- }
+ prepend_to_include_path (optarg);
break;
case 'r': /* --reference-limit */
@@ -671,7 +720,7 @@ main (argc, argv)
{
fprintf (stderr,
_("%s: %s arg must be numeric, not `%s'.\n"),
- "--reference-limit", progname, optarg);
+ progname, "--reference-limit", optarg);
usage (1);
}
break;
@@ -680,7 +729,7 @@ main (argc, argv)
if (set_footnote_style (optarg) < 0)
{
fprintf (stderr,
- _("%s: --footnote-style arg must be `separate' or `end', not `%s'.\n"),
+ _("%s: --footnote-style arg must be `separate' or `end', not `%s'.\n"),
progname, optarg);
usage (1);
}
@@ -692,11 +741,20 @@ main (argc, argv)
{
fprintf (stderr,
_("%s: %s arg must be numeric, not `%s'.\n"),
- "--split-size", progname, optarg);
+ progname, "--split-size", optarg);
usage (1);
}
break;
+ case 't': /* --plaintext */
+ splitting = 0;
+ no_headers = 1;
+ html = 0;
+ docbook = 0;
+ xml = 0;
+ process_plaintext = 1;
+ break;
+
case 'v':
verbose_mode++;
break;
@@ -704,21 +762,24 @@ main (argc, argv)
case 'V': /* --version */
print_version_info ();
puts ("");
- printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\
-There is NO warranty. You may redistribute this software\n\
+ puts ("Copyright (C) 2004 Free Software Foundation, Inc.");
+ printf (_("There is NO warranty. You may redistribute this software\n\
under the terms of the GNU General Public License.\n\
-For more information about these matters, see the files named COPYING.\n"),
- "2003");
+For more information about these matters, see the files named COPYING.\n"));
xexit (0);
break;
case 'w': /* --html */
+ xml = 0;
+ docbook = 0;
html = 1;
process_html = 1;
break;
case 'x': /* --xml */
splitting = 0;
+ html = 0;
+ docbook = 0;
xml = 1;
process_xml = 1;
break;
@@ -729,6 +790,9 @@ For more information about these matters, see the files named COPYING.\n"),
}
}
+ if (macro_expansion_output_stream)
+ validating = 0;
+
if (!validating)
expensive_validation = 0;
@@ -746,6 +810,10 @@ For more information about these matters, see the files named COPYING.\n"),
if (no_headers)
{
+ /* If the user did not specify an output file, use stdout. */
+ if (!command_output_filename)
+ command_output_filename = xstrdup ("-");
+
if (html && splitting && !STREQ (command_output_filename, "-"))
{ /* --no-headers --no-split --html indicates confusion. */
fprintf (stderr,
@@ -756,10 +824,6 @@ For more information about these matters, see the files named COPYING.\n"),
/* --no-headers implies --no-split. */
splitting = 0;
-
- /* If the user did not specify an output file, use stdout. */
- if (!command_output_filename)
- command_output_filename = xstrdup ("-");
}
if (process_info == -1)
@@ -790,7 +854,6 @@ For more information about these matters, see the files named COPYING.\n"),
xexit (errors_printed ? 2 : 0);
return 0; /* Avoid bogus warnings. */
}
-
/* Hacking tokens and strings. */
@@ -808,8 +871,8 @@ For more information about these matters, see the files named COPYING.\n"),
&& (c) != '^' \
)
-char *
-read_token ()
+static char *
+read_token (void)
{
int i, character;
char *result;
@@ -841,8 +904,7 @@ read_token ()
/* Return nonzero if CHARACTER is self-delimiting. */
int
-self_delimiting (character)
- int character;
+self_delimiting (int character)
{
/* @; and @\ are not Texinfo commands, but they are listed here
anyway. I don't know why. --karl, 10aug96. */
@@ -851,35 +913,35 @@ self_delimiting (character)
/* Clear whitespace from the front and end of string. */
void
-canon_white (string)
- char *string;
+canon_white (char *string)
{
- int len = strlen (string);
- int x;
+ char *p = string;
+ unsigned len;
- if (!len)
+ if (!*p)
return;
- for (x = 0; x < len; x++)
+ do
{
- if (!cr_or_whitespace (string[x]))
- {
- strcpy (string, string + x);
- break;
- }
+ if (!cr_or_whitespace (*p))
+ break;
+ ++p;
}
- len = strlen (string);
- if (len)
- len--;
- while (len > -1 && cr_or_whitespace (string[len]))
- len--;
- string[len + 1] = 0;
+ while (*p);
+
+ len = strlen (p);
+ while (len && cr_or_whitespace (p[len-1]))
+ --len;
+
+ if (p != string)
+ memmove (string, p, len);
+
+ string[len] = 0;
}
/* Bash STRING, replacing all whitespace with just one space. */
void
-fix_whitespace (string)
- char *string;
+fix_whitespace (char *string)
{
char *temp = xmalloc (strlen (string) + 1);
int string_index = 0;
@@ -909,8 +971,7 @@ fix_whitespace (string)
/* Discard text until the desired string is found. The string is
included in the discarded text. */
void
-discard_until (string)
- char *string;
+discard_until (char *string)
{
int temp = search_forward (string, input_text_offset);
@@ -924,18 +985,26 @@ discard_until (string)
if (temp < 0)
{
- input_text_offset = input_text_length - strlen (string);
-
+ /* not found, move current position to end of string */
+ input_text_offset = input_text_length;
if (strcmp (string, "\n") != 0)
- {
- line_error (_("Expected `%s'"), string);
+ { /* Give a more descriptive feedback, if we are looking for ``@end ''
+ during macro execution. That means someone used a multiline
+ command as an argument to, say, @section ... style commands. */
+ char *end_block = xmalloc (8);
+ sprintf (end_block, "\n%cend ", COMMAND_PREFIX);
+ if (executing_string && strstr (string, end_block))
+ line_error (_("Multiline command %c%s used improperly"),
+ COMMAND_PREFIX, command);
+ else
+ line_error (_("Expected `%s'"), string);
+ free (end_block);
return;
}
}
else
- input_text_offset = temp;
-
- input_text_offset += strlen (string);
+ /* found, move current position to after the found string */
+ input_text_offset = temp + strlen (string);
}
/* Read characters from the file until we are at MATCH.
@@ -943,8 +1012,7 @@ discard_until (string)
On exit input_text_offset is after the match string.
Return the offset where the string starts. */
int
-get_until (match, string)
- char *match, **string;
+get_until (char *match, char **string)
{
int len, current_point, x, new_point, tem;
@@ -977,8 +1045,7 @@ get_until (match, string)
/* Replace input_text[FROM .. TO] with its expansion. */
void
-replace_with_expansion (from, to)
- int from, *to;
+replace_with_expansion (int from, int *to)
{
char *xp;
unsigned xp_len, new_len;
@@ -1054,9 +1121,7 @@ replace_with_expansion (from, to)
expand the text before looking for MATCH for those cases where
MATCH might be produced by some macro. */
void
-get_until_in_line (expand, match, string)
- int expand;
- char *match, **string;
+get_until_in_line (int expand, char *match, char **string)
{
int real_bottom = input_text_length;
int limit = search_forward ("\n", input_text_offset);
@@ -1088,9 +1153,7 @@ get_until_in_line (expand, match, string)
}
void
-get_rest_of_line (expand, string)
- int expand;
- char **string;
+get_rest_of_line (int expand, char **string)
{
xml_no_para ++;
if (expand)
@@ -1121,7 +1184,7 @@ get_rest_of_line (expand, string)
/* Backup the input pointer to the previous character, keeping track
of the current line number. */
void
-backup_input_pointer ()
+backup_input_pointer (void)
{
if (input_text_offset)
{
@@ -1134,8 +1197,7 @@ backup_input_pointer ()
/* Read characters from the file until we are at MATCH or closing brace.
Place the characters read into STRING. */
void
-get_until_in_braces (match, string)
- char *match, **string;
+get_until_in_braces (char *match, char **string)
{
char *temp;
int i, brace = 0;
@@ -1192,8 +1254,8 @@ static char *suffixes[] = {
NULL
};
-void
-initialize_conversion ()
+static void
+initialize_conversion (void)
{
init_tag_table ();
init_indices ();
@@ -1207,16 +1269,11 @@ initialize_conversion ()
output_position = 0;
}
-typedef struct generic_list {
- struct generic_list *next;
-} GENERIC_LIST;
-
/* Reverse the chain of structures in LIST. Output the new head
of the chain. You should always assign the output value of this
function to something, or you will lose the chain. */
GENERIC_LIST *
-reverse_list (list)
- GENERIC_LIST *list;
+reverse_list (GENERIC_LIST *list)
{
GENERIC_LIST *next;
GENERIC_LIST *prev = NULL;
@@ -1237,10 +1294,8 @@ reverse_list (list)
/* Convert the Texinfo file coming from the open stream STREAM. Assume the
source of the stream is named NAME. */
-void
-convert_from_stream (stream, name)
- FILE *stream;
- char *name;
+static void
+convert_from_stream (FILE *stream, char *name)
{
char *buffer = NULL;
int buffer_offset = 0, buffer_size = 0;
@@ -1287,13 +1342,15 @@ convert_from_stream (stream, name)
convert_from_loaded_file (name);
}
-void
-convert_from_file (name)
- char *name;
+static void
+convert_from_file (char *name)
{
int i;
char *filename = xmalloc (strlen (name) + 50);
+ /* Prepend file directory to the search path, so relative links work. */
+ prepend_to_include_path (pathname_part (name));
+
initialize_conversion ();
/* Try to load the file specified by NAME, concatenated with our
@@ -1304,7 +1361,7 @@ convert_from_file (name)
strcpy (filename, name);
strcat (filename, suffixes[i]);
- if (find_and_load (filename))
+ if (find_and_load (filename, 1))
break;
if (!suffixes[i][0] && strrchr (filename, '.'))
@@ -1325,6 +1382,38 @@ convert_from_file (name)
input_filename = filename;
convert_from_loaded_file (name);
+
+ /* Pop the prepended path, so multiple filenames in the
+ command line do not screw each others include paths. */
+ pop_path_from_include_path ();
+}
+
+static int
+create_html_directory (char *dir, int can_remove_file)
+{
+ struct stat st;
+
+ /* Already exists. */
+ if (stat (dir, &st) == 0)
+ {
+ /* And it's a directory, so silently reuse it. */
+ if (S_ISDIR (st.st_mode))
+ return 1;
+ /* Not a directory, so move it out of the way if we are allowed. */
+ else if (can_remove_file)
+ {
+ if (unlink (dir) != 0)
+ return 0;
+ }
+ else
+ return 0;
+ }
+
+ if (mkdir (dir, 0777) == 0)
+ /* Success! */
+ return 1;
+ else
+ return 0;
}
/* Given OUTPUT_FILENAME == ``/foo/bar/baz.html'', return
@@ -1339,13 +1428,11 @@ convert_from_file (name)
foo.whatever unchanged. */
static char *
-insert_toplevel_subdirectory (output_filename)
- char *output_filename;
+insert_toplevel_subdirectory (char *output_filename)
{
static const char index_name[] = "index.html";
char *dir, *subdir, *base, *basename, *p;
char buf[PATH_MAX];
- struct stat st;
const int index_len = sizeof (index_name) - 1;
strcpy (buf, output_filename);
@@ -1375,41 +1462,34 @@ insert_toplevel_subdirectory (output_filename)
if (strlen (dir))
strcat (output_filename, "/");
strcat (output_filename, subdir);
- if ((mkdir (output_filename, 0777) == -1 && errno != EEXIST)
- /* output_filename might exist, but be a non-directory. */
- || (stat (output_filename, &st) == 0 && !S_ISDIR (st.st_mode)))
- { /* that failed, try subdir name with .html */
+
+ /* First try, do not remove existing file. */
+ if (!create_html_directory (output_filename, 0))
+ {
+ /* That failed, try subdir name with .html.
+ Remove it if it exists. */
strcpy (output_filename, dir);
if (strlen (dir))
strcat (output_filename, "/");
strcat (output_filename, basename);
- if (mkdir (output_filename, 0777) == -1)
- {
- const char *errmsg = strerror (errno);
- if ((errno == EEXIST
-#ifdef __MSDOS__
- || errno == EACCES
-#endif
- )
- && (stat (output_filename, &st) == 0 && !S_ISDIR (st.st_mode)))
- errmsg = _("File exists, but is not a directory");
+ if (!create_html_directory (output_filename, 1))
+ {
+ /* Last try failed too :-\ */
line_error (_("Can't create directory `%s': %s"),
- output_filename, errmsg);
+ output_filename, strerror (errno));
xexit (1);
}
- strcat (output_filename, "/");
}
- else if (strlen (subdir))
- strcat (output_filename, "/");
+
+ strcat (output_filename, "/");
strcat (output_filename, index_name);
return output_filename;
}
/* FIXME: this is way too hairy */
-void
-convert_from_loaded_file (name)
- char *name;
+static void
+convert_from_loaded_file (char *name)
{
char *real_output_filename = NULL;
@@ -1476,8 +1556,6 @@ convert_from_loaded_file (name)
if (!command_output_filename)
{
get_until ("\n", &output_filename); /* read rest of line */
- if (xml && !docbook)
- xml_begin_document (output_filename);
if (html || xml)
{ /* Change any extension to .html or .xml. */
char *html_name, *directory_part, *basename_part, *temp;
@@ -1553,6 +1631,9 @@ convert_from_loaded_file (name)
set_current_output_filename (real_output_filename);
+ if (xml && !docbook)
+ xml_begin_document (filename_part (output_filename));
+
if (verbose_mode)
printf (_("Making %s file `%s' from `%s'.\n"),
no_headers ? "text"
@@ -1593,6 +1674,19 @@ convert_from_loaded_file (name)
output_filename, VERSION, input_filename);
close_paragraph ();
+
+ if (xml && !docbook)
+ {
+ /* Just before the real main loop, let's handle the defines. */
+ COMMAND_LINE_DEFINE *temp;
+
+ for (temp = command_line_defines; temp; temp = temp->next)
+ {
+ handle_variable_internal (temp->action, temp->define);
+ free(temp->define);
+ }
+ }
+
reader_loop ();
if (xml)
xml_end_document ();
@@ -1611,7 +1705,8 @@ finished:
&& FILENAME_CMP (macro_expansion_filename, NULL_DEVICE) != 0
&& FILENAME_CMP (macro_expansion_filename, ALSO_NULL_DEVICE) != 0)
{
- fprintf (stderr, _("%s: Removing macro output file `%s' due to errors; use --force to preserve.\n"),
+ fprintf (stderr,
+_("%s: Removing macro output file `%s' due to errors; use --force to preserve.\n"),
progname, macro_expansion_filename);
if (unlink (macro_expansion_filename) < 0)
perror (macro_expansion_filename);
@@ -1621,15 +1716,10 @@ finished:
if (output_stream)
{
output_pending_notes ();
- if (tag_table)
- {
- tag_table = (TAG_ENTRY *) reverse_list (tag_table);
- if (!no_headers && !html)
- write_tag_table ();
- }
if (html)
{
+ no_indent = 1;
start_paragraph ();
add_word ("</body></html>\n");
close_paragraph ();
@@ -1638,14 +1728,19 @@ finished:
/* maybe we want local variables in info output. */
{
char *trailer = info_trailer ();
- if (trailer)
+ if (!xml && !docbook && trailer)
{
+ if (html)
+ insert_string ("<!--");
insert_string (trailer);
free (trailer);
+ if (html)
+ insert_string ("\n-->\n");
}
}
- flush_output (); /* in case there was no @bye */
+ /* Write stuff makeinfo generates after @bye, ie. info_trailer. */
+ flush_output ();
if (output_stream != stdout)
fclose (output_stream);
@@ -1654,19 +1749,28 @@ finished:
if (validating)
validate_file (tag_table);
- /* If we need to output the table of contents, do it now. */
- if (contents_filename || shortcontents_filename)
- toc_update ();
+ handle_delayed_writes ();
+
+ if (tag_table)
+ {
+ tag_table = (TAG_ENTRY *) reverse_list ((GENERIC_LIST *) tag_table);
+ if (!no_headers && !html && !STREQ (current_output_filename, "-"))
+ write_tag_table (real_output_filename);
+ }
if (splitting && !html && (!errors_printed || force))
- split_file (real_output_filename, split_size);
+ {
+ clean_old_split_files (real_output_filename);
+ split_file (real_output_filename, split_size);
+ }
else if (errors_printed
&& !force
&& strcmp (real_output_filename, "-") != 0
&& FILENAME_CMP (real_output_filename, NULL_DEVICE) != 0
&& FILENAME_CMP (real_output_filename, ALSO_NULL_DEVICE) != 0)
{ /* If there were errors, and no --force, remove the output. */
- fprintf (stderr, _("%s: Removing output file `%s' due to errors; use --force to preserve.\n"),
+ fprintf (stderr,
+ _("%s: Removing output file `%s' due to errors; use --force to preserve.\n"),
progname, real_output_filename);
if (unlink (real_output_filename) < 0)
perror (real_output_filename);
@@ -1674,33 +1778,35 @@ finished:
}
free (real_output_filename);
}
-
-
-/* If enable_encoding and document_encoding are both set, return a Local
- Variables section (as a malloc-ed string) so that Emacs' locale
- features can work. Else return NULL. */
-
+/* If enable_encoding is set and @documentencoding is used, return a
+ Local Variables section (as a malloc-ed string) so that Emacs'
+ locale features can work. Else return NULL. */
char *
-info_trailer ()
+info_trailer (void)
{
- if (!enable_encoding || document_encoding_code <= US_ASCII)
+ char *encoding;
+
+ if (!enable_encoding)
return NULL;
- {
-#define LV_FMT "\n\037\nLocal Variables:\ncoding: %s\nEnd:\n"
- char *enc_name = encoding_table[document_encoding_code].encname;
- char *lv = xmalloc (sizeof (LV_FMT) + strlen (enc_name));
- sprintf (lv, LV_FMT, enc_name);
- return lv;
- }
-}
+ encoding = current_document_encoding ();
+ if (encoding && *encoding)
+ {
+#define LV_FMT "\n\037\nLocal Variables:\ncoding: %s\nEnd:\n"
+ char *lv = xmalloc (sizeof (LV_FMT) + strlen (encoding));
+ sprintf (lv, LV_FMT, encoding);
+ free (encoding);
+ return lv;
+ }
+ free (encoding);
+ return NULL;
+}
void
-free_and_clear (pointer)
- char **pointer;
+free_and_clear (char **pointer)
{
if (*pointer)
{
@@ -1710,8 +1816,8 @@ free_and_clear (pointer)
}
/* Initialize some state. */
-void
-init_internals ()
+static void
+init_internals (void)
{
free_and_clear (&output_filename);
free_and_clear (&command);
@@ -1731,9 +1837,9 @@ init_internals ()
}
void
-init_paragraph ()
+init_paragraph (void)
{
- free_and_clear (&output_paragraph);
+ free (output_paragraph);
output_paragraph = xmalloc (paragraph_buffer_len);
output_paragraph[0] = 0;
output_paragraph_offset = 0;
@@ -1747,7 +1853,7 @@ init_paragraph ()
menu line. */
static void
-handle_menu_entry ()
+handle_menu_entry (void)
{
char *tem;
@@ -1773,23 +1879,21 @@ handle_menu_entry ()
if (had_menu_commentary)
{
- add_word ("<ul class=\"menu\">\n");
+ add_html_block_elt ("<ul class=\"menu\">\n");
had_menu_commentary = 0;
in_paragraph = 0;
}
- else if (!in_paragraph && !paragraph_is_open)
- {
- add_word ("<p>\n");
- in_paragraph = 1;
- }
if (in_paragraph)
{
- add_word ("</p>");
+ add_html_block_elt ("</p>\n");
+ add_html_block_elt ("<ul class=\"menu\">\n");
in_paragraph = 0;
}
- add_word ("<li><a");
+ in_menu_item = 1;
+
+ add_html_block_elt ("<li><a");
if (next_menu_item_number <= 9)
{
add_word(" accesskey=");
@@ -1819,7 +1923,18 @@ handle_menu_entry ()
free (string);
}
input_text_offset++; /* discard the second colon or the period */
- add_word (": ");
+
+ /* Insert a colon only if there is a description of this menu item. */
+ {
+ int save_input_text_offset = input_text_offset;
+ int save_line_number = line_number;
+ char *test_string;
+ get_rest_of_line (0, &test_string);
+ if (strlen (test_string) > 0)
+ add_word (": ");
+ input_text_offset = save_input_text_offset;
+ line_number = save_line_number;
+ }
}
else if (xml && tem)
{
@@ -1840,8 +1955,7 @@ handle_menu_entry ()
/* Find the command corresponding to STRING. If the command is found,
return a pointer to the data structure. Otherwise return -1. */
static COMMAND *
-get_command_entry (string)
- char *string;
+get_command_entry (char *string)
{
int i;
@@ -1864,7 +1978,7 @@ get_command_entry (string)
Read the next token to determine what to do. Return zero
if there's no known command or macro after the prefix character. */
static int
-read_command ()
+read_command (void)
{
COMMAND *entry;
int old_text_offset = input_text_offset++;
@@ -1894,7 +2008,7 @@ read_command ()
return 1;
}
- }
+ }
if (only_macro_expansion)
{
@@ -1970,11 +2084,10 @@ read_command ()
the function with the proper arguments. Although the filling isn't
necessary for HTML, it should do no harm. */
void
-reader_loop ()
+reader_loop (void)
{
int character;
int done = 0;
- int dash_count = 0;
while (!done)
{
@@ -1986,25 +2099,79 @@ reader_loop ()
/* If only_macro_expansion, only handle macros and leave
everything else intact. */
if (!only_macro_expansion && !in_fixed_width_font
+ && ((!html && !xml) || escape_html)
&& (character == '\'' || character == '`')
&& input_text[input_text_offset + 1] == character)
{
- input_text_offset++;
- character = '"'; /* html fixxme */
+ if (html)
+ {
+ input_text_offset += 2;
+ add_word (character == '`' ? "&ldquo;" : "&rdquo;");
+ continue;
+ }
+ else if (xml)
+ {
+ input_text_offset += 2;
+ xml_insert_entity (character == '`' ? "ldquo" : "rdquo");
+ continue;
+ }
+ else
+ {
+ input_text_offset++;
+ character = '"';
+ }
}
/* Convert --- to --. */
- if (!only_macro_expansion && character == '-')
+ if (!only_macro_expansion && character == '-' && !in_fixed_width_font
+ && ((!html && !xml) || escape_html))
{
- dash_count++;
- if (dash_count == 2 && !in_fixed_width_font)
+ int dash_count = 0;
+
+ /* Get the number of consequtive dashes. */
+ while (input_text[input_text_offset] == '-')
{
+ dash_count++;
input_text_offset++;
- continue;
}
+
+ /* Eat one dash. */
+ dash_count--;
+
+ if (html || xml)
+ {
+ if (dash_count == 0)
+ add_char ('-');
+ else
+ while (dash_count > 0)
+ {
+ if (dash_count >= 2)
+ {
+ if (html)
+ add_word ("&mdash;");
+ else
+ xml_insert_entity ("mdash");
+ dash_count -= 2;
+ }
+ else if (dash_count >= 1)
+ {
+ if (html)
+ add_word ("&ndash;");
+ else
+ xml_insert_entity ("ndash");
+ dash_count--;
+ }
+ }
+ }
+ else
+ {
+ add_char ('-');
+ while (--dash_count > 0)
+ add_char ('-');
+ }
+
+ continue;
}
- else if (dash_count > 0)
- dash_count = 0;
/* If this is a whitespace character, then check to see if the line
is blank. If so, advance to the carriage return. */
@@ -2094,10 +2261,8 @@ reader_loop ()
remember_brace (misplaced_brace);
}
else
- { /* We don't mind `extra' braces inside @math. */
- extern void cm_no_op ();
- remember_brace (cm_no_op);
- }
+ /* We don't mind `extra' braces inside @math. */
+ remember_brace (cm_no_op);
/* remember_brace advances input_text_offset. */
break;
}
@@ -2121,29 +2286,16 @@ reader_loop ()
maybe_write_itext (input_text, input_text_offset);
}
-void
-init_brace_stack ()
+static void
+init_brace_stack (void)
{
brace_stack = NULL;
}
-void
-remember_brace (proc)
- COMMAND_FUNCTION *proc;
-{
- if (curchar () != '{')
- line_error (_("%c%s expected braces"), COMMAND_PREFIX, command);
- else
- input_text_offset++;
- remember_brace_1 (proc, output_paragraph_offset);
-}
-
/* Remember the current output position here. Save PROC
along with it so you can call it later. */
-void
-remember_brace_1 (proc, position)
- COMMAND_FUNCTION *proc;
- int position;
+static void
+remember_brace_1 (COMMAND_FUNCTION (*proc), int position)
{
BRACE_ELEMENT *new = xmalloc (sizeof (BRACE_ELEMENT));
new->next = brace_stack;
@@ -2155,10 +2307,20 @@ remember_brace_1 (proc, position)
brace_stack = new;
}
+static void
+remember_brace (COMMAND_FUNCTION (*proc))
+{
+ if (curchar () != '{')
+ line_error (_("%c%s expected braces"), COMMAND_PREFIX, command);
+ else
+ input_text_offset++;
+ remember_brace_1 (proc, output_paragraph_offset);
+}
+
/* Pop the top of the brace stack, and call the associated function
with the args END and POS. */
-void
-pop_and_call_brace ()
+static void
+pop_and_call_brace (void)
{
if (brace_stack == NULL)
{
@@ -2186,9 +2348,8 @@ pop_and_call_brace ()
}
/* Shift all of the markers in `brace_stack' by AMOUNT. */
-void
-adjust_braces_following (here, amount)
- int here, amount;
+static void
+adjust_braces_following (int here, int amount)
{
BRACE_ELEMENT *stack = brace_stack;
@@ -2204,8 +2365,7 @@ adjust_braces_following (here, amount)
Always returns the first function in the command table if more than
one matches PROC. */
static const char *
-find_proc_name (proc)
- COMMAND_FUNCTION *proc;
+find_proc_name (COMMAND_FUNCTION (*proc))
{
int i;
@@ -2220,7 +2380,7 @@ find_proc_name (proc)
in braces, but that was wrong because of things like @code{foo @@}. So now
I only detect it at the beginning of nodes. */
void
-discard_braces ()
+discard_braces (void)
{
if (!brace_stack)
return;
@@ -2247,9 +2407,8 @@ discard_braces ()
}
}
-int
-get_char_len (character)
- int character;
+static int
+get_char_len (int character)
{
/* Return the printed length of the character. */
int len;
@@ -2307,8 +2466,7 @@ add_word_args (format, va_alist)
/* Add STRING to output_paragraph. */
void
-add_word (string)
- char *string;
+add_word (char *string)
{
while (*string)
add_char (*string++);
@@ -2318,14 +2476,49 @@ add_word (string)
Use this to output HTML directives with embedded blanks, to make
them @w-safe. */
void
-add_html_elt (string)
- char *string;
+add_html_elt (char *string)
{
in_html_elt++;
add_word (string);
in_html_elt--;
}
+/* These two functions below, add_html_block_elt and add_html_block_elt_args,
+ are mixtures of add_html_elt and add_word_args. They inform makeinfo that
+ the current HTML element being inserted should not be enclosed in a <p>
+ element. */
+void
+add_html_block_elt (char *string)
+{
+ in_html_block_level_elt++;
+ add_word (string);
+ in_html_block_level_elt--;
+}
+
+void
+#if defined (VA_FPRINTF) && __STDC__
+add_html_block_elt_args (const char *format, ...)
+#else
+add_html_block_elt_args (format, va_alist)
+ const char *format;
+ va_dcl
+#endif
+{
+ char buffer[2000]; /* xx no fixed limits */
+#ifdef VA_FPRINTF
+ va_list ap;
+#endif
+
+ VA_START (ap, format);
+#ifdef VA_SPRINTF
+ VA_SPRINTF (buffer, format, ap);
+#else
+ sprintf (buffer, format, a1, a2, a3, a4, a5, a6, a7, a8);
+#endif /* not VA_SPRINTF */
+ va_end (ap);
+ add_html_block_elt (buffer);
+}
+
/* Here is another awful kludge, used in add_char. Ordinarily, macro
expansions take place in the body of the document, and therefore we
should html_output_head when we see one. But there's an exception: a
@@ -2335,7 +2528,7 @@ add_html_elt (string)
So we need to be able to check if we are defining the @copying text.
We do this by looking back through the insertion stack. */
static int
-defining_copying ()
+defining_copying (void)
{
INSERTION_ELT *i;
for (i = insertion_stack; i; i = i->next)
@@ -2350,8 +2543,7 @@ defining_copying ()
/* Add the character to the current paragraph. If filling_enabled is
nonzero, then do filling as well. */
void
-add_char (character)
- int character;
+add_char (int character)
{
if (xml)
{
@@ -2463,6 +2655,7 @@ add_char (character)
any order and with any omissions, and we'll still output
the html <head> `just in time'. */
if ((executing_macro || !executing_string)
+ && !only_macro_expansion
&& html && !html_output_head_p && !defining_copying ())
html_output_head ();
@@ -2476,12 +2669,16 @@ add_char (character)
indent (pending_indent);
pending_indent = 0;
- /* This horrible kludge of checking for a < prevents <p>
- from being inserted when we already have html markup
- starting a paragraph, as with <ul> and <h1> and the like. */
- if ((html || xml) && escape_html && character != '<'
- && (!in_fixed_width_font || in_menu || in_detailmenu))
+ /* This check for in_html_block_level_elt prevents <p> from being
+ inserted when we already have html markup starting a paragraph,
+ as with <ul> and <h1> and the like. */
+ if (html && !in_html_block_level_elt)
{
+ if ((in_menu || in_detailmenu) && in_menu_item)
+ {
+ insert_string ("</li></ul>\n");
+ in_menu_item = 0;
+ }
insert_string ("<p>");
in_paragraph = 1;
adjust_braces_following (0, 3); /* adjust for <p> */
@@ -2536,9 +2733,9 @@ add_char (character)
if (t1 != temp)
{
adjust_braces_following (temp, (- (t1 - temp)));
- strncpy ((char *) &output_paragraph[temp],
- (char *) &output_paragraph[t1],
- (output_paragraph_offset - t1));
+ memmove (&output_paragraph[temp],
+ &output_paragraph[t1],
+ output_paragraph_offset - t1);
output_paragraph_offset -= (t1 - temp);
}
}
@@ -2600,8 +2797,7 @@ add_char (character)
/* Add a character and store its position in meta_char_pos. */
void
-add_meta_char (character)
- int character;
+add_meta_char (int character)
{
meta_char_pos = output_paragraph_offset;
add_char (character);
@@ -2609,9 +2805,19 @@ add_meta_char (character)
/* Insert CHARACTER into `output_paragraph'. */
void
-insert (character)
- int character;
+insert (int character)
{
+ /* We don't want to strip trailing whitespace in multitables. Otherwise
+ horizontal separators confuse the font locking in Info mode in Emacs,
+ because it looks like a @subsection. Adding a trailing space to those
+ lines fixes it. */
+ if (character == '\n' && !html && !xml && !multitable_active)
+ {
+ while (output_paragraph_offset
+ && whitespace (output_paragraph[output_paragraph_offset-1]))
+ output_paragraph_offset--;
+ }
+
output_paragraph[output_paragraph_offset++] = character;
if (output_paragraph_offset == paragraph_buffer_len)
{
@@ -2622,8 +2828,7 @@ insert (character)
/* Insert the null-terminated string STRING into `output_paragraph'. */
void
-insert_string (string)
- char *string;
+insert_string (const char *string)
{
while (*string)
insert (*string++);
@@ -2637,7 +2842,7 @@ insert_string (string)
/* Return true if at an end-of-sentence character, possibly followed by
post-sentence punctuation to ignore. */
static int
-end_of_sentence_p ()
+end_of_sentence_p (void)
{
int loc = output_paragraph_offset - 1;
@@ -2660,8 +2865,7 @@ end_of_sentence_p ()
the current output line. If COUNT is less than zero,
then remove until none left. */
void
-kill_self_indent (count)
- int count;
+kill_self_indent (int count)
{
/* Handle infinite case first. */
if (count < 0)
@@ -2690,20 +2894,20 @@ static int flushing_ignored = 0;
/* Prevent calls to flush_output () from having any effect. */
void
-inhibit_output_flushing ()
+inhibit_output_flushing (void)
{
flushing_ignored++;
}
/* Allow calls to flush_output () to write the paragraph data. */
void
-uninhibit_output_flushing ()
+uninhibit_output_flushing (void)
{
flushing_ignored--;
}
void
-flush_output ()
+flush_output (void)
{
int i;
@@ -2712,6 +2916,12 @@ flush_output ()
for (i = 0; i < output_paragraph_offset; i++)
{
+ if (output_paragraph[i] == '\n')
+ {
+ output_line_number++;
+ node_line_number++;
+ }
+
/* If we turned on the 8th bit for a space inside @w, turn it
back off for output. This might be problematic, since the
0x80 character may be used in 8-bit character sets. Sigh.
@@ -2741,8 +2951,7 @@ flush_output ()
int paragraph_spacing = DEFAULT_PARAGRAPH_SPACING;
static void
-close_paragraph_with_lines (lines)
- int lines;
+close_paragraph_with_lines (int lines)
{
int old_spacing = paragraph_spacing;
paragraph_spacing = lines;
@@ -2752,14 +2961,14 @@ close_paragraph_with_lines (lines)
/* Close the current paragraph, leaving no blank lines between them. */
void
-close_single_paragraph ()
+close_single_paragraph (void)
{
close_paragraph_with_lines (0);
}
/* Close a paragraph after an insertion has ended. */
void
-close_insertion_paragraph ()
+close_insertion_paragraph (void)
{
if (!insertion_paragraph_closed)
{
@@ -2795,18 +3004,21 @@ close_insertion_paragraph ()
/* Close the currently open paragraph. */
void
-close_paragraph ()
+close_paragraph (void)
{
int i;
+ /* We don't need these newlines in XML and Docbook outputs for
+ paragraph seperation. We have <para> element for that. */
+ if (xml)
+ return;
+
/* The insertion paragraph is no longer closed. */
insertion_paragraph_closed = 0;
if (paragraph_is_open && !must_start_paragraph)
{
- int tindex, c;
-
- tindex = output_paragraph_offset;
+ int tindex = output_paragraph_offset;
/* Back up to last non-newline/space character, forcing all such
subsequent characters to be newlines. This isn't strictly
@@ -2814,7 +3026,7 @@ close_paragraph ()
to make decisions. */
for (tindex = output_paragraph_offset - 1; tindex >= 0; --tindex)
{
- c = output_paragraph[tindex];
+ int c = output_paragraph[tindex];
if (c == ' '|| c == '\n')
output_paragraph[tindex] = '\n';
@@ -2858,15 +3070,15 @@ close_paragraph ()
/* Make the last line just read look as if it were only a newline. */
void
-ignore_blank_line ()
+ignore_blank_line (void)
{
last_inserted_character = '\n';
last_char_was_newline = 1;
}
/* Align the end of the text in output_paragraph with fill_column. */
-void
-do_flush_right_indentation ()
+static void
+do_flush_right_indentation (void)
{
char *temp;
int temp_len;
@@ -2903,7 +3115,7 @@ do_flush_right_indentation ()
/* Begin a new paragraph. */
void
-start_paragraph ()
+start_paragraph (void)
{
/* First close existing one. */
if (paragraph_is_open)
@@ -2950,8 +3162,7 @@ start_paragraph ()
/* Insert the indentation specified by AMOUNT. */
void
-indent (amount)
- int amount;
+indent (int amount)
{
/* For every START_POS saved within the brace stack which will be affected
by this indentation, bump that start pos forward. */
@@ -2964,9 +3175,7 @@ indent (amount)
/* Search forward for STRING in input_text.
FROM says where where to start. */
int
-search_forward (string, from)
- char *string;
- int from;
+search_forward (char *string, int from)
{
int len = strlen (string);
@@ -2978,518 +3187,64 @@ search_forward (string, from)
}
return -1;
}
-
-/* Cross references. */
-
-/* Return next comma-delimited argument, but do not cross a close-brace
- boundary. Clean up whitespace, too. If EXPAND is nonzero, replace
- the entire brace-delimited argument list with its expansion before
- looking for the next comma. */
-char *
-get_xref_token (expand)
- int expand;
-{
- char *string;
-
- if (docbook)
- xml_in_xref_token = 1;
-
- if (expand)
- {
- int old_offset = input_text_offset;
- int old_lineno = line_number;
-
- get_until_in_braces ("}", &string);
- if (curchar () == '}') /* as opposed to end of text */
- input_text_offset++;
- if (input_text_offset > old_offset)
- {
- int limit = input_text_offset;
-
- input_text_offset = old_offset;
- line_number = old_lineno;
- only_macro_expansion++;
- replace_with_expansion (input_text_offset, &limit);
- only_macro_expansion--;
- }
- free (string);
- }
-
- get_until_in_braces (",", &string);
- if (curchar () == ',')
- input_text_offset++;
- fix_whitespace (string);
-
- if (docbook)
- xml_in_xref_token = 0;
-
- return string;
-}
-/* NOTE: If you wonder why the HTML output is produced with such a
- peculiar mix of calls to add_word and execute_string, here's the
- reason. get_xref_token (1) expands all macros in a reference, but
- any other commands, like @value, @@, etc., are left intact. To
- expand them, we need to run the arguments through execute_string.
- However, characters like <, &, > and others cannot be let into
- execute_string, because they will be escaped. See the mess? */
-
-/* Make a cross reference. */
-void
-cm_xref (arg)
+/* search_forward until n characters. */
+int
+search_forward_until_pos (char *string, int from, int end_pos)
{
- if (arg == START)
- {
- char *arg1 = get_xref_token (1); /* expands all macros in xref */
- char *arg2 = get_xref_token (0);
- char *arg3 = get_xref_token (0);
- char *arg4 = get_xref_token (0);
- char *arg5 = get_xref_token (0);
- char *tem;
-
- /* "@xref{,Foo,, Bar, Baz} is not valid usage of @xref. The
- first argument must never be blank." --rms.
- We hereby comply by disallowing such constructs. */
- if (!*arg1)
- line_error (_("First argument to cross-reference may not be empty"));
-
- if (xml && docbook)
- {
- if (!*arg4 && !*arg5)
- {
- char *arg1_id = xml_id (arg1);
- if (*arg2)
- {
- xml_insert_element_with_attribute (XREFNODENAME, START,
- "linkend=\"%s\"", arg1_id);
- free (arg1_id);
- if (*arg2)
- execute_string (arg2);
- xml_insert_element (XREFNODENAME, END);
- }
- else
- {
- xml_insert_element_with_attribute (XREF, START,
- "linkend=\"%s\"", arg1_id);
- free (arg1_id);
- xml_pop_current_element ();
- }
- }
- }
- else if (xml)
- {
- xml_insert_element (XREF, START);
- xml_insert_element (XREFNODENAME, START);
- execute_string (arg1);
- xml_insert_element (XREFNODENAME, END);
- if (*arg2)
- {
- xml_insert_element (XREFINFONAME, START);
- execute_string (arg2);
- xml_insert_element (XREFINFONAME, END);
- }
- if (*arg3)
- {
- xml_insert_element (XREFPRINTEDDESC, START);
- execute_string (arg3);
- xml_insert_element (XREFPRINTEDDESC, END);
- }
- if (*arg4)
- {
- xml_insert_element (XREFINFOFILE, START);
- execute_string (arg4);
- xml_insert_element (XREFINFOFILE, END);
- }
- if (*arg5)
- {
- xml_insert_element (XREFPRINTEDNAME, START);
- execute_string (arg5);
- xml_insert_element (XREFPRINTEDNAME, END);
- }
- xml_insert_element (XREF, END);
- }
- else if (html)
- {
- if (!ref_flag)
- add_word_args ("%s", px_ref_flag ? _("see ") : _("See "));
- }
- else
- add_word_args ("%s", px_ref_flag ? "*note " : "*Note ");
-
- if (!xml)
- {
- if (*arg5 || *arg4)
- {
- /* arg1 - node name
- arg2 - reference name
- arg3 - title or topic (and reference name if arg2 is NULL)
- arg4 - info file name
- arg5 - printed manual title */
- char *ref_name;
-
- if (!*arg2)
- {
- if (*arg3)
- ref_name = arg3;
- else
- ref_name = arg1;
- }
- else
- ref_name = arg2;
-
- if (html)
- {
- /* html fixxme: revisit this; external node name not
- much use to us with numbered nodes. */
- add_html_elt ("<a href=");
- /* Note that if we are splitting, and the referenced
- tag is an anchor rather than a node, we will
- produce a reference to a file whose name is
- derived from the anchor name. However, only
- nodes create files, so we are referencing a
- non-existent file. cm_anchor, which see, deals
- with that problem. */
- if (splitting)
- execute_string ("\"../%s/", arg4);
- else
- execute_string ("\"%s.html", arg4);
- /* Do not collapse -- to -, etc., in references. */
- in_fixed_width_font++;
- tem = expansion (arg1, 0); /* expand @-commands in node */
- in_fixed_width_font--;
- add_anchor_name (tem, 1);
- free (tem);
- add_word ("\">");
- execute_string ("%s", ref_name);
- add_word ("</a>");
- }
- else
- {
- execute_string ("%s:", ref_name);
- in_fixed_width_font++;
- execute_string (" (%s)%s%s", arg4, arg1, px_ref_flag ? "." : "");
- in_fixed_width_font--;
- }
+ int save_input_text_length = input_text_length;
+ input_text_length = end_pos;
- /* Free all of the arguments found. */
- if (arg1) free (arg1);
- if (arg2) free (arg2);
- if (arg3) free (arg3);
- if (arg4) free (arg4);
- if (arg5) free (arg5);
- return;
- }
- else
- remember_node_reference (arg1, line_number, followed_reference);
+ from = search_forward (string, from);
- if (*arg3)
- {
- if (html)
- {
- add_html_elt ("<a href=\"");
- in_fixed_width_font++;
- tem = expansion (arg1, 0);
- in_fixed_width_font--;
- add_anchor_name (tem, 1);
- free (tem);
- add_word ("\">");
- execute_string ("%s", *arg2 ? arg2 : arg3);
- add_word ("</a>");
- }
- else
- {
- execute_string ("%s:", *arg2 ? arg2 : arg3);
- in_fixed_width_font++;
- execute_string (" %s%s", arg1, px_ref_flag ? "." : "");
- in_fixed_width_font--;
- }
- }
- else
- {
- if (html)
- {
- add_html_elt ("<a href=\"");
- in_fixed_width_font++;
- tem = expansion (arg1, 0);
- in_fixed_width_font--;
- add_anchor_name (tem, 1);
- free (tem);
- add_word ("\">");
- execute_string ("%s", *arg2 ? arg2 : arg1);
- add_word ("</a>");
- }
- else
- {
- if (*arg2)
- {
- execute_string ("%s:", arg2);
- in_fixed_width_font++;
- execute_string (" %s%s", arg1, px_ref_flag ? "." : "");
- in_fixed_width_font--;
- }
- else
- {
- in_fixed_width_font++;
- execute_string ("%s::", arg1);
- in_fixed_width_font--;
- }
- }
- }
- }
- /* Free all of the arguments found. */
- if (arg1) free (arg1);
- if (arg2) free (arg2);
- if (arg3) free (arg3);
- if (arg4) free (arg4);
- if (arg5) free (arg5);
- }
- else
- { /* Check to make sure that the next non-whitespace character is
- valid to follow an xref (so info readers can find the node
- names). `input_text_offset' is pointing at the "}" which ended
- the xref or ref command. */
- int temp;
+ input_text_length = save_input_text_length;
- for (temp = input_text_offset + 1; temp < input_text_length; )
- {
- if (cr_or_whitespace (input_text[temp]))
- temp++;
- else
- {
- if (input_text[temp] != '.' && input_text[temp] != ',')
- warning (_("`.' or `,' must follow cross reference, not %c"),
- input_text[temp]);
- break;
- }
- }
- }
+ return from;
}
-void
-cm_pxref (arg)
- int arg;
-{
- if (arg == START)
- {
- px_ref_flag++;
- cm_xref (arg);
- px_ref_flag--;
- }
- /* Note that cm_xref isn't called with arg == END, which disables
- the code near the end of cm_xref that checks for `.' or `,'
- after the cross-reference. This is because @pxref{} generates
- the required character itself, when needed. */
-}
-
-void
-cm_ref (arg)
- int arg;
+/* Return next non-whitespace and non-cr character. */
+int
+next_nonwhitespace_character (void)
{
- if (arg == START)
- {
- ref_flag++;
- cm_xref (arg);
- ref_flag--;
- }
-}
+ /* First check the current input_text. Start from the next char because
+ we already have input_text[input_text_offset] in ``current''. */
+ int pos = input_text_offset + 1;
-void
-cm_inforef (arg)
- int arg;
-{
- if (arg == START)
+ while (pos < input_text_length)
{
- char *node = get_xref_token (1); /* expands all macros in inforef */
- char *pname = get_xref_token (0);
- char *file = get_xref_token (0);
-
- /* (see comments at cm_xref). */
- if (!*node)
- line_error (_("First argument to @inforef may not be empty"));
-
- if (xml && !docbook)
- {
- xml_insert_element (INFOREF, START);
- xml_insert_element (INFOREFNODENAME, START);
- execute_string (node);
- xml_insert_element (INFOREFNODENAME, END);
- if (*pname)
- {
- xml_insert_element (INFOREFREFNAME, START);
- execute_string (pname);
- xml_insert_element (INFOREFREFNAME, END);
- }
- xml_insert_element (INFOREFINFONAME, START);
- execute_string (file);
- xml_insert_element (INFOREFINFONAME, END);
-
- xml_insert_element (INFOREF, END);
- }
- else if (html)
- {
- char *tem;
-
- add_word (_("see "));
- /* html fixxme: revisit this */
- add_html_elt ("<a href=");
- if (splitting)
- execute_string ("\"../%s/", file);
- else
- execute_string ("\"%s.html", file);
- tem = expansion (node, 0);
- add_anchor_name (tem, 1);
- add_word ("\">");
- execute_string ("%s", *pname ? pname : tem);
- add_word ("</a>");
- free (tem);
- }
- else
- {
- if (*pname)
- execute_string ("*note %s: (%s)%s", pname, file, node);
- else
- execute_string ("*note (%s)%s::", file, node);
- }
-
- free (node);
- free (pname);
- free (file);
+ if (!cr_or_whitespace(input_text[pos]))
+ return input_text[pos];
+ pos++;
}
-}
-/* A URL reference. */
-void
-cm_uref (arg)
- int arg;
-{
- if (arg == START)
- {
- extern int printing_index;
- char *url = get_xref_token (1); /* expands all macros in uref */
- char *desc = get_xref_token (0);
- char *replacement = get_xref_token (0);
+ { /* Can't find a valid character, so go through filestack
+ in case we are doing @include or expanding a macro. */
+ FSTACK *tos = filestack;
- if (xml)
- {
- xml_insert_element (UREF, START);
- xml_insert_element (UREFURL, START);
- execute_string (url);
- xml_insert_element (UREFURL, END);
- if (*desc)
- {
- xml_insert_element (UREFDESC, START);
- execute_string (desc);
- xml_insert_element (UREFDESC, END);
- }
- if (*replacement)
- {
- xml_insert_element (UREFREPLACEMENT, START);
- execute_string (replacement);
- xml_insert_element (UREFREPLACEMENT, END);
- }
- xml_insert_element (UREF, END);
- }
- else if (html)
- { /* never need to show the url */
- add_html_elt ("<a href=");
- /* don't collapse `--' etc. in the url */
- in_fixed_width_font++;
- execute_string ("\"%s\"", url);
- in_fixed_width_font--;
- add_word (">");
- execute_string ("%s", *replacement ? replacement
- : (*desc ? desc : url));
- add_word ("</a>");
- }
- else if (*replacement) /* do not show the url */
- execute_string ("%s", replacement);
- else if (*desc) /* show both text and url */
- {
- execute_string ("%s ", desc);
- in_fixed_width_font++;
- execute_string ("(%s)", url);
- in_fixed_width_font--;
- }
- else /* no text at all, so have the url to show */
- {
- in_fixed_width_font++;
- execute_string ("%s%s%s",
- printing_index ? "" : "`",
- url,
- printing_index ? "" : "'");
- in_fixed_width_font--;
- }
- if (url)
- free (url);
- if (desc)
- free (desc);
- if (replacement)
- free (replacement);
- }
-}
+ while (tos)
+ {
+ int tmp_input_text_length = filestack->size;
+ int tmp_input_text_offset = filestack->offset;
+ char *tmp_input_text = filestack->text;
-/* An email reference. */
-void
-cm_email (arg)
- int arg;
-{
- if (arg == START)
- {
- char *addr = get_xref_token (1); /* expands all macros in email */
- char *name = get_xref_token (0);
+ while (tmp_input_text_offset < tmp_input_text_length)
+ {
+ if (!cr_or_whitespace(tmp_input_text[tmp_input_text_offset]))
+ return tmp_input_text[tmp_input_text_offset];
+ tmp_input_text_offset++;
+ }
- if (xml && docbook)
- {
- xml_insert_element_with_attribute (EMAIL, START, "url=\"mailto:%s\"", addr);
- if (*name)
- execute_string (name);
- xml_insert_element (EMAIL, END);
- }
- else if (xml)
- {
- xml_insert_element (EMAIL, START);
- xml_insert_element (EMAILADDRESS, START);
- execute_string (addr);
- xml_insert_element (EMAILADDRESS, END);
- if (*name)
- {
- xml_insert_element (EMAILNAME, START);
- execute_string (name);
- xml_insert_element (EMAILNAME, END);
- }
- xml_insert_element (EMAIL, END);
- }
- else if (html)
- {
- add_html_elt ("<a href=");
- /* don't collapse `--' etc. in the address */
- in_fixed_width_font++;
- execute_string ("\"mailto:%s\"", addr);
- in_fixed_width_font--;
- add_word (">");
- execute_string ("%s", *name ? name : addr);
- add_word ("</a>");
- }
- else
- {
- execute_string ("%s%s", name, *name ? " " : "");
- in_fixed_width_font++;
- execute_string ("<%s>", addr);
- in_fixed_width_font--;
- }
+ tos = tos->next;
+ }
+ }
- if (addr)
- free (addr);
- if (name)
- free (name);
- }
+ return -1;
}
-
+
/* An external image is a reference, kind of. The parsing is (not
coincidentally) similar, anyway. */
void
-cm_image (arg)
- int arg;
+cm_image (int arg)
{
char *name_arg, *w_arg, *h_arg, *alt_arg, *ext_arg;
@@ -3507,34 +3262,48 @@ cm_image (arg)
struct stat file_info;
char *pathname = NULL;
char *fullname = xmalloc (strlen (name_arg)
- + (ext_arg && *ext_arg ? strlen (ext_arg) + 1 : 4) + 1);
+ + (ext_arg && *ext_arg ? strlen (ext_arg) + 1: 4) + 1);
if (ext_arg && *ext_arg)
{
- sprintf (fullname, "%s.%s", name_arg, ext_arg);
+ sprintf (fullname, "%s%s", name_arg, ext_arg);
if (access (fullname, R_OK) != 0)
pathname = get_file_info_in_path (fullname, include_files_path,
&file_info);
+
+ if (pathname == NULL)
+ {
+ /* Backwards compatibility (4.6 <= version < 4.7):
+ try prefixing @image's EXTENSION parameter with a period. */
+ sprintf (fullname, "%s.%s", name_arg, ext_arg);
+ if (access (fullname, R_OK) != 0)
+ pathname = get_file_info_in_path (fullname, include_files_path,
+ &file_info);
+ }
}
else
{
sprintf (fullname, "%s.png", name_arg);
- if (access (fullname, R_OK) != 0)
- {
- pathname = get_file_info_in_path (fullname,
- include_files_path, &file_info);
- if (pathname == NULL)
- {
- sprintf (fullname, "%s.jpg", name_arg);
- if (access (fullname, R_OK) != 0)
- pathname = get_file_info_in_path (fullname,
+ if (access (fullname, R_OK) != 0) {
+ pathname = get_file_info_in_path (fullname,
+ include_files_path, &file_info);
+ if (pathname == NULL) {
+ sprintf (fullname, "%s.jpg", name_arg);
+ if (access (fullname, R_OK) != 0) {
+ sprintf (fullname, "%s.gif", name_arg);
+ if (access (fullname, R_OK) != 0) {
+ pathname = get_file_info_in_path (fullname,
include_files_path, &file_info);
}
+ }
}
+ }
}
if (html)
{
+ int image_in_div = 0;
+
if (pathname == NULL && access (fullname, R_OK) != 0)
{
line_error(_("@image file `%s' (for HTML) not readable: %s"),
@@ -3548,19 +3317,42 @@ cm_image (arg)
return;
}
+ if (!paragraph_is_open)
+ {
+ add_html_block_elt ("<div class=\"block-image\">");
+ image_in_div = 1;
+ }
+
add_html_elt ("<img src=");
add_word_args ("\"%s\"", fullname);
add_html_elt (" alt=");
- add_word_args ("\"%s\">", (*alt_arg) ? alt_arg : fullname);
+ add_word_args ("\"%s\">",
+ escape_string (*alt_arg ? text_expansion (alt_arg) : fullname));
+
+ if (image_in_div)
+ add_html_block_elt ("</div>");
}
else if (xml && docbook)
xml_insert_docbook_image (name_arg);
else if (xml)
{
- xml_insert_element_with_attribute (IMAGE, START, "width=\"%s\" height=\"%s\" alttext=\"%s\" extension=\"%s\"",
- w_arg, h_arg, alt_arg, ext_arg);
- add_word (name_arg);
- xml_insert_element (IMAGE, END);
+ extern int xml_in_para;
+ extern int xml_no_para;
+ int elt = xml_in_para ? INLINEIMAGE : IMAGE;
+
+ if (!xml_in_para)
+ xml_no_para++;
+
+ xml_insert_element_with_attribute (elt,
+ START, "width=\"%s\" height=\"%s\" name=\"%s\" extension=\"%s\"",
+ w_arg, h_arg, name_arg, ext_arg);
+ xml_insert_element (IMAGEALTTEXT, START);
+ execute_string ("%s", alt_arg);
+ xml_insert_element (IMAGEALTTEXT, END);
+ xml_insert_element (elt, END);
+
+ if (!xml_in_para)
+ xml_no_para--;
}
else
{ /* Try to open foo.EXT or foo.txt. */
@@ -3568,7 +3360,7 @@ cm_image (arg)
char *txtpath = NULL;
char *txtname = xmalloc (strlen (name_arg)
+ (ext_arg && *ext_arg
- ? strlen (ext_arg) + 1 : 4) + 1);
+ ? strlen (ext_arg) : 4) + 1);
strcpy (txtname, name_arg);
strcat (txtname, ".txt");
image_file = fopen (txtname, "r");
@@ -3587,49 +3379,72 @@ cm_image (arg)
int ch;
int save_inhibit_indentation = inhibit_paragraph_indentation;
int save_filling_enabled = filling_enabled;
+ int image_in_brackets = paragraph_is_open;
+
+ /* Write magic ^@^H[image ...^@^H] cookie in the info file, if
+ there's an accompanying bitmap. Otherwise just include the
+ text image. In the plaintext output, always include the text
+ image without the magic cookie. */
+ int use_magic_cookie = !no_headers
+ && access (fullname, R_OK) == 0 && !STREQ (fullname, txtname);
inhibit_paragraph_indentation = 1;
filling_enabled = 0;
last_char_was_newline = 0;
- /* Write magic ^@^H[image ...^@^H] cookie in the info file. */
- add_char ('\0');
- add_word ("\010[image");
+ if (use_magic_cookie)
+ {
+ add_char ('\0');
+ add_word ("\010[image");
- if (access (fullname, R_OK) == 0
- || (pathname != NULL && access (pathname, R_OK) == 0))
- add_word_args (" src=%s", fullname);
+ if (access (fullname, R_OK) == 0
+ || (pathname != NULL && access (pathname, R_OK) == 0))
+ add_word_args (" src=\"%s\"", fullname);
- if (*alt_arg)
- add_word_args (" alt=\"%s\"", alt_arg);
+ if (*alt_arg)
+ add_word_args (" alt=\"%s\"", alt_arg);
+ }
if (image_file != NULL)
{
- add_word (" text=\"");
+ if (use_magic_cookie)
+ add_word (" text=\"");
+
+ if (image_in_brackets)
+ add_char ('[');
+
/* Maybe we need to remove the final newline if the image
file is only one line to allow in-line images. On the
other hand, they could just make the file without a
final newline. */
while ((ch = getc (image_file)) != EOF)
{
- if (ch == '"' || ch == '\\')
+ if (use_magic_cookie && (ch == '"' || ch == '\\'))
add_char ('\\');
add_char (ch);
}
- add_char ('"');
+
+ if (image_in_brackets)
+ add_char (']');
+
+ if (use_magic_cookie)
+ add_char ('"');
if (fclose (image_file) != 0)
perror (txtname);
}
+ if (use_magic_cookie)
+ {
+ add_char ('\0');
+ add_word ("\010]");
+ }
+
inhibit_paragraph_indentation = save_inhibit_indentation;
filling_enabled = save_filling_enabled;
-
- add_char ('\0');
- add_word ("\010]");
}
else
- line_error (_("@image file `%s' (for text) unreadable: %s"),
+ warning (_("@image file `%s' (for text) unreadable: %s"),
txtname, strerror (errno));
}
@@ -3665,10 +3480,8 @@ typedef struct defines {
DEFINE *defines = NULL;
/* Add NAME to the list of `set' defines. */
-void
-set (name, value)
- char *name;
- char *value;
+static void
+set (char *name, char *value)
{
DEFINE *temp;
@@ -3685,12 +3498,18 @@ set (name, value)
temp->name = xstrdup (name);
temp->value = xstrdup (value);
defines = temp;
+
+ if (xml && !docbook)
+ {
+ xml_insert_element_with_attribute (SETVALUE, START, "name=\"%s\"", name);
+ execute_string ("%s", value);
+ xml_insert_element (SETVALUE, END);
+ }
}
/* Remove NAME from the list of `set' defines. */
-void
-clear (name)
- char *name;
+static void
+clear (char *name)
{
DEFINE *temp, *last;
@@ -3714,12 +3533,17 @@ clear (name)
last = temp;
temp = temp->next;
}
+
+ if (xml && !docbook)
+ {
+ xml_insert_element_with_attribute (CLEARVALUE, START, "name=\"%s\"", name);
+ xml_insert_element (CLEARVALUE, END);
+ }
}
/* Return the value of NAME. The return value is NULL if NAME is unset. */
-char *
-set_p (name)
- char *name;
+static char *
+set_p (char *name)
{
DEFINE *temp;
@@ -3732,26 +3556,26 @@ set_p (name)
/* Create a variable whose name appears as the first word on this line. */
void
-cm_set ()
+cm_set (void)
{
handle_variable (SET);
}
/* Remove a variable whose name appears as the first word on this line. */
void
-cm_clear ()
+cm_clear (void)
{
handle_variable (CLEAR);
}
void
-cm_ifset ()
+cm_ifset (void)
{
handle_variable (IFSET);
}
void
-cm_ifclear ()
+cm_ifclear (void)
{
handle_variable (IFCLEAR);
}
@@ -3763,7 +3587,7 @@ cm_ifclear ()
if ARG1 and ARG2 caselessly string compare to the same string, otherwise,
it produces no output. */
void
-cm_ifeq ()
+cm_ifeq (void)
{
char **arglist;
@@ -3783,11 +3607,16 @@ cm_ifeq ()
}
void
-cm_value (arg, start_pos, end_pos)
- int arg, start_pos, end_pos;
+cm_value (int arg, int start_pos, int end_pos)
{
static int value_level = 0, saved_meta_pos = -1;
+ /* xml_add_char() skips any content inside menus when output format is
+ Docbook, so @value{} is no use there. Also start_pos and end_pos does not
+ get updated, causing name to be empty string. So just return. */
+ if (docbook && in_menu)
+ return;
+
/* All the text after @value{ upto the matching } will eventually
disappear from output_paragraph, when this function is called
with ARG == END. If the text produced until then sets
@@ -3833,11 +3662,18 @@ cm_value (arg, start_pos, end_pos)
among other things. */
if (value)
- execute_string ("%s", value);
+ {
+ /* We need to get past the closing brace since the value may
+ expand to a context-sensitive macro (e.g. @xref) and produce
+ spurious warnings */
+ input_text_offset++;
+ execute_string ("%s", value);
+ input_text_offset--;
+ }
else
{
- warning (_("undefined flag: %s"), name);
- add_word_args (_("{No value for `%s'}"), name);
+ warning (_("undefined flag: %s"), name);
+ add_word_args (_("{No value for `%s'}"), name);
}
free (name);
@@ -3845,9 +3681,8 @@ cm_value (arg, start_pos, end_pos)
}
/* Set, clear, or conditionalize based on ACTION. */
-void
-handle_variable (action)
- int action;
+static void
+handle_variable (int action)
{
char *name;
@@ -3861,10 +3696,8 @@ handle_variable (action)
free (name);
}
-void
-handle_variable_internal (action, name)
- int action;
- char *name;
+static void
+handle_variable_internal (int action, char *name)
{
char *temp;
int delimiter, additional_text_present = 0;
@@ -4020,7 +3853,6 @@ handle_variable_internal (action, name)
}
/* Execution of random text not in file. */
-
typedef struct {
char *string; /* The string buffer. */
int size; /* The size of the buffer. */
@@ -4031,9 +3863,8 @@ static EXECUTION_STRING **execution_strings = NULL;
static int execution_strings_index = 0;
static int execution_strings_slots = 0;
-EXECUTION_STRING *
-get_execution_string (initial_size)
- int initial_size;
+static EXECUTION_STRING *
+get_execution_string (int initial_size)
{
int i = 0;
EXECUTION_STRING *es = NULL;
@@ -4081,9 +3912,7 @@ get_execution_string (initial_size)
entry in the execution_strings[] array and change the .STRING and
.SIZE members of that entry as appropriate. */
void
-maybe_update_execution_strings (text, new_len)
- char **text;
- unsigned new_len;
+maybe_update_execution_strings (char **text, unsigned int new_len)
{
int i = 0;
@@ -4127,10 +3956,11 @@ execute_string (format, va_alist)
#endif
{
EXECUTION_STRING *es;
- char *temp_string;
+ char *temp_string, *temp_input_filename;
#ifdef VA_FPRINTF
va_list ap;
#endif
+ int insertion_level_at_start = insertion_level;
es = get_execution_string (EXECUTE_STRING_MAX);
temp_string = es->string;
@@ -4147,28 +3977,50 @@ execute_string (format, va_alist)
pushfile ();
input_text_offset = 0;
input_text = temp_string;
- input_filename = xstrdup (input_filename);
input_text_length = strlen (temp_string);
+ input_filename = xstrdup (input_filename);
+ temp_input_filename = input_filename;
executing_string++;
reader_loop ();
- free (input_filename);
+
+ /* If insertion stack level changes during execution, that means a multiline
+ command is used inside braces or @section ... kind of commands. */
+ if (insertion_level_at_start != insertion_level && !executing_macro)
+ {
+ line_error (_("Multiline command %c%s used improperly"),
+ COMMAND_PREFIX,
+ command);
+ /* We also need to keep insertion_level intact to make sure warnings are
+ issued for @end ... command. */
+ while (insertion_level > insertion_level_at_start)
+ pop_insertion ();
+ }
popfile ();
executing_string--;
es->in_use = 0;
+ free (temp_input_filename);
}
/* Return what would be output for STR (in newly-malloced memory), i.e.,
- expand Texinfo commands. If IMPLICIT_CODE is set, expand @code{STR}.
- This is generally used for short texts; filling, indentation, and
- html escapes are disabled. */
+ expand Texinfo commands according to the current output format. If
+ IMPLICIT_CODE is set, expand @code{STR}. This is generally used for
+ short texts; filling, indentation, and html escapes are disabled. */
+
+char *
+expansion (char *str, int implicit_code)
+{
+ return maybe_escaped_expansion (str, implicit_code, 0);
+}
+
+
+/* Do HTML escapes according to DO_HTML_ESCAPE. Needed in
+ cm_printindex, q.v. */
char *
-expansion (str, implicit_code)
- char *str;
- int implicit_code;
+maybe_escaped_expansion (char *str, int implicit_code, int do_html_escape)
{
char *result;
@@ -4183,7 +4035,7 @@ expansion (str, implicit_code)
filling_enabled = 0;
indented_fill = 0;
no_indent = 1;
- escape_html = 0;
+ escape_html = do_html_escape;
result = full_expansion (str, implicit_code);
@@ -4198,12 +4050,10 @@ expansion (str, implicit_code)
/* Expand STR (or @code{STR} if IMPLICIT_CODE is nonzero). No change to
any formatting parameters -- filling, indentation, html escapes,
- etc., are not reset. */
+ etc., are not reset. Always returned in new memory. */
char *
-full_expansion (str, implicit_code)
- char *str;
- int implicit_code;
+full_expansion (char *str, int implicit_code)
{
int length;
char *result;
@@ -4260,18 +4110,20 @@ full_expansion (str, implicit_code)
format is. */
char *
-text_expansion (str)
- char *str;
+text_expansion (char *str)
{
char *ret;
int save_html = html;
int save_xml = xml;
+ int save_docbook = docbook;
html = 0;
xml = 0;
+ docbook = 0;
ret = expansion (str, 0);
html = save_html;
xml = save_xml;
+ docbook = save_docbook;
return ret;
}
@@ -4285,8 +4137,7 @@ text_expansion (str)
If NUM is zero, we assume `none'.
Returns 0 if successful, or nonzero if STRING isn't one of the above. */
int
-set_paragraph_indent (string)
- char *string;
+set_paragraph_indent (char *string)
{
if (strcmp (string, "asis") == 0 || strcmp (string, _("asis")) == 0)
paragraph_start_indent = 0;
diff --git a/contrib/texinfo/makeinfo/makeinfo.h b/contrib/texinfo/makeinfo/makeinfo.h
index dd77fe6..de4d423 100644
--- a/contrib/texinfo/makeinfo/makeinfo.h
+++ b/contrib/texinfo/makeinfo/makeinfo.h
@@ -1,7 +1,7 @@
/* makeinfo.h -- declarations for Makeinfo.
- $Id: makeinfo.h,v 1.10 2003/05/12 13:12:32 karl Exp $
+ $Id: makeinfo.h,v 1.17 2004/11/30 02:03:23 karl Exp $
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free
Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
@@ -31,13 +31,6 @@
/* Hardcoded per GNU standards, not dependent on argv[0]. */
DECLARE (char *, progname, "makeinfo");
-
-enum reftype
-{
- menu_reference, followed_reference
-};
-
-extern char *get_xref_token ();
/* Nonzero means a string is in execution, as opposed to a file. */
DECLARE (int, executing_string, 0);
@@ -45,8 +38,6 @@ DECLARE (int, executing_string, 0);
/* Nonzero means to inhibit writing macro expansions to the output
stream, because it has already been written. */
DECLARE (int, me_inhibit_expansion, 0);
-
-extern char *expansion (), *text_expansion (), *full_expansion ();
/* Current output stream. */
DECLARE (FILE *, output_stream, NULL);
@@ -68,6 +59,10 @@ DECLARE (int, output_column, 0);
/* Position in the output file. */
DECLARE (int, output_position, 0);
+/* Number of lines in the output. */
+DECLARE (int, output_line_number, 1);
+DECLARE (int, node_line_number, 0);
+
/* The offset into OUTPUT_PARAGRAPH where we have a meta character
produced by a markup such as @code or @dfn. */
DECLARE (int, meta_char_pos, -1);
@@ -96,8 +91,15 @@ DECLARE (int, current_indent, 0);
DECLARE (int, do_first_par_indent, 0);
/* Amount by which @example indentation increases/decreases. */
+DECLARE (int, example_indentation_increment, 5);
+
+/* Amount by which @table, @defun, etc. indentation increases/decreases. */
DECLARE (int, default_indentation_increment, 5);
+/* Amount by which xml indentation increases/decreases.
+ Zero means unnecessary whitespace is compressed. */
+DECLARE (int, xml_indentation_increment, 2);
+
/* Nonzero indicates that filling a line also indents the new line. */
DECLARE (int, indented_fill, 0);
@@ -133,7 +135,6 @@ DECLARE (int, enable_encoding, 0);
/* Nonzero means escape characters in HTML output. */
DECLARE (int, escape_html, 1);
-extern char *escape_string (); /* do HTML escapes */
/* Access key number for next menu entry to be generated (1 to 9, or 10 to
mean no access key) */
@@ -154,6 +155,9 @@ DECLARE (char *, current_node, NULL);
/* Command name in the process of being hacked. */
DECLARE (char *, command, NULL);
+/* Nonzero if we have seen an @titlepage command. */
+DECLARE (int, titlepage_cmd_present, 0);
+
/* @copying ... @end copying. */
DECLARE (char *, copying_text, NULL);
@@ -186,6 +190,9 @@ DECLARE (char *, css_include, NULL);
is, generate plain text. (--no-headers) */
DECLARE (int, no_headers, 0);
+/* Nonzero means that we process @docbook and @ifdocbook. (--ifdocbook) */
+DECLARE (int, process_docbook, 0);
+
/* Nonzero means that we process @html and @rawhtml even when not
generating HTML. (--ifhtml) */
DECLARE (int, process_html, 0);
@@ -218,7 +225,7 @@ DECLARE (int, verbose_mode, 0);
/* Nonzero means prefix each @chapter, ... with a number like
1, 1.1, etc. (--number-sections) */
-DECLARE (int, number_sections, 0);
+DECLARE (int, number_sections, 1);
/* Nonzero means split size. When zero, DEFAULT_SPLIT_SIZE is used. */
DECLARE (int, split_size, 0);
@@ -262,8 +269,16 @@ DECLARE (int, expensive_validation, 0);
#define digit_value(c) ((c) - '0')
#endif
-#define HTML_SAFE "$-_.+!*'()"
-#define URL_SAFE_CHAR(ch) (isalnum (ch) || strchr (HTML_SAFE, ch))
+/* These characters are not really HTML-safe (with strict XHTML),
+ and also there are possible collisions. That's the whole reason we
+ designed a new conversion scheme in the first place. But we
+ nevertheless need to generate the old names. See
+ `add_escaped_anchor_name' in html.c. */
+#define OLD_HTML_SAFE "$-_.+!*'()"
+#define OLD_URL_SAFE_CHAR(ch) (strchr (OLD_HTML_SAFE, ch))
+
+/* For the current/stable scheme. */
+#define URL_SAFE_CHAR(ch) (isalnum (ch))
#define COMMAND_PREFIX '@'
@@ -296,7 +311,76 @@ DECLARE (int, splitting, 1); /* Defaults to true for now. */
#define looking_at(string) \
(strncmp (input_text + input_text_offset, string, strlen (string)) == 0)
+/* Any list with a member named `next'. */
+typedef struct generic_list {
+ struct generic_list *next;
+} GENERIC_LIST;
+
+/* Reverse the order of a list. */
+extern GENERIC_LIST * reverse_list (GENERIC_LIST *list);
+
/* Possibly return Local Variables trailer for Info output. */
-extern char *info_trailer ();
+extern char *info_trailer (void),
+ *expansion (char *str, int implicit_code),
+ *text_expansion (char *str),
+ *maybe_escaped_expansion (char *str, int implicit_code, int do_escape_html),
+ *full_expansion (char *str, int implicit_code);
+
+extern void free_and_clear (char **pointer),
+ add_word (char *string),
+ add_char (int character),
+ add_meta_char (int character),
+ close_single_paragraph (void),
+ insert_string (const char *),
+ insert (int character),
+ get_rest_of_line (int expand, char **string),
+ add_html_block_elt (char *string),
+ get_until_in_braces (char *match, char **string),
+ get_until_in_line (int expand, char *match, char **string),
+ canon_white (char *string),
+ discard_until (char *string),
+ indent (int amount),
+ kill_self_indent (int count),
+ backup_input_pointer (void),
+ inhibit_output_flushing (void),
+ uninhibit_output_flushing (void),
+ flush_output (void),
+ start_paragraph (void),
+ close_paragraph (void),
+ close_insertion_paragraph (void),
+ init_paragraph (void),
+ ignore_blank_line (void),
+ reader_loop (void),
+ discard_braces (void),
+ replace_with_expansion (int from, int *to),
+ fix_whitespace (char *string),
+ add_html_elt (char *string);
+
+extern int get_until (char *match, char **string),
+ set_paragraph_indent (char *string),
+ self_delimiting (int character),
+ search_forward (char *string, int from),
+ search_forward_until_pos (char *string, int from, int end_pos),
+ next_nonwhitespace_character (void),
+ fs_error (char *filename);
+
+#if defined (VA_FPRINTF) && __STDC__
+/* Unfortunately we must use prototypes if we are to use <stdarg.h>. */
+extern void add_word_args (const char *, ...),
+ add_html_block_elt_args (const char *, ...),
+ execute_string (char *, ...),
+ warning (const char *format, ...),
+ error (const char *format, ...),
+ line_error (const char *format, ...),
+ file_line_error (char *infile, int lno, const char *format, ...);
+#else
+extern void add_word_args (),
+ add_html_block_elt_args (),
+ execute_string (),
+ warning (),
+ error (),
+ line_error (),
+ file_line_error ();
+#endif /* no prototypes */
#endif /* not MAKEINFO_H */
diff --git a/contrib/texinfo/makeinfo/multi.c b/contrib/texinfo/makeinfo/multi.c
index d5cc19c..06c548f 100644
--- a/contrib/texinfo/makeinfo/multi.c
+++ b/contrib/texinfo/makeinfo/multi.c
@@ -1,7 +1,7 @@
/* multi.c -- multiple-column tables (@multitable) for makeinfo.
- $Id: multi.c,v 1.4 2002/11/04 21:28:10 karl Exp $
+ $Id: multi.c,v 1.8 2004/04/11 17:56:47 karl Exp $
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004 Free Software
Foundation, Inc.
This program is free software; you can redistribute it and/or modify
@@ -18,11 +18,13 @@
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- Written by phr@gnu.org (Paul Rubin). */
+ Originally written by phr@gnu.org (Paul Rubin). */
#include "system.h"
+#include "cmds.h"
#include "insertion.h"
#include "makeinfo.h"
+#include "multi.h"
#include "xml.h"
#define MAXCOLS 100 /* remove this limit later @@ */
@@ -66,6 +68,13 @@ struct env
/* index in environment table of currently selected environment */
static int current_env_no;
+/* current column number */
+static int current_column_no;
+
+/* We need to make a difference between template based widths and
+ @columnfractions for HTML tables' sake. Sigh. */
+static int seen_column_fractions;
+
/* column number of last column in current multitable */
static int last_column;
@@ -75,133 +84,13 @@ static int hsep, vsep;
/* whether this is the first row. */
static int first_row;
-
-static void output_multitable_row ();
-/* Output a row. Calls insert, but also flushes the buffered output
- when we see a newline, since in multitable every line is a separate
- paragraph. */
-static void
-out_char (ch)
- int ch;
-{
- if (html)
- add_char (ch);
- else
- {
- int env = select_output_environment (0);
- insert (ch);
- if (ch == '\n')
- {
- uninhibit_output_flushing ();
- flush_output ();
- inhibit_output_flushing ();
- }
- select_output_environment (env);
- }
-}
-
-
-void
-draw_horizontal_separator ()
-{
- int i, j, s;
-
- if (html)
- {
- add_word ("<hr>");
- return;
- }
- if (xml)
- return;
-
- for (s = 0; s < envs[0].current_indent; s++)
- out_char (' ');
- if (vsep)
- out_char ('+');
- for (i = 1; i <= last_column; i++) {
- for (j = 0; j <= envs[i].fill_column; j++)
- out_char ('-');
- if (vsep)
- out_char ('+');
- }
- out_char ('\n');
-}
-
-
-/* multitable strategy:
- for each item {
- for each column in an item {
- initialize a new paragraph
- do ordinary formatting into the new paragraph
- save the paragraph away
- repeat if there are more paragraphs in the column
- }
- dump out the saved paragraphs and free the storage
- }
-
- For HTML we construct a simple HTML 3.2 table with <br>s inserted
- to help non-tables browsers. `@item' inserts a <tr> and `@tab'
- inserts <td>; we also try to close <tr>. The only real
- alternative is to rely on the info formatting engine and present
- preformatted text. */
-
-void
-do_multitable ()
-{
- int ncolumns;
-
- if (multitable_active)
- {
- line_error ("Multitables cannot be nested");
- return;
- }
-
- close_single_paragraph ();
-
- /* scan the current item function to get the field widths
- and number of columns, and set up the output environment list
- accordingly. */
- /* if (docbook)*/ /* 05-08 */
- if (xml)
- xml_no_para = 1;
- ncolumns = setup_multitable_parameters ();
- first_row = 1;
-
- /* <p> for non-tables browsers. @multitable implicitly ends the
- current paragraph, so this is ok. */
- if (html)
- add_word ("<p><table>");
- /* else if (docbook)*/ /* 05-08 */
- else if (xml)
- {
- int *widths = xmalloc (ncolumns * sizeof (int));
- int i;
- for (i=0; i<ncolumns; i++)
- widths[i] = envs[i+1].fill_column;
- xml_begin_multitable (ncolumns, widths);
- free (widths);
- }
-
- if (hsep)
- draw_horizontal_separator ();
-
- /* The next @item command will direct stdout into the first column
- and start processing. @tab will then switch to the next column,
- and @item will flush out the saved output and return to the first
- column. Environment #1 is the first column. (Environment #0 is
- the normal output) */
-
- ++multitable_active;
-}
-
/* Called to handle a {...} template on the @multitable line.
We're at the { and our first job is to find the matching }; as a side
effect, we change *PARAMS to point to after it. Our other job is to
expand the template text and return the width of that string. */
static unsigned
-find_template_width (params)
- char **params;
+find_template_width (char **params)
{
char *template, *xtemplate;
unsigned len;
@@ -241,12 +130,63 @@ find_template_width (params)
return len;
}
+/* Direct current output to environment number N. Used when
+ switching work from one column of a multitable to the next.
+ Returns previous environment number. */
+static int
+select_output_environment (int n)
+{
+ struct env *e = &envs[current_env_no];
+ int old_env_no = current_env_no;
+
+ /* stash current env info from global vars into the old environment */
+ e->output_paragraph = output_paragraph;
+ e->output_paragraph_offset = output_paragraph_offset;
+ e->meta_char_pos = meta_char_pos;
+ e->output_column = output_column;
+ e->paragraph_is_open = paragraph_is_open;
+ e->current_indent = current_indent;
+ e->fill_column = fill_column;
+
+ /* now copy new environment into global vars */
+ current_env_no = n;
+ e = &envs[current_env_no];
+ output_paragraph = e->output_paragraph;
+ output_paragraph_offset = e->output_paragraph_offset;
+ meta_char_pos = e->meta_char_pos;
+ output_column = e->output_column;
+ paragraph_is_open = e->paragraph_is_open;
+ current_indent = e->current_indent;
+ fill_column = e->fill_column;
+ return old_env_no;
+}
+
+/* Initialize environment number ENV_NO, of width WIDTH.
+ The idea is that we're going to use one environment for each column of
+ a multitable, so we can build them up separately and print them
+ all out at the end. */
+static int
+setup_output_environment (int env_no, int width)
+{
+ int old_env = select_output_environment (env_no);
+
+ /* clobber old environment and set width of new one */
+ init_paragraph ();
+
+ /* make our change */
+ fill_column = width;
+
+ /* Save new environment and restore previous one. */
+ select_output_environment (old_env);
+
+ return env_no;
+}
/* Read the parameters for a multitable from the current command
line, save the parameters away, and return the
number of columns. */
-int
-setup_multitable_parameters ()
+static int
+setup_multitable_parameters (void)
{
char *params = insertion_stack->item_function;
int nchars;
@@ -259,6 +199,9 @@ setup_multitable_parameters ()
but TeX doesn't either. */
hsep = vsep = 0;
+ /* Assume no @columnfractions per default. */
+ seen_column_fractions = 0;
+
while (*params) {
while (whitespace (*params))
params++;
@@ -272,6 +215,7 @@ setup_multitable_parameters ()
else if (strcmp (command, "@vsep") == 0)
vsep++;
else if (strcmp (command, "@columnfractions") == 0) {
+ seen_column_fractions = 1;
/* Clobber old environments and create new ones, starting at #1.
Environment #0 is the normal output, so don't mess with it. */
for ( ; i <= MAXCOLS; i++) {
@@ -282,19 +226,26 @@ setup_multitable_parameters ()
number) and then non-whitespace (the number). */
while (*params && (*params == ' ' || *params == '\t'))
params++;
- /* Hmm, but what about @columnfractions 3foo. Well, I suppose
+ /* Hmm, but what about @columnfractions 3foo. Oh well,
it's invalid input anyway. */
while (*params && *params != ' ' && *params != '\t'
&& *params != '\n' && *params != '@')
params++;
- setup_output_environment (i,
- (int) (columnfrac * (fill_column - current_indent) + .5));
+
+ {
+ /* For html/xml/docbook, translate fractions into integer
+ percentages, adding .005 to avoid rounding problems. For
+ info, we want the character width. */
+ int width = xml || html ? (columnfrac + .005) * 100
+ : (columnfrac * (fill_column - current_indent) + .5);
+ setup_output_environment (i, width);
+ }
}
}
} else if (*params == '{') {
unsigned template_width = find_template_width (&params);
-
+
/* This gives us two spaces between columns. Seems reasonable.
How to take into account current_indent here? */
setup_output_environment (i++, template_width + 2);
@@ -313,64 +264,130 @@ done:
return last_column;
}
-/* Initialize environment number ENV_NO, of width WIDTH.
- The idea is that we're going to use one environment for each column of
- a multitable, so we can build them up separately and print them
- all out at the end. */
-int
-setup_output_environment (env_no, width)
- int env_no;
- int width;
+/* Output a row. Calls insert, but also flushes the buffered output
+ when we see a newline, since in multitable every line is a separate
+ paragraph. */
+static void
+out_char (int ch)
{
- int old_env = select_output_environment (env_no);
+ if (html || xml)
+ add_char (ch);
+ else
+ {
+ int env = select_output_environment (0);
+ insert (ch);
+ if (ch == '\n')
+ {
+ uninhibit_output_flushing ();
+ flush_output ();
+ inhibit_output_flushing ();
+ }
+ select_output_environment (env);
+ }
+}
- /* clobber old environment and set width of new one */
- init_paragraph ();
- /* make our change */
- fill_column = width;
+static void
+draw_horizontal_separator (void)
+{
+ int i, j, s;
- /* Save new environment and restore previous one. */
- select_output_environment (old_env);
+ if (html)
+ {
+ add_word ("<hr>");
+ return;
+ }
+ if (xml)
+ return;
- return env_no;
+ for (s = 0; s < envs[0].current_indent; s++)
+ out_char (' ');
+ if (vsep)
+ out_char ('+');
+ for (i = 1; i <= last_column; i++) {
+ for (j = 0; j <= envs[i].fill_column; j++)
+ out_char ('-');
+ if (vsep)
+ out_char ('+');
+ }
+ out_char (' ');
+ out_char ('\n');
}
-/* Direct current output to environment number N. Used when
- switching work from one column of a multitable to the next.
- Returns previous environment number. */
-int
-select_output_environment (n)
- int n;
+
+/* multitable strategy:
+ for each item {
+ for each column in an item {
+ initialize a new paragraph
+ do ordinary formatting into the new paragraph
+ save the paragraph away
+ repeat if there are more paragraphs in the column
+ }
+ dump out the saved paragraphs and free the storage
+ }
+
+ For HTML we construct a simple HTML 3.2 table with <br>s inserted
+ to help non-tables browsers. `@item' inserts a <tr> and `@tab'
+ inserts <td>; we also try to close <tr>. The only real
+ alternative is to rely on the info formatting engine and present
+ preformatted text. */
+
+void
+do_multitable (void)
{
- struct env *e = &envs[current_env_no];
- int old_env_no = current_env_no;
+ int ncolumns;
- /* stash current env info from global vars into the old environment */
- e->output_paragraph = output_paragraph;
- e->output_paragraph_offset = output_paragraph_offset;
- e->meta_char_pos = meta_char_pos;
- e->output_column = output_column;
- e->paragraph_is_open = paragraph_is_open;
- e->current_indent = current_indent;
- e->fill_column = fill_column;
+ if (multitable_active)
+ {
+ line_error ("Multitables cannot be nested");
+ return;
+ }
- /* now copy new environment into global vars */
- current_env_no = n;
- e = &envs[current_env_no];
- output_paragraph = e->output_paragraph;
- output_paragraph_offset = e->output_paragraph_offset;
- meta_char_pos = e->meta_char_pos;
- output_column = e->output_column;
- paragraph_is_open = e->paragraph_is_open;
- current_indent = e->current_indent;
- fill_column = e->fill_column;
- return old_env_no;
+ close_single_paragraph ();
+
+ if (xml)
+ {
+ xml_no_para = 1;
+ if (output_paragraph[output_paragraph_offset-1] == '\n')
+ output_paragraph_offset--;
+ }
+
+ /* scan the current item function to get the field widths
+ and number of columns, and set up the output environment list
+ accordingly. */
+ ncolumns = setup_multitable_parameters ();
+ first_row = 1;
+
+ /* <p> for non-tables browsers. @multitable implicitly ends the
+ current paragraph, so this is ok. */
+ if (html)
+ add_html_block_elt ("<p><table summary=\"\">");
+ /* else if (docbook)*/ /* 05-08 */
+ else if (xml)
+ {
+ int *widths = xmalloc (ncolumns * sizeof (int));
+ int i;
+ for (i=0; i<ncolumns; i++)
+ widths[i] = envs[i+1].fill_column;
+ xml_begin_multitable (ncolumns, widths);
+ free (widths);
+ }
+
+ if (hsep)
+ draw_horizontal_separator ();
+
+ /* The next @item command will direct stdout into the first column
+ and start processing. @tab will then switch to the next column,
+ and @item will flush out the saved output and return to the first
+ column. Environment #1 is the first column. (Environment #0 is
+ the normal output) */
+
+ ++multitable_active;
}
/* advance to the next environment number */
-void
-nselect_next_environment ()
+static void
+nselect_next_environment (void)
{
if (current_env_no >= last_column) {
line_error (_("Too many columns in multitable item (max %d)"), last_column);
@@ -382,8 +399,8 @@ nselect_next_environment ()
/* do anything needed at the beginning of processing a
multitable column. */
-void
-init_column ()
+static void
+init_column (void)
{
/* don't indent 1st paragraph in the item */
cm_noindent ();
@@ -392,50 +409,8 @@ init_column ()
skip_whitespace ();
}
-/* start a new item (row) of a multitable */
-int
-multitable_item ()
-{
- if (!multitable_active) {
- line_error ("multitable_item internal error: no active multitable");
- xexit (1);
- }
-
- if (html)
- {
- if (!first_row)
- add_word ("<br></td></tr>"); /* <br> for non-tables browsers. */
- add_word ("<tr align=\"left\"><td valign=\"top\">");
- first_row = 0;
- return 0;
- }
- /* else if (docbook)*/ /* 05-08 */
- else if (xml)
- {
- xml_end_multitable_row (first_row);
- first_row = 0;
- return 0;
- }
- first_row = 0;
-
- if (current_env_no > 0) {
- output_multitable_row ();
- }
- /* start at column 1 */
- select_output_environment (1);
- if (!output_paragraph) {
- line_error (_("[unexpected] cannot select column #%d in multitable"),
- current_env_no);
- xexit (1);
- }
-
- init_column ();
-
- return 0;
-}
-
static void
-output_multitable_row ()
+output_multitable_row (void)
{
/* offset in the output paragraph of the next char needing
to be output for that column. */
@@ -520,18 +495,108 @@ output_multitable_row ()
}
}
+int after_headitem = 0;
+int headitem_row = 0;
+
+/* start a new item (row) of a multitable */
+int
+multitable_item (void)
+{
+ if (!multitable_active) {
+ line_error ("multitable_item internal error: no active multitable");
+ xexit (1);
+ }
+
+ current_column_no = 1;
+
+ if (html)
+ {
+ if (!first_row)
+ /* <br> for non-tables browsers. */
+ add_word_args ("<br></%s></tr>", after_headitem ? "th" : "td");
+
+ if (seen_column_fractions)
+ add_word_args ("<tr align=\"left\"><%s valign=\"top\" width=\"%d%%\">",
+ headitem_flag ? "th" : "td",
+ envs[current_column_no].fill_column);
+ else
+ add_word_args ("<tr align=\"left\"><%s valign=\"top\">",
+ headitem_flag ? "th" : "td");
+
+ if (headitem_flag)
+ after_headitem = 1;
+ else
+ after_headitem = 0;
+ first_row = 0;
+ headitem_row = headitem_flag;
+ headitem_flag = 0;
+ return 0;
+ }
+ /* else if (docbook)*/ /* 05-08 */
+ else if (xml)
+ {
+ xml_end_multitable_row (first_row);
+ if (headitem_flag)
+ after_headitem = 1;
+ else
+ after_headitem = 0;
+ first_row = 0;
+ headitem_flag = 0;
+ return 0;
+ }
+ first_row = 0;
+
+ if (current_env_no > 0) {
+ output_multitable_row ();
+ }
+ /* start at column 1 */
+ select_output_environment (1);
+ if (!output_paragraph) {
+ line_error (_("[unexpected] cannot select column #%d in multitable"),
+ current_env_no);
+ xexit (1);
+ }
+
+ init_column ();
+
+ if (headitem_flag)
+ hsep = 1;
+ else
+ hsep = 0;
+
+ if (headitem_flag)
+ after_headitem = 1;
+ else
+ after_headitem = 0;
+ headitem_flag = 0;
+
+ return 0;
+}
+
#undef CHAR_AT
#undef CHAR_ADDR
/* select a new column in current row of multitable */
void
-cm_tab ()
+cm_tab (void)
{
if (!multitable_active)
error (_("ignoring @tab outside of multitable"));
+
+ current_column_no++;
if (html)
- add_word ("</td><td valign=\"top\">");
+ {
+ if (seen_column_fractions)
+ add_word_args ("</%s><%s valign=\"top\" width=\"%d%%\">",
+ headitem_row ? "th" : "td",
+ headitem_row ? "th" : "td",
+ envs[current_column_no].fill_column);
+ else
+ add_word_args ("</%s><%s valign=\"top\">",
+ headitem_row ? "th" : "td",
+ headitem_row ? "th" : "td");
+ }
/* else if (docbook)*/ /* 05-08 */
else if (xml)
xml_end_multitable_column ();
@@ -544,7 +609,7 @@ cm_tab ()
/* close a multitable, flushing its output and resetting
whatever needs resetting */
void
-end_multitable ()
+end_multitable (void)
{
if (!html && !docbook)
output_multitable_row ();
@@ -558,7 +623,7 @@ end_multitable ()
close_insertion_paragraph ();
if (html)
- add_word ("<br></td></tr></table>\n");
+ add_word_args ("<br></%s></tr></table>\n", headitem_row ? "th" : "td");
/* else if (docbook)*/ /* 05-08 */
else if (xml)
xml_end_multitable ();
diff --git a/contrib/texinfo/makeinfo/multi.h b/contrib/texinfo/makeinfo/multi.h
new file mode 100644
index 0000000..64311e0
--- /dev/null
+++ b/contrib/texinfo/makeinfo/multi.h
@@ -0,0 +1,28 @@
+/* multi.h -- declarations for multi.c.
+ $Id: multi.h,v 1.1 2004/04/11 17:56:47 karl Exp $
+
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef MULTI_H
+#define MULTI_H
+
+extern void do_multitable (void);
+extern void end_multitable (void);
+extern int multitable_item (void);
+
+#endif /* !MULTI_H */
diff --git a/contrib/texinfo/makeinfo/node.c b/contrib/texinfo/makeinfo/node.c
index 2215d4c..07a37fe 100644
--- a/contrib/texinfo/makeinfo/node.c
+++ b/contrib/texinfo/makeinfo/node.c
@@ -1,7 +1,7 @@
/* node.c -- nodes for Texinfo.
- $Id: node.c,v 1.12 2003/05/01 00:30:07 karl Exp $
+ $Id: node.c,v 1.27 2004/12/20 23:56:07 karl Exp $
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
Foundation, Inc.
This program is free software; you can redistribute it and/or modify
@@ -21,6 +21,7 @@
#include "system.h"
#include "cmds.h"
#include "files.h"
+#include "float.h"
#include "footnote.h"
#include "macro.h"
#include "makeinfo.h"
@@ -30,12 +31,12 @@
#include "insertion.h"
#include "xml.h"
-
/* See comments in node.h. */
NODE_REF *node_references = NULL;
NODE_REF *node_node_references = NULL;
TAG_ENTRY *tag_table = NULL;
int node_number = -1;
+int node_order = 0;
int current_section = 0;
int outstanding_node = 0;
@@ -43,7 +44,7 @@ int outstanding_node = 0;
/* Start a new tag table. */
void
-init_tag_table ()
+init_tag_table (void)
{
while (tag_table)
{
@@ -61,8 +62,7 @@ init_tag_table ()
INDIRECT_P says how to format the output (it depends on whether the
table is direct or indirect). */
static void
-write_tag_table_internal (indirect_p)
- int indirect_p;
+write_tag_table_internal (int indirect_p)
{
TAG_ENTRY *node;
int old_indent = no_indent;
@@ -112,29 +112,37 @@ write_tag_table_internal (indirect_p)
}
void
-write_tag_table ()
+write_tag_table (char *filename)
{
+ output_stream = fopen (filename, "a");
+ if (!output_stream)
+ {
+ fs_error (filename);
+ return;
+ }
+
write_tag_table_internal (0); /* Not indirect. */
+
+ if (fclose (output_stream) != 0)
+ fs_error (filename);
}
-void
-write_tag_table_indirect ()
+static void
+write_tag_table_indirect (void)
{
write_tag_table_internal (1);
}
/* Convert "top" and friends into "Top". */
static void
-normalize_node_name (string)
- char *string;
+normalize_node_name (char *string)
{
if (strcasecmp (string, "Top") == 0)
strcpy (string, "Top");
}
-char *
-get_node_token (expand)
- int expand;
+static char *
+get_node_token (int expand)
{
char *string;
@@ -154,8 +162,7 @@ get_node_token (expand)
/* Expand any macros and other directives in a node name, and
return the expanded name as an malloc'ed string. */
char *
-expand_node_name (node)
- char *node;
+expand_node_name (char *node)
{
char *result = node;
@@ -175,8 +182,7 @@ expand_node_name (node)
/* Look up NAME in the tag table, and return the associated
tag_entry. If the node is not in the table return NULL. */
TAG_ENTRY *
-find_node (name)
- char *name;
+find_node (char *name)
{
TAG_ENTRY *tag = tag_table;
char *expanded_name;
@@ -223,9 +229,8 @@ find_node (name)
/* Look in the tag table for a node whose file name is FNAME, and
return the associated tag_entry. If there's no such node in the
table, return NULL. */
-TAG_ENTRY *
-find_node_by_fname (fname)
- char *fname;
+static TAG_ENTRY *
+find_node_by_fname (char *fname)
{
TAG_ENTRY *tag = tag_table;
while (tag)
@@ -241,8 +246,7 @@ find_node_by_fname (fname)
/* Remember next, prev, etc. references in a @node command, where we
don't care about most of the entries. */
static void
-remember_node_node_reference (node)
- char *node;
+remember_node_node_reference (char *node)
{
NODE_REF *temp = xmalloc (sizeof (NODE_REF));
int number;
@@ -263,10 +267,9 @@ remember_node_node_reference (node)
}
/* Remember NODE and associates. */
-void
-remember_node (node, prev, next, up, position, line_no, fname, flags)
- char *node, *prev, *next, *up, *fname;
- int position, line_no, flags;
+static void
+remember_node (char *node, char *prev, char *next, char *up,
+ int position, int line_no, char *fname, int flags)
{
/* Check for existence of this tag already. */
if (validating)
@@ -314,6 +317,11 @@ remember_node (node, prev, next, up, position, line_no, fname, flags)
new->html_fname
= normalize_filename (filename_part (current_output_filename));
new->next_ent = tag_table;
+
+ /* Increment the order counter, and save it. */
+ node_order++;
+ new->order = node_order;
+
tag_table = new;
}
@@ -330,10 +338,7 @@ remember_node (node, prev, next, up, position, line_no, fname, flags)
output file has been written, if validation is on, then we use the
contents of `node_references' as a list of nodes to validate. */
void
-remember_node_reference (node, line, type)
- char *node;
- int line;
- enum reftype type;
+remember_node_reference (char *node, int line, enum reftype type)
{
NODE_REF *temp = xmalloc (sizeof (NODE_REF));
int number = number_of_node (node);
@@ -357,8 +362,7 @@ remember_node_reference (node, line, type)
}
static void
-isolate_nodename (nodename)
- char *nodename;
+isolate_nodename (char *nodename)
{
int i, c;
int paren_seen, paren;
@@ -417,9 +421,7 @@ isolate_nodename (nodename)
just before the menu line. If REMEMBER_REF is zero, REF_TYPE is unused. */
#define MENU_STARTER "* "
char *
-glean_node_from_menu (remember_ref, ref_type)
- int remember_ref;
- enum reftype ref_type;
+glean_node_from_menu (int remember_ref, enum reftype ref_type)
{
int i, orig_offset = input_text_offset;
char *nodename;
@@ -473,14 +475,60 @@ glean_node_from_menu (remember_ref, ref_type)
/* Set the name of the current output file. */
void
-set_current_output_filename (fname)
- const char *fname;
+set_current_output_filename (const char *fname)
{
if (current_output_filename)
free (current_output_filename);
current_output_filename = xstrdup (fname);
}
+
+/* Output the <a name="..."></a> constructs for NODE. We output both
+ the new-style conversion and the old-style, if they are different.
+ See comments at `add_escaped_anchor_name' in html.c. */
+
+static void
+add_html_names (char *node)
+{
+ char *tem = expand_node_name (node);
+ char *otem = xstrdup (tem);
+
+ /* Determine if the old and new schemes come up with different names;
+ only output the old scheme if that is so. We don't want to output
+ the same name twice. */
+ canon_white (otem);
+ {
+ char *optr = otem;
+ int need_old = 0;
+
+ for (; *optr; optr++)
+ {
+ if (!cr_or_whitespace (*optr) && !URL_SAFE_CHAR (*optr))
+ {
+ need_old = 1;
+ break;
+ }
+ }
+
+ if (need_old)
+ {
+ add_word ("<a name=\"");
+ add_anchor_name (otem, -1); /* old anchor name conversion */
+ add_word ("\"></a>\n");
+ }
+ free (otem);
+ }
+
+ /* Always output the new scheme. */
+ canon_white (tem);
+ add_word ("<a name=\"");
+ add_anchor_name (tem, 0);
+ add_word ("\"></a>\n");
+
+ free (tem);
+}
+
+
/* The order is: nodename, nextnode, prevnode, upnode.
If all of the NEXT, PREV, and UP fields are empty, they are defaulted.
You must follow a node command which has those fields defaulted
@@ -488,7 +536,7 @@ set_current_output_filename (fname)
It is an error not to do so.
The defaults come from the menu in this node's parent. */
void
-cm_node ()
+cm_node (void)
{
static long epilogue_len = 0L;
char *node, *prev, *next, *up;
@@ -510,7 +558,6 @@ cm_node ()
if (!html && !already_outputting_pending_notes)
{
- if (!xml)
close_paragraph ();
output_pending_notes ();
}
@@ -586,6 +633,7 @@ cm_node ()
epilogue_len = ftell (output_stream) - pos1;
fclose (output_stream);
output_stream = NULL;
+ output_position = 0;
tag = find_node_by_fname (fname_for_this_node);
}
free (fname_for_prev_node);
@@ -602,6 +650,10 @@ cm_node ()
if (macro_expansion_output_stream && !executing_string)
remember_itext (input_text, input_text_offset);
+ /* Reset the line number in each node for Info output, so that
+ index entries will save the line numbers of parent node. */
+ node_line_number = 0;
+
no_indent = 1;
if (xml)
{
@@ -621,6 +673,9 @@ cm_node ()
}
else if (!no_headers && !html)
{
+ /* Emacs Info reader cannot grok indented escape sequence. */
+ kill_self_indent (-1);
+
add_word_args ("\037\nFile: %s, Node: ", pretty_output_filename);
if (macro_expansion_output_stream && !executing_string)
@@ -633,7 +688,7 @@ cm_node ()
/* Check for defaulting of this node's next, prev, and up fields. */
defaulting = (*next == 0 && *prev == 0 && *up == 0);
- this_section = what_section (input_text + input_text_offset);
+ this_section = what_section (input_text + input_text_offset, NULL);
/* If we are defaulting, then look at the immediately following
sectioning command (error if none) to determine the node's
@@ -679,6 +734,8 @@ cm_node ()
int orig_offset, orig_size;
+ int bye_offset = search_forward ("\n@bye", input_text_offset);
+
/* No matter what, make this file point back at `(dir)'. */
free (up);
up = xstrdup ("(dir)"); /* html fixxme */
@@ -694,6 +751,7 @@ cm_node ()
input_text_offset = search_forward ("\n@menu", orig_offset);
if (input_text_offset > -1
+ && (bye_offset > -1 && input_text_offset < bye_offset)
&& cr_or_whitespace (input_text[input_text_offset + 6]))
{
char *nodename_from_menu = NULL;
@@ -911,61 +969,66 @@ cm_node ()
}
if (!splitting && no_headers)
- { /* cross refs need a name="#anchor" even if we're not writing headers*/
- add_word ("<a name=\"");
- tem = expand_node_name (node);
- add_anchor_name (tem, 0);
- add_word ("\"></a>");
- free (tem);
+ { /* cross refs need a name="#anchor" even if not writing headers */
+ add_html_names (node);
}
if (splitting || !no_headers)
{ /* Navigation bar. */
- add_word ("<div class=\"node\">\n");
+ add_html_block_elt ("<div class=\"node\">\n");
/* The <p> avoids the links area running on with old Lynxen. */
add_word_args ("<p>%s\n", splitting ? "" : "<hr>");
- add_word_args ("%s%s<a name=\"", _("Node:"), "&nbsp;");
- tem = expand_node_name (node);
- add_anchor_name (tem, 0);
- add_word_args ("\">%s</a>", tem);
- free (tem);
+
+ /* In the split HTML case, the filename is wrong for the
+ old-style converted names, but we'll add them anyway, for
+ consistency. (And we need them in the normal (not
+ no_headers) nonsplit case.) */
+ add_html_names (node);
if (next)
{
tem = expansion (next, 0);
- add_word (",\n");
- add_word (_("Next:"));
+ add_word ((char *) _("Next:"));
add_word ("&nbsp;");
+
add_word ("<a rel=\"next\" accesskey=\"n\" href=\"");
add_anchor_name (tem, 1);
+ tem = escape_string (tem);
add_word_args ("\">%s</a>", tem);
+
free (tem);
+
+ if (prev || up)
+ add_word (",\n");
}
if (prev)
{
tem = expansion (prev, 0);
- add_word (",\n");
- add_word (_("Previous:"));
+ add_word ((char *) _("Previous:"));
add_word ("&nbsp;");
add_word ("<a rel=\"previous\" accesskey=\"p\" href=\"");
add_anchor_name (tem, 1);
+ tem = escape_string (tem);
add_word_args ("\">%s</a>", tem);
free (tem);
+
+ if (up)
+ add_word (",\n");
}
if (up)
{
tem = expansion (up, 0);
- add_word (",\n");
- add_word (_("Up:"));
+ add_word ((char *) _("Up:"));
add_word ("&nbsp;");
add_word ("<a rel=\"up\" accesskey=\"u\" href=\"");
add_anchor_name (tem, 1);
+ tem = escape_string (tem);
add_word_args ("\">%s</a>", tem);
free (tem);
}
/* html fixxme: we want a `top' or `contents' link here. */
- add_word_args ("\n%s<br>\n", splitting ? "<hr>" : "");
+ add_word_args ("\n%s\n", splitting ? "<hr>" : "");
add_word ("</div>\n");
}
}
@@ -1033,8 +1096,7 @@ cm_node ()
/* Cross-reference target at an arbitrary spot. */
void
-cm_anchor (arg)
- int arg;
+cm_anchor (int arg)
{
char *anchor;
char *fname_for_anchor = NULL;
@@ -1170,9 +1232,7 @@ cm_anchor (arg)
/* Find NODE in REF_LIST. */
static NODE_REF *
-find_node_reference (node, ref_list)
- char *node;
- NODE_REF *ref_list;
+find_node_reference (char *node, NODE_REF *ref_list)
{
NODE_REF *orig_ref_list = ref_list;
char *expanded_node;
@@ -1210,7 +1270,7 @@ find_node_reference (node, ref_list)
}
void
-free_node_references ()
+free_node_references (void)
{
NODE_REF *list, *temp;
@@ -1228,7 +1288,7 @@ free_node_references ()
}
void
-free_node_node_references ()
+free_node_node_references (void)
{
NODE_REF *list, *temp;
@@ -1247,8 +1307,7 @@ free_node_node_references ()
/* Return the number assigned to a named node in either the tag_table
or node_references list or zero if no number has been assigned. */
int
-number_of_node (node)
- char *node;
+number_of_node (char *node)
{
NODE_REF *temp_ref;
TAG_ENTRY *temp_node = find_node (node);
@@ -1270,10 +1329,7 @@ number_of_node (node)
Menu, Cross, Next, etc. */
static int
-validate (tag, line, label)
- char *tag;
- int line;
- char *label;
+validate (char *tag, int line, const char *label)
{
TAG_ENTRY *result;
@@ -1299,8 +1355,7 @@ validate (tag, line, label)
the `validate' routine. They are only used in messages, thus are
translated. */
static const char *
-reftype_type_string (type)
- enum reftype type;
+reftype_type_string (enum reftype type)
{
switch (type)
{
@@ -1314,8 +1369,7 @@ reftype_type_string (type)
}
static void
-validate_other_references (ref_list)
- NODE_REF *ref_list;
+validate_other_references (NODE_REF *ref_list)
{
char *old_input_filename = input_filename;
@@ -1344,8 +1398,7 @@ validate_other_references (ref_list)
If the Next is different from the Next of the Up,
then the Next node must have a Prev pointing at this node. */
void
-validate_file (tag_table)
- TAG_ENTRY *tag_table;
+validate_file (TAG_ENTRY *tag_table)
{
char *old_input_filename = input_filename;
TAG_ENTRY *tags = tag_table;
@@ -1384,7 +1437,7 @@ validate_file (tag_table)
tem1 = expand_node_name (prev);
tem2 = expand_node_name (tags->node);
- if (STREQ (tem1, tem2))
+ if (tem1 && tem2 && STREQ (tem1, tem2))
you_lose = 0;
free (tem1);
free (tem2);
@@ -1590,8 +1643,7 @@ validate_file (tag_table)
This means only anchors follow. */
static int
-last_node_p (tags)
- TAG_ENTRY *tags;
+last_node_p (TAG_ENTRY *tags)
{
int last = 1;
while (tags->next_ent) {
@@ -1609,23 +1661,91 @@ last_node_p (tags)
}
+static char *
+enumerate_filename (char *pathname, char *basename, int number)
+{
+ /* Do we need to generate names of subfiles which don't exceed 8+3 limits? */
+ const int dos_file_names = !HAVE_LONG_FILENAMES (pathname ? pathname : ".");
+ unsigned name_len = strlen (basename);
+ char *filename = xmalloc (10 + strlen (pathname) + name_len);
+ char *base_filename = xmalloc (10 + name_len);
+
+ sprintf (base_filename, "%s-%d", basename, number);
+
+ if (dos_file_names)
+ {
+ char *dot = strchr (base_filename, '.');
+ unsigned base_len = strlen (base_filename);
+
+ if (dot)
+ { /* Make foobar.i1, .., foobar.i99, foobar.100, ... */
+ dot[1] = 'i';
+ memmove (number <= 99 ? dot + 2 : dot + 1,
+ base_filename + name_len + 1,
+ strlen (base_filename + name_len + 1) + 1);
+ }
+ else if (base_len > 8)
+ {
+ /* Make foobar-1, .., fooba-10, .., foob-100, ... */
+ unsigned numlen = base_len - name_len;
+
+ memmove (base_filename + 8 - numlen, base_filename + name_len, numlen + 1);
+ }
+ }
+
+ sprintf (filename, "%s%s", pathname, base_filename);
+
+ return filename;
+}
+
+/* Remove previously split files, to avoid
+ lingering parts of shrinked documents. */
+void
+clean_old_split_files (char *filename)
+{
+ char *root_filename = filename_part (filename);
+ char *root_pathname = pathname_part (filename);
+ int i;
+
+ /* We break as soon as we hit an inexistent file,
+ so looping until large numbers is harmless. */
+ for (i = 1; i < 1000; i++)
+ {
+ struct stat st;
+ char *check_file = enumerate_filename (root_pathname, root_filename, i);
+
+ if (stat (check_file, &st) != 0)
+ break;
+ else if (!S_ISDIR (st.st_mode))
+ {
+ /* Give feedback if requested, removing a file is important. */
+ if (verbose_mode)
+ printf (_("Removing %s\n"), check_file);
+
+ /* Warn user that we cannot remove the file. */
+ if (unlink (check_file) != 0)
+ warning (_("Can't remove file `%s': %s"), check_file, strerror (errno));
+ }
+
+ free (check_file);
+ }
+}
+
+
/* Split large output files into a series of smaller files. Each file
is pointed to in the tag table, which then gets written out as the
original file. The new files have the same name as the original file
with a "-num" attached. SIZE is the largest number of bytes to allow
in any single split file. */
void
-split_file (filename, size)
- char *filename;
- int size;
+split_file (char *filename, int size)
{
char *root_filename, *root_pathname;
- char *the_file, *filename_part ();
+ char *the_file;
struct stat fileinfo;
long file_size;
char *the_header;
int header_size;
- int dos_file_names = 0; /* if nonzero, don't exceed 8+3 limits */
/* Can only do this to files with tag tables. */
if (!tag_table)
@@ -1639,16 +1759,13 @@ split_file (filename, size)
return;
file_size = (long) fileinfo.st_size;
- the_file = find_and_load (filename);
+ the_file = find_and_load (filename, 0);
if (!the_file)
return;
root_filename = filename_part (filename);
root_pathname = pathname_part (filename);
- /* Do we need to generate names of subfiles which don't exceed 8+3 limits? */
- dos_file_names = !HAVE_LONG_FILENAMES (root_pathname ? root_pathname : ".");
-
if (!root_pathname)
root_pathname = xstrdup ("");
@@ -1751,36 +1868,9 @@ split_file (filename, size)
write_region:
{
int fd;
- char *split_filename, *split_basename;
- unsigned root_len = strlen (root_filename);
-
- split_filename = xmalloc (10 + strlen (root_pathname)
- + root_len);
- split_basename = xmalloc (10 + root_len);
- sprintf (split_basename, "%s-%d", root_filename, which_file);
- if (dos_file_names)
- {
- char *dot = strchr (split_basename, '.');
- unsigned base_len = strlen (split_basename);
-
- if (dot)
- { /* Make foobar.i1, .., foobar.i99, foobar.100, ... */
- dot[1] = 'i';
- memmove (which_file <= 99 ? dot + 2 : dot + 1,
- split_basename + root_len + 1,
- strlen (split_basename + root_len + 1) + 1);
- }
- else if (base_len > 8)
- {
- /* Make foobar-1, .., fooba-10, .., foob-100, ... */
- unsigned numlen = base_len - root_len;
-
- memmove (split_basename + 8 - numlen,
- split_basename + root_len, numlen + 1);
- }
- }
- sprintf (split_filename, "%s%s", root_pathname,
- split_basename);
+ char *split_filename = enumerate_filename (root_pathname,
+ root_filename, which_file);
+ char *split_basename = filename_part (split_filename);
fd = open (split_filename, O_WRONLY|O_TRUNC|O_CREAT, 0666);
if (fd < 0
@@ -1840,7 +1930,7 @@ split_file (filename, size)
/* preserve local variables in info output. */
if (trailer)
{
- insert_string (trailer);
+ fwrite (trailer, 1, trailer_len, output_stream);
free (trailer);
}
diff --git a/contrib/texinfo/makeinfo/node.h b/contrib/texinfo/makeinfo/node.h
index a625e88..766c503 100644
--- a/contrib/texinfo/makeinfo/node.h
+++ b/contrib/texinfo/makeinfo/node.h
@@ -1,5 +1,5 @@
/* node.h -- declarations for Node.
- $Id: node.h,v 1.1 2002/08/25 23:38:39 karl Exp $
+ $Id: node.h,v 1.2 2004/04/11 17:56:47 karl Exp $
Copyright (C) 1996, 1997, 1998, 1999, 2002 Free Software Foundation, Inc.
@@ -22,6 +22,8 @@
#ifndef NODE_H
#define NODE_H
+#include "xref.h"
+
/* The various references that we know about. */
/* What we remember for each node. */
typedef struct tentry
@@ -39,6 +41,7 @@ typedef struct tentry
int number; /* Number for this node, relevant for HTML
splitting -- from use+define order, not just
define. */
+ int order; /* The order of the tag, starting from zero. */
char *html_fname; /* The HTML file to which this node is written
(non-NULL only for HTML splitting). */
} TAG_ENTRY;
@@ -85,6 +88,9 @@ extern TAG_ENTRY *tag_table;
/* Counter for setting node_ref.number; zero is Top. */
extern int node_number;
+/* Node order counter. */
+extern int node_order;
+
/* The current node's section level. */
extern int current_section;
@@ -92,22 +98,32 @@ extern int current_section;
corresponding to the current node in HTML mode. */
extern int outstanding_node;
-extern TAG_ENTRY *find_node ();
+extern TAG_ENTRY *find_node (char *name);
/* A search string which is used to find a line defining a node. */
DECLARE (char *, node_search_string, "\n@node ");
/* Extract node name from a menu item. */
-extern char *glean_node_from_menu ();
+extern char *glean_node_from_menu (int remember_ref, enum reftype ref_type);
/* Remember a node for later validation. */
-extern void remember_node_reference ();
+extern void remember_node_reference (char *node, int line, enum reftype type);
/* Remember the name of the current output file. */
-extern void set_current_output_filename ();
+extern void set_current_output_filename (const char *fname);
/* Expand macros and commands in the node name and canonicalize
whitespace in the resulting expansion. */
-extern char *expand_node_name ();
+extern char *expand_node_name (char *node);
+
+extern int number_of_node (char *node);
+
+extern void init_tag_table (void);
+extern void write_tag_table (char *filename);
+extern void free_node_references (void);
+extern void free_node_node_references (void);
+extern void validate_file (TAG_ENTRY *tag_table);
+extern void split_file (char *filename, int size);
+extern void clean_old_split_files (char *filename);
#endif /* NODE_H */
diff --git a/contrib/texinfo/makeinfo/sectioning.c b/contrib/texinfo/makeinfo/sectioning.c
index cd04dfa..ce32aeb 100644
--- a/contrib/texinfo/makeinfo/sectioning.c
+++ b/contrib/texinfo/makeinfo/sectioning.c
@@ -1,7 +1,7 @@
/* sectioning.c -- for @chapter, @section, ..., @contents ...
- $Id: sectioning.c,v 1.10 2003/05/13 16:37:54 karl Exp $
+ $Id: sectioning.c,v 1.25 2004/07/05 22:23:23 karl Exp $
- Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -34,6 +34,7 @@ section_alist_type section_alist[] = {
{ "unnumberedsubsec", 4, ENUM_SECT_NO, TOC_YES },
{ "unnumberedsec", 3, ENUM_SECT_NO, TOC_YES },
{ "unnumbered", 2, ENUM_SECT_NO, TOC_YES },
+ { "centerchap", 2, ENUM_SECT_NO, TOC_YES },
{ "appendixsubsubsec", 5, ENUM_SECT_APP, TOC_YES }, /* numbered like A.X.X.X */
{ "appendixsubsec", 4, ENUM_SECT_APP, TOC_YES },
@@ -81,14 +82,18 @@ static char *scoring_characters = "*=-.";
/* Amount to offset the name of sectioning commands to levels by. */
static int section_alist_offset = 0;
+/* These two variables are for @float, @cindex like commands that need to know
+ in which section they are used. */
+/* Last value returned by get_sectioning_number. */
+static char *last_sectioning_number = "";
+/* Last title used by sectioning_underscore, etc. */
+static char *last_sectioning_title = "";
/* num == ENUM_SECT_NO means unnumbered (should never call this)
num == ENUM_SECT_YES means numbered
num == ENUM_SECT_APP means numbered like A.1 and so on */
-char *
-get_sectioning_number (level, num)
- int level;
- int num;
+static char *
+get_sectioning_number (int level, int num)
{
static char s[100]; /* should ever be enough for 99.99.99.99
Appendix A.1 */
@@ -114,9 +119,14 @@ get_sectioning_number (level, num)
if ((num == ENUM_SECT_APP)
&& (i == 0)
&& (enum_marker == APPENDIX_MAGIC))
- sprintf (p, _("Appendix %c "), numbers[i] + 64);
+ sprintf (p, _("Appendix %c"), numbers[i] + 64);
else
- sprintf (p, "%d ", numbers[i]);
+ sprintf (p, "%d", numbers[i]);
+
+ /* Poor man's cache :-) */
+ if (strlen (last_sectioning_number))
+ free (last_sectioning_number);
+ last_sectioning_number = xstrdup (s);
return s;
}
@@ -124,8 +134,7 @@ get_sectioning_number (level, num)
/* Set the level of @top to LEVEL. Return the old level of @top. */
int
-set_top_section_level (level)
- int level;
+set_top_section_level (int level)
{
int i, result = -1;
@@ -141,9 +150,8 @@ set_top_section_level (level)
/* return the index of the given sectioning command in section_alist */
-int
-search_sectioning (text)
- char *text;
+static int
+search_sectioning (char *text)
{
int i;
char *t;
@@ -162,10 +170,13 @@ search_sectioning (text)
return -1;
}
-/* Return an integer which identifies the type section present in TEXT. */
+/* Return an integer which identifies the type of section present in
+ TEXT -- 1 for @top, 2 for chapters, ..., 5 for subsubsections (as
+ specified in section_alist). We take into account any @lowersections
+ and @raisesections. If SECNAME is non-NULL, also return the
+ corresponding section name. */
int
-what_section (text)
- char *text;
+what_section (char *text, char **secname)
{
int index, j;
char *temp;
@@ -205,126 +216,213 @@ what_section (text)
if (return_val < 0)
return_val = 0;
else if (return_val > 5)
- return_val = 5;
+ return_val = 5;
+
+ if (secname)
+ {
+ int i;
+ int alist_size = sizeof (section_alist) / sizeof(section_alist_type);
+ /* Find location of offset sectioning entry, but don't go off
+ either end of the array. */
+ int index_offset = MAX (index - section_alist_offset, 0);
+ index_offset = MIN (index_offset, alist_size - 1);
+
+ /* Also make sure we don't go into the next "group" of
+ sectioning changes, e.g., change from an @appendix to an
+ @heading or some such. */
+#define SIGN(expr) ((expr) < 0 ? -1 : 1)
+ for (i = index; i != index_offset; i -= SIGN (section_alist_offset))
+ {
+ /* As it happens, each group has unique .num/.toc values. */
+ if (section_alist[i].num != section_alist[index_offset].num
+ || section_alist[i].toc != section_alist[index_offset].toc)
+ break;
+ }
+ *secname = section_alist[i].name;
+ }
return return_val;
}
return -1;
}
-void
-sectioning_underscore (cmd)
- char *cmd;
+/* Returns current top level division (ie. chapter, unnumbered) number.
+ - For chapters, returns the number.
+ - For unnumbered sections, returns empty string.
+ - For appendices, returns A, B, etc. */
+char *
+current_chapter_number (void)
{
- /* If we're not indenting the first paragraph, we shall make it behave
- like @noindent is called directly after the section heading. */
- if (! do_first_par_indent)
- cm_noindent ();
-
- if (xml)
+ if (enum_marker == UNNUMBERED_MAGIC)
+ return xstrdup ("");
+ else if (enum_marker == APPENDIX_MAGIC)
{
- char *temp;
- int level;
- temp = xmalloc (2 + strlen (cmd));
- temp[0] = COMMAND_PREFIX;
- strcpy (&temp[1], cmd);
- level = what_section (temp);
- level -= 2;
- free (temp);
- xml_close_sections (level);
- /* Mark the beginning of the section
- If the next command is printindex, we will remove
- the section and put an Index instead */
- flush_output ();
- xml_last_section_output_position = output_paragraph_offset;
-
- xml_insert_element (xml_element (cmd), START);
- xml_insert_element (TITLE, START);
- xml_open_section (level, cmd);
- get_rest_of_line (0, &temp);
- execute_string ("%s\n", temp);
- free (temp);
- xml_insert_element (TITLE, END);
+ char s[1];
+ sprintf (s, "%c", numbers[0] + 64);
+ return xstrdup (s);
}
else
{
- char character;
- char *temp;
+ char s[5];
+ sprintf (s, "%d", numbers[0]);
+ return xstrdup (s);
+ }
+}
+
+/* Returns number of the last sectioning command used. */
+char *
+current_sectioning_number (void)
+{
+ if (enum_marker == UNNUMBERED_MAGIC || !number_sections)
+ return xstrdup ("");
+ else
+ return xstrdup (last_sectioning_number);
+}
+
+/* Returns arguments of the last sectioning command used. */
+char *
+current_sectioning_name (void)
+{
+ return xstrdup (last_sectioning_title);
+}
+
+/* insert_and_underscore, sectioning_underscore and sectioning_html call this. */
+
+static char *
+handle_enum_increment (int level, int index)
+{
+ /* Here is how TeX handles enumeration:
+ - Anything starting with @unnumbered is not enumerated.
+ - @majorheading and the like are not enumberated. */
+ int i;
+
+ /* First constraint above. */
+ if (enum_marker == UNNUMBERED_MAGIC && level == 0)
+ return xstrdup ("");
+
+ /* Second constraint. */
+ if (section_alist[index].num == ENUM_SECT_NO)
+ return xstrdup ("");
+
+ /* reset all counters which are one level deeper */
+ for (i = level; i < 3; i++)
+ numbers [i + 1] = 0;
+
+ numbers[level]++;
+ if (section_alist[index].num == ENUM_SECT_NO || enum_marker == UNNUMBERED_MAGIC
+ || !number_sections)
+ return xstrdup ("");
+ else
+ return xstrdup (get_sectioning_number (level, section_alist[index].num));
+}
+
+
+void
+sectioning_underscore (char *cmd)
+{
+ char *temp, *secname;
int level;
+
+ /* If we're not indenting the first paragraph, we shall make it behave
+ like @noindent is called directly after the section heading. */
+ if (! do_first_par_indent)
+ cm_noindent ();
temp = xmalloc (2 + strlen (cmd));
temp[0] = COMMAND_PREFIX;
strcpy (&temp[1], cmd);
- level = what_section (temp);
- free (temp);
+ level = what_section (temp, &secname);
level -= 2;
-
if (level < 0)
level = 0;
+ free (temp);
- if (html)
- sectioning_html (level, cmd);
- else
+ /* If the argument to @top is empty, we try using the one from @settitle.
+ Warn if both are unusable. */
+ if (STREQ (command, "top"))
{
- character = scoring_characters[level];
- insert_and_underscore (level, character, cmd);
- }
- }
-}
+ int save_input_text_offset = input_text_offset;
-/* insert_and_underscore and sectioning_html are the
- only functions which call this.
- I have created this, because it was exactly the same
- code in both functions. */
-static char *
-handle_enum_increment (level, index)
- int level;
- int index;
-{
- /* special for unnumbered */
- if (number_sections && section_alist[index].num == ENUM_SECT_NO)
- {
- if (level == 0
- && enum_marker != UNNUMBERED_MAGIC)
- enum_marker = UNNUMBERED_MAGIC;
+ get_rest_of_line (0, &temp);
+
+ /* Due to get_rest_of_line ... */
+ line_number--;
+
+ if (strlen (temp) == 0 && (!title || strlen (title) == 0))
+ warning ("Must specify a title with least one of @settitle or @top");
+
+ input_text_offset = save_input_text_offset;
}
- /* enumerate only things which are allowed */
- if (number_sections && section_alist[index].num)
+
+ if (xml)
{
- /* reset the marker if we get into enumerated areas */
- if (section_alist[index].num == ENUM_SECT_YES
- && level == 0
- && enum_marker == UNNUMBERED_MAGIC)
- enum_marker = 0;
- /* This is special for appendix; if we got the first
- time an appendix command then we are entering appendix.
- Thats the point we have to start countint with A, B and so on. */
- if (section_alist[index].num == ENUM_SECT_APP
- && level == 0
- && enum_marker != APPENDIX_MAGIC)
- {
- enum_marker = APPENDIX_MAGIC;
- numbers [0] = 0; /* this means we start with Appendix A */
- }
+ /* If the section appears in the toc, it means it's a real section
+ unlike majorheading, chapheading etc. */
+ if (section_alist[search_sectioning (cmd)].toc == TOC_YES)
+ {
+ xml_close_sections (level);
+ /* Mark the beginning of the section
+ If the next command is printindex, we will remove
+ the section and put an Index instead */
+ flush_output ();
+ xml_last_section_output_position = output_paragraph_offset;
+
+ get_rest_of_line (0, &temp);
+
+ /* Use @settitle value if @top parameter is empty. */
+ if (STREQ (command, "top") && strlen(temp) == 0)
+ temp = xstrdup (title ? title : "");
+
+ /* Docbook does not support @unnumbered at all. So we provide numbers
+ that other formats use. @appendix seems to be fine though, so we let
+ Docbook handle that as usual. */
+ if (docbook && enum_marker != APPENDIX_MAGIC)
+ {
+ if (section_alist[search_sectioning (cmd)].num == ENUM_SECT_NO
+ && section_alist[search_sectioning (cmd)].toc == TOC_YES)
+ xml_insert_element_with_attribute (xml_element (secname),
+ START, "label=\"%s\" xreflabel=\"%s\"",
+ handle_enum_increment (level, search_sectioning (cmd)),
+ text_expansion (temp));
+ else
+ xml_insert_element_with_attribute (xml_element (secname),
+ START, "label=\"%s\"",
+ handle_enum_increment (level, search_sectioning (cmd)));
+ }
+ else
+ xml_insert_element (xml_element (secname), START);
+
+ xml_insert_element (TITLE, START);
+ xml_open_section (level, secname);
+ execute_string ("%s", temp);
+ xml_insert_element (TITLE, END);
- /* only increment counters if we are not in unnumbered
- area. This handles situations like this:
- @unnumbered .... This sets enum_marker to UNNUMBERED_MAGIC
- @section .... */
- if (enum_marker != UNNUMBERED_MAGIC)
+ free (temp);
+ }
+ else
{
- int i;
+ if (docbook)
+ {
+ if (level > 0)
+ xml_insert_element_with_attribute (xml_element (secname), START,
+ "renderas=\"sect%d\"", level);
+ else
+ xml_insert_element_with_attribute (xml_element (secname), START,
+ "renderas=\"other\"");
+ }
+ else
+ xml_insert_element (xml_element (secname), START);
- /* reset all counters which are one level deeper */
- for (i = level; i < 3; i++)
- numbers [i + 1] = 0;
+ get_rest_of_line (0, &temp);
+ execute_string ("%s", temp);
+ free (temp);
- numbers[level]++;
- return xstrdup
- (get_sectioning_number (level, section_alist[index].num));
+ xml_insert_element (xml_element (secname), END);
}
- } /* if (number_sections)... */
-
- return xstrdup ("");
+ }
+ else if (html)
+ sectioning_html (level, secname);
+ else
+ insert_and_underscore (level, secname);
}
@@ -332,16 +430,14 @@ handle_enum_increment (level, index)
in a new, separate paragraph. Directly underneath it, insert a
line of WITH_CHAR, the same length of the inserted text. */
void
-insert_and_underscore (level, with_char, cmd)
- int level;
- int with_char;
- char *cmd;
+insert_and_underscore (int level, char *cmd)
{
int i, len;
int index;
int old_no_indent;
unsigned char *starting_pos, *ending_pos;
char *temp;
+ char with_char = scoring_characters[level];
close_paragraph ();
filling_enabled = indented_fill = 0;
@@ -352,13 +448,23 @@ insert_and_underscore (level, with_char, cmd)
append_to_expansion_output (input_text_offset + 1);
get_rest_of_line (0, &temp);
+
+ /* Use @settitle value if @top parameter is empty. */
+ if (STREQ (command, "top") && strlen(temp) == 0)
+ temp = xstrdup (title ? title : "");
+
starting_pos = output_paragraph + output_paragraph_offset;
+ /* Poor man's cache for section title. */
+ if (strlen (last_sectioning_title))
+ free (last_sectioning_title);
+ last_sectioning_title = xstrdup (temp);
+
index = search_sectioning (cmd);
if (index < 0)
{
/* should never happen, but a poor guy, named Murphy ... */
- warning (_("Internal error (search_sectioning) \"%s\"!"), cmd);
+ warning (_("Internal error (search_sectioning) `%s'!"), cmd);
return;
}
@@ -367,7 +473,7 @@ insert_and_underscore (level, with_char, cmd)
output. */
/* Step 1: produce "X.Y" and add it to Info output. */
- add_word (handle_enum_increment (level, index));
+ add_word_args ("%s ", handle_enum_increment (level, index));
/* Step 2: add "SECTION-NAME" to both Info and macro-expanded output. */
if (macro_expansion_output_stream && !executing_string)
@@ -404,9 +510,7 @@ insert_and_underscore (level, with_char, cmd)
tagged as an anchor for the current node.. */
void
-sectioning_html (level, cmd)
- int level;
- char *cmd;
+sectioning_html (int level, char *cmd)
{
static int toc_ref_count = 0;
int index;
@@ -419,10 +523,8 @@ sectioning_html (level, cmd)
old_no_indent = no_indent;
no_indent = 1;
- /* level 0 (chapter) is <h2>, everything else is <h3>. We don't want
- to go lower than that because browsers then start rendering the
- headings smaller than the text. */
- add_word_args ("<h%d class=\"%s\">", MIN (3, level + 2), cmd);
+ /* level 0 (chapter) is <h2>, and we go down from there. */
+ add_html_block_elt_args ("<h%d class=\"%s\">", level + 2, cmd);
/* If we are outside of any node, produce an anchor that
the TOC could refer to. */
@@ -449,6 +551,10 @@ sectioning_html (level, cmd)
get_rest_of_line (0, &temp);
+ /* Use @settitle value if @top parameter is empty. */
+ if (STREQ (command, "top") && strlen(temp) == 0)
+ temp = xstrdup (title ? title : "");
+
index = search_sectioning (cmd);
if (index < 0)
{
@@ -458,7 +564,11 @@ sectioning_html (level, cmd)
}
/* Produce "X.Y" and add it to HTML output. */
- add_word (handle_enum_increment (level, index));
+ {
+ char *title_number = handle_enum_increment (level, index);
+ if (strlen (title_number) > 0)
+ add_word_args ("%s ", title_number);
+ }
/* add the section name to both HTML and macro-expanded output. */
if (macro_expansion_output_stream && !executing_string)
@@ -492,7 +602,7 @@ sectioning_html (level, cmd)
/* Shift the meaning of @section to @chapter. */
void
-cm_raisesections ()
+cm_raisesections (void)
{
discard_until ("\n");
section_alist_offset--;
@@ -500,7 +610,7 @@ cm_raisesections ()
/* Shift the meaning of @chapter to @section. */
void
-cm_lowersections ()
+cm_lowersections (void)
{
discard_until ("\n");
section_alist_offset++;
@@ -508,8 +618,7 @@ cm_lowersections ()
/* The command still works, but prints a warning message in addition. */
void
-cm_ideprecated (arg, start, end)
- int arg, start, end;
+cm_ideprecated (int arg, int start, int end)
{
warning (_("%c%s is obsolete; use %c%s instead"),
COMMAND_PREFIX, command, COMMAND_PREFIX, command + 1);
@@ -520,7 +629,7 @@ cm_ideprecated (arg, start, end)
/* Treat this just like @unnumbered. The only difference is
in node defaulting. */
void
-cm_top ()
+cm_top (void)
{
/* It is an error to have more than one @top. */
if (top_node_seen && strcmp (current_node, "Top") != 0)
@@ -584,7 +693,8 @@ cm_top ()
if (input_text_offset < input_text_length)
input_text_offset++;
- this_section = what_section (input_text + input_text_offset);
+ this_section = what_section (input_text + input_text_offset,
+ NULL);
/* If we found a sectioning command, then give the top section
a level of this section - 1. */
@@ -598,42 +708,44 @@ cm_top ()
/* The remainder of the text on this line is a chapter heading. */
void
-cm_chapter ()
+cm_chapter (void)
{
+ enum_marker = 0;
sectioning_underscore ("chapter");
}
/* The remainder of the text on this line is a section heading. */
void
-cm_section ()
+cm_section (void)
{
sectioning_underscore ("section");
}
/* The remainder of the text on this line is a subsection heading. */
void
-cm_subsection ()
+cm_subsection (void)
{
sectioning_underscore ("subsection");
}
/* The remainder of the text on this line is a subsubsection heading. */
void
-cm_subsubsection ()
+cm_subsubsection (void)
{
sectioning_underscore ("subsubsection");
}
/* The remainder of the text on this line is an unnumbered heading. */
void
-cm_unnumbered ()
+cm_unnumbered (void)
{
+ enum_marker = UNNUMBERED_MAGIC;
sectioning_underscore ("unnumbered");
}
/* The remainder of the text on this line is an unnumbered section heading. */
void
-cm_unnumberedsec ()
+cm_unnumberedsec (void)
{
sectioning_underscore ("unnumberedsec");
}
@@ -641,7 +753,7 @@ cm_unnumberedsec ()
/* The remainder of the text on this line is an unnumbered
subsection heading. */
void
-cm_unnumberedsubsec ()
+cm_unnumberedsubsec (void)
{
sectioning_underscore ("unnumberedsubsec");
}
@@ -649,28 +761,32 @@ cm_unnumberedsubsec ()
/* The remainder of the text on this line is an unnumbered
subsubsection heading. */
void
-cm_unnumberedsubsubsec ()
+cm_unnumberedsubsubsec (void)
{
sectioning_underscore ("unnumberedsubsubsec");
}
/* The remainder of the text on this line is an appendix heading. */
void
-cm_appendix ()
+cm_appendix (void)
{
+ /* Reset top level number so we start from Appendix A */
+ if (enum_marker != APPENDIX_MAGIC)
+ numbers [0] = 0;
+ enum_marker = APPENDIX_MAGIC;
sectioning_underscore ("appendix");
}
/* The remainder of the text on this line is an appendix section heading. */
void
-cm_appendixsec ()
+cm_appendixsec (void)
{
sectioning_underscore ("appendixsec");
}
/* The remainder of the text on this line is an appendix subsection heading. */
void
-cm_appendixsubsec ()
+cm_appendixsubsec (void)
{
sectioning_underscore ("appendixsubsec");
}
@@ -678,38 +794,38 @@ cm_appendixsubsec ()
/* The remainder of the text on this line is an appendix
subsubsection heading. */
void
-cm_appendixsubsubsec ()
+cm_appendixsubsubsec (void)
{
sectioning_underscore ("appendixsubsubsec");
}
/* Compatibility functions substitute for chapter, section, etc. */
void
-cm_majorheading ()
+cm_majorheading (void)
{
sectioning_underscore ("majorheading");
}
void
-cm_chapheading ()
+cm_chapheading (void)
{
sectioning_underscore ("chapheading");
}
void
-cm_heading ()
+cm_heading (void)
{
sectioning_underscore ("heading");
}
void
-cm_subheading ()
+cm_subheading (void)
{
sectioning_underscore ("subheading");
}
void
-cm_subsubheading ()
+cm_subsubheading (void)
{
sectioning_underscore ("subsubheading");
}
diff --git a/contrib/texinfo/makeinfo/sectioning.h b/contrib/texinfo/makeinfo/sectioning.h
index 455fc32..8c3f220 100644
--- a/contrib/texinfo/makeinfo/sectioning.h
+++ b/contrib/texinfo/makeinfo/sectioning.h
@@ -1,7 +1,7 @@
/* sectioning.h -- all related stuff @chapter, @section... @contents
- $Id: sectioning.h,v 1.1 2002/08/25 23:38:39 karl Exp $
+ $Id: sectioning.h,v 1.5 2004/04/11 17:56:47 karl Exp $
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2003 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,28 +23,51 @@
#define SECTIONING_H
/* Sectioning. */
-extern void
- cm_chapter (), cm_unnumbered (), cm_appendix (), cm_top (),
- cm_section (), cm_unnumberedsec (), cm_appendixsec (),
- cm_subsection (), cm_unnumberedsubsec (), cm_appendixsubsec (),
- cm_subsubsection (), cm_unnumberedsubsubsec (), cm_appendixsubsubsec (),
- cm_heading (), cm_chapheading (), cm_subheading (), cm_subsubheading (),
- cm_majorheading (), cm_raisesections (), cm_lowersections (),
- cm_ideprecated ();
+/* Level 4. */
+extern void cm_chapter (void),
+ cm_unnumbered (void),
+ cm_appendix (void),
+ cm_top (void);
+
+/* Level 3. */
+extern void cm_section (void),
+ cm_unnumberedsec (void),
+ cm_appendixsec (void);
+
+/* Level 2. */
+extern void cm_subsection (void),
+ cm_unnumberedsubsec (void),
+ cm_appendixsubsec (void);
+
+/* Level 1. */
+extern void cm_subsubsection (void),
+ cm_unnumberedsubsubsec (void),
+ cm_appendixsubsubsec (void);
+
+/* Headings. */
+extern void cm_heading (void),
+ cm_chapheading (void),
+ cm_subheading (void),
+ cm_subsubheading (void),
+ cm_majorheading (void);
+
+extern void cm_raisesections (void),
+ cm_lowersections (void),
+ cm_ideprecated (int arg, int start, int end);
extern void
- sectioning_underscore (), insert_and_underscore ();
-
-extern int what_section ();
-
-
+ sectioning_underscore (char *cmd),
+ insert_and_underscore (int level, char *cmd);
-/* is needed in node.c */
-extern int set_top_section_level ();
+/* needed in node.c */
+extern int set_top_section_level (int level);
-extern void sectioning_html ();
-extern int what_section ();
+extern void sectioning_html (int level, char *cmd);
+extern int what_section (char *text, char **secname);
+extern char *current_chapter_number (void),
+ *current_sectioning_number (void),
+ *current_sectioning_name (void);
/* The argument of @settitle, used for HTML. */
extern char *title;
diff --git a/contrib/texinfo/makeinfo/toc.c b/contrib/texinfo/makeinfo/toc.c
index 394a480..fa3d8e0 100644
--- a/contrib/texinfo/makeinfo/toc.c
+++ b/contrib/texinfo/makeinfo/toc.c
@@ -1,7 +1,7 @@
/* toc.c -- table of contents handling.
- $Id: toc.c,v 1.3 2002/11/07 16:13:59 karl Exp $
+ $Id: toc.c,v 1.6 2004/04/11 17:56:47 karl Exp $
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -30,36 +30,20 @@
#include "makeinfo.h"
#include "sectioning.h"
#include "toc.h"
+#include "xml.h"
-
-
/* array of toc entries */
static TOC_ENTRY_ELT **toc_entry_alist = NULL;
/* toc_counter start from 0 ... n for every @chapter, @section ... */
static int toc_counter = 0;
-
-/* the file where we found the @contents directive */
-char *contents_filename;
-
-/* the file where we found the @shortcontents directive */
-char *shortcontents_filename;
-
-static const char contents_placebo[] = "\n...Table of Contents...\n";
-static const char shortcontents_placebo[] = "\n...Short Contents...\n";
-static const char lots_of_stars[] =
-"***************************************************************************";
-
/* Routine to add an entry to the table of contents */
int
-toc_add_entry (tocname, level, node_name, anchor)
- char *tocname;
- int level;
- char *node_name;
- char *anchor;
+toc_add_entry (char *tocname, int level, char *node_name, char *anchor)
{
- char *tocname_and_node, *expanded_node, *s, *d;
+ char *tocname_and_node, *expanded_node, *d;
+ char *s = NULL;
char *filename = NULL;
if (!node_name)
@@ -107,14 +91,11 @@ toc_add_entry (tocname, level, node_name, anchor)
{
for (; *s; s++)
{
- if (*s == '&')
- {
- strcpy (d, "&amp;");
- d += 5;
- }
+ if (cr_or_whitespace (*s))
+ *d++ = '-';
else if (! URL_SAFE_CHAR (*s))
{
- sprintf (d, "%%%x", (unsigned char) *s);
+ sprintf (d, "_00%x", (unsigned char) *s);
/* do this manually since sprintf returns char * on
SunOS 4 and other old systems. */
while (*d)
@@ -165,8 +146,7 @@ toc_add_entry (tocname, level, node_name, anchor)
more than a single chapter structioning command in a node,
or if they have a node without any structuring commands. */
char *
-toc_find_section_of_node (node)
- char *node;
+toc_find_section_of_node (char *node)
{
int i;
@@ -181,7 +161,7 @@ toc_find_section_of_node (node)
/* free up memory used by toc entries */
void
-toc_free ()
+toc_free (void)
{
int i;
@@ -199,13 +179,11 @@ toc_free ()
toc_counter = 0; /* to be absolutley sure ;-) */
}
}
-
/* Print table of contents in HTML. */
static void
-contents_update_html (fp)
- FILE *fp;
+contents_update_html (void)
{
int i;
int k;
@@ -216,9 +194,7 @@ contents_update_html (fp)
/* no, so return to sender ;-) */
return;
- flush_output (); /* in case we are writing stdout */
-
- fprintf (fp, "\n<div class=\"contents\">\n<h2>%s</h2>\n<ul>\n", _("Table of Contents"));
+ add_html_block_elt_args ("\n<div class=\"contents\">\n<h2>%s</h2>\n<ul>\n", _("Table of Contents"));
last_level = toc_entry_alist[0]->level;
@@ -230,14 +206,14 @@ contents_update_html (fp)
@chapter ...
@subsubsection ... ? */
for (k = 0; k < (toc_entry_alist[i]->level-last_level); k++)
- fputs ("<ul>\n", fp);
+ add_html_block_elt ("<ul>\n");
}
else if (toc_entry_alist[i]->level < last_level)
{
/* @subsubsection ...
@chapter ... this IS usual.*/
for (k = 0; k < (last_level-toc_entry_alist[i]->level); k++)
- fputs ("</li></ul>\n", fp);
+ add_word ("</li></ul>\n");
}
/* No double entries in TOC. */
@@ -245,11 +221,11 @@ contents_update_html (fp)
toc_entry_alist[i-1]->name) == 0))
{
/* each toc entry is a list item. */
- fputs ("<li>", fp);
+ add_word ("<li>");
/* Insert link -- to an external file if splitting, or
within the current document if not splitting. */
- fprintf (fp, "<a ");
+ add_word ("<a ");
/* For chapters (only), insert an anchor that the short contents
will link to. */
if (toc_entry_alist[i]->level == 0)
@@ -262,10 +238,10 @@ contents_update_html (fp)
ends, and use that in toc_FOO. */
while (*p && *p != '"')
p++;
- fprintf (fp, "name=\"toc_%.*s\" ",
+ add_word_args ("name=\"toc_%.*s\" ",
p - toc_entry_alist[i]->name, toc_entry_alist[i]->name);
}
- fprintf (fp, "href=\"%s#%s</a>\n",
+ add_word_args ("href=\"%s#%s</a>\n",
splitting ? toc_entry_alist[i]->html_file : "",
toc_entry_alist[i]->name);
}
@@ -276,16 +252,15 @@ contents_update_html (fp)
/* Go back to start level. */
if (toc_entry_alist[0]->level < last_level)
for (k = 0; k < (last_level-toc_entry_alist[0]->level); k++)
- fputs ("</li></ul>\n", fp);
+ add_word ("</li></ul>\n");
- fputs ("</li></ul>\n</div>\n\n", fp);
+ add_word ("</li></ul>\n</div>\n\n");
}
/* print table of contents in ASCII (--no-headers)
May be we should create a new command line switch --ascii ? */
static void
-contents_update_info (fp)
- FILE *fp;
+contents_update_info (void)
{
int i;
int k;
@@ -293,41 +268,40 @@ contents_update_info (fp)
if (!toc_counter)
return;
- flush_output (); /* in case we are writing stdout */
-
- fprintf (fp, "%s\n%.*s\n\n", _("Table of Contents"),
- (int) strlen (_("Table of Contents")), lots_of_stars);
+ insert_string ((char *) _("Table of Contents"));
+ insert ('\n');
+ for (i = 0; i < strlen (_("Table of Contents")); i++)
+ insert ('*');
+ insert_string ("\n\n");
for (i = 0; i < toc_counter; i++)
{
if (toc_entry_alist[i]->level == 0)
- fputs ("\n", fp);
+ add_char ('\n');
/* indention with two spaces per level, should this
changed? */
for (k = 0; k < toc_entry_alist[i]->level; k++)
- fputs (" ", fp);
+ insert_string (" ");
- fprintf (fp, "%s\n", toc_entry_alist[i]->name);
+ insert_string (toc_entry_alist[i]->name);
+ insert ('\n');
}
- fputs ("\n\n", fp);
+ insert_string ("\n\n");
}
/* shortcontents in HTML; Should this produce a standalone file? */
static void
-shortcontents_update_html (fp)
- FILE *fp;
+shortcontents_update_html (char *contents_filename)
{
int i;
- char *toc_file;
+ char *toc_file = NULL;
/* does exist any toc? */
if (!toc_counter)
return;
- flush_output (); /* in case we are writing stdout */
-
- fprintf (fp, "\n<div class=\"shortcontents\">\n<h2>%s</h2>\n<ul>\n", _("Short Contents"));
+ add_html_block_elt_args ("\n<div class=\"shortcontents\">\n<h2>%s</h2>\n<ul>\n", _("Short Contents"));
if (contents_filename)
toc_file = filename_part (contents_filename);
@@ -339,194 +313,76 @@ shortcontents_update_html (fp)
if (toc_entry_alist[i]->level == 0)
{
if (contents_filename)
- fprintf (fp, "<li><a href=\"%s#toc_%s</a></li>\n",
+ add_word_args ("<li><a href=\"%s#toc_%s</a></li>\n",
splitting ? toc_file : "", name);
else
- fprintf (fp, "<a href=\"%s#%s</a>\n",
+ add_word_args ("<a href=\"%s#%s</a>\n",
splitting ? toc_entry_alist[i]->html_file : "", name);
}
}
- fputs ("</ul>\n</div>\n\n", fp);
+ add_word ("</ul>\n</div>\n\n");
if (contents_filename)
free (toc_file);
}
/* short contents in ASCII (--no-headers). */
static void
-shortcontents_update_info (fp)
- FILE *fp;
+shortcontents_update_info (void)
{
int i;
if (!toc_counter)
return;
- flush_output (); /* in case we are writing stdout */
-
- fprintf (fp, "%s\n%.*s\n\n", _("Short Contents"),
- (int) strlen (_("Short Contents")), lots_of_stars);
+ insert_string ((char *) _("Short Contents"));
+ insert ('\n');
+ for (i = 0; i < strlen (_("Short Contents")); i++)
+ insert ('*');
+ insert_string ("\n\n");
for (i = 0; i < toc_counter; i++)
{
if (toc_entry_alist[i]->level == 0)
- fprintf (fp, "%s\n", toc_entry_alist[i]->name);
- }
- fputs ("\n\n", fp);
-}
-
-
-static FILE *toc_fp;
-static char *toc_buf;
-
-static int
-rewrite_top (fname, placebo)
- const char *fname, *placebo;
-{
- int idx;
-
- /* Can't rewrite standard output or the null device. No point in
- complaining. */
- if (STREQ (fname, "-")
- || FILENAME_CMP (fname, NULL_DEVICE) == 0
- || FILENAME_CMP (fname, ALSO_NULL_DEVICE) == 0)
- return -1;
-
- toc_buf = find_and_load (fname);
-
- if (!toc_buf)
- {
- fs_error (fname);
- return -1;
- }
-
- idx = search_forward (placebo, 0);
-
- if (idx < 0)
- {
- error (_("%s: TOC should be here, but it was not found"), fname);
- return -1;
- }
-
- toc_fp = fopen (fname, "w");
- if (!toc_fp)
- {
- fs_error (fname);
- return -1;
- }
-
- if (fwrite (toc_buf, 1, idx, toc_fp) != idx)
- {
- fs_error (fname);
- return -1;
+ {
+ insert_string (toc_entry_alist[i]->name);
+ insert ('\n');
+ }
}
-
- return idx + strlen (placebo);
-}
-
-static void
-contents_update ()
-{
- int cont_idx = rewrite_top (contents_filename, contents_placebo);
-
- if (cont_idx < 0)
- return;
-
- if (html)
- contents_update_html (toc_fp);
- else
- contents_update_info (toc_fp);
-
- if (fwrite (toc_buf + cont_idx, 1, input_text_length - cont_idx, toc_fp)
- != input_text_length - cont_idx
- || fclose (toc_fp) != 0)
- fs_error (contents_filename);
-}
-
-static void
-shortcontents_update ()
-{
- int cont_idx = rewrite_top (shortcontents_filename, shortcontents_placebo);
-
- if (cont_idx < 0)
- return;
-
- if (html)
- shortcontents_update_html (toc_fp);
- else
- shortcontents_update_info (toc_fp);
-
- if (fwrite (toc_buf + cont_idx, 1, input_text_length - cont_idx - 1, toc_fp)
- != input_text_length - cont_idx - 1
- || fclose (toc_fp) != 0)
- fs_error (shortcontents_filename);
+ insert_string ("\n\n");
}
void
-toc_update ()
+cm_contents (int arg)
{
- if (!html && !no_headers)
- return;
-
- if (contents_filename)
- contents_update ();
- if (shortcontents_filename)
- shortcontents_update ();
-}
+ /* the file where we found the @contents directive */
+ static char *contents_filename;
-void
-cm_contents (arg)
- int arg;
-{
- if ((html || no_headers) && arg == START)
+ /* No need to mess with delayed stuff for XML and Docbook. */
+ if (xml)
{
- if (contents_filename)
- {
- free (contents_filename);
- contents_filename = NULL;
- }
-
- if (contents_filename && STREQ (contents_filename, "-"))
+ if (arg == START)
{
- if (html)
- contents_update_html (stdout);
- else
- contents_update_info (stdout);
- }
- else
- {
- if (!executing_string && html)
- html_output_head ();
- contents_filename = xstrdup (current_output_filename);
- insert_string (contents_placebo); /* just mark it, for now */
+ int elt = STREQ (command, "contents") ? CONTENTS : SHORTCONTENTS;
+ xml_insert_element (elt, START);
+ xml_insert_element (elt, END);
}
}
-}
-
-void
-cm_shortcontents (arg)
- int arg;
-{
- if ((html || no_headers) && arg == START)
+ else if (!handling_delayed_writes)
{
- if (shortcontents_filename)
- {
- free (shortcontents_filename);
- shortcontents_filename = NULL;
- }
+ register_delayed_write (STREQ (command, "contents")
+ ? "@contents" : "@shortcontents");
- if (shortcontents_filename && STREQ (shortcontents_filename, "-"))
+ if (html && STREQ (command, "contents"))
{
- if (html)
- shortcontents_update_html (stdout);
- else
- shortcontents_update_info (stdout);
- }
- else
- {
- if (!executing_string && html)
- html_output_head ();
- shortcontents_filename = xstrdup (current_output_filename);
- insert_string (shortcontents_placebo); /* just mark it, for now */
+ if (contents_filename)
+ free (contents_filename);
+ contents_filename = xstrdup (current_output_filename);
}
}
+ else if (html)
+ STREQ (command, "contents")
+ ? contents_update_html () : shortcontents_update_html (contents_filename);
+ else if (no_headers)
+ STREQ (command, "contents")
+ ? contents_update_info () : shortcontents_update_info ();
}
diff --git a/contrib/texinfo/makeinfo/toc.h b/contrib/texinfo/makeinfo/toc.h
index 0d3e417..854f6fc 100644
--- a/contrib/texinfo/makeinfo/toc.h
+++ b/contrib/texinfo/makeinfo/toc.h
@@ -1,5 +1,5 @@
/* toc.h -- table of contents handling.
- $Id: toc.h,v 1.1 2002/08/25 23:38:39 karl Exp $
+ $Id: toc.h,v 1.2 2004/04/11 17:56:47 karl Exp $
Copyright (C) 1999 Free Software Foundation, Inc.
@@ -22,12 +22,6 @@
#ifndef TOC_H
#define TOC_H
-/* the file where we found the @contents directive */
-extern char *contents_filename;
-
-/* the file where we found the @shortcontents directive */
-extern char *shortcontents_filename;
-
/* Structure to hold one entry for the toc. */
typedef struct toc_entry_elt {
char *name;
@@ -41,10 +35,11 @@ typedef struct toc_entry_elt {
/* all routines which have relationship with TOC should start with
toc_ (this is a kind of name-space) */
-extern int toc_add_entry (); /* return the number for the toc-entry */
-extern void toc_free ();
-extern char *toc_find_section_of_node ();
+extern int toc_add_entry (char *tocname, int level,
+ char *node_name, char *anchor); /* return the number for the toc-entry */
+extern void toc_free (void);
+extern char *toc_find_section_of_node (char *node);
-extern void cm_contents (), cm_shortcontents ();
+extern void cm_contents (int arg);
#endif /* not TOC_H */
diff --git a/contrib/texinfo/makeinfo/xml.c b/contrib/texinfo/makeinfo/xml.c
index 83c8b56..cdbec1f 100644
--- a/contrib/texinfo/makeinfo/xml.c
+++ b/contrib/texinfo/makeinfo/xml.c
@@ -1,7 +1,7 @@
/* xml.c -- xml output.
- $Id: xml.c,v 1.19 2003/05/13 16:37:54 karl Exp $
+ $Id: xml.c,v 1.52 2004/12/19 17:02:23 karl Exp $
- Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,6 +22,8 @@
#include "system.h"
#include "makeinfo.h"
#include "insertion.h"
+#include "files.h"
+#include "float.h"
#include "macro.h"
#include "cmds.h"
#include "lang.h"
@@ -31,294 +33,436 @@
/* Options */
int xml_index_divisions = 1;
-
-void xml_close_sections (/* int level */);
-
typedef struct _element
{
char name[32];
int contains_para;
int contained_in_para;
+ int keep_space;
} element;
element texinfoml_element_list [] = {
- { "texinfo", 1, 0 },
- { "setfilename", 0, 0 },
- { "titlefont", 0, 0 },
- { "settitle", 0, 0 },
-
- { "node", 1, 0 },
- { "nodenext", 0, 0 },
- { "nodeprev", 0, 0 },
- { "nodeup", 0, 0 },
-
- { "chapter", 1, 0 },
- { "section", 1, 0 },
- { "subsection", 1, 0 },
- { "subsubsection", 1, 0 },
-
- { "top", 1, 0 },
- { "unnumbered", 1, 0 },
- { "unnumberedsec", 1, 0 },
- { "unnumberedsubsec", 1, 0 },
- { "unnumberedsubsubsec", 1, 0 },
-
- { "appendix", 1, 0 },
- { "appendixsec", 1, 0 },
- { "appendixsubsec", 1, 0 },
- { "appendixsubsubsec", 1, 0 },
-
- { "majorheading", 1, 0 },
- { "chapheading", 1, 0 },
- { "heading", 1, 0 },
- { "subheading", 1, 0 },
- { "subsubheading", 1, 0 },
-
- { "menu", 1, 0 },
- { "menuentry", 1, 0 },
- { "menutitle", 0, 0 },
- { "menucomment", 1, 0 },
- { "menunode", 0, 0 },
- { "nodename", 0, 0 },
-
- { "acronym", 0, 1 },
- { "tt", 0, 1 },
- { "code", 0, 1 },
- { "kbd", 0, 1 },
- { "url", 0, 1 },
- { "key", 0, 1 },
- { "var", 0, 1 },
- { "sc", 0, 1 },
- { "dfn", 0, 1 },
- { "emph", 0, 1 },
- { "strong", 0, 1 },
- { "cite", 0, 1 },
- { "notfixedwidth", 0, 1 },
- { "i", 0, 1 },
- { "b", 0, 1 },
- { "r", 0, 1 },
-
- { "title", 0, 0 },
- { "ifinfo", 1, 0 },
- { "sp", 0, 0 },
- { "center", 1, 0 },
- { "dircategory", 0, 0 },
- { "quotation", 0, 0 },
- { "example", 0, 0 },
- { "smallexample", 0, 0 },
- { "lisp", 0, 0 },
- { "smalllisp", 0, 0 },
- { "cartouche", 1, 0 },
- { "copying", 1, 0 },
- { "format", 0, 0 },
- { "smallformat", 0, 0 },
- { "display", 0, 0 },
- { "smalldisplay", 0, 0 },
- { "footnote", 0, 1 },
-
- { "itemize", 0, 0 },
- { "itemfunction", 0, 0 },
- { "item", 1, 0 },
- { "enumerate", 0, 0 },
- { "table", 0, 0 },
- { "tableitem", 0, 0 }, /* not used */ /* TABLEITEM */
- { "tableterm", 0, 0 }, /* not used */ /* TABLETERM */
-
- { "indexterm", 0, 1 },
-
- { "xref", 0, 1 },
- { "xrefnodename", 0, 1 },
- { "xrefinfoname", 0, 1 },
- { "xrefprinteddesc", 0, 1 },
- { "xrefinfofile", 0, 1 },
- { "xrefprintedname", 0, 1 },
-
- { "inforef", 0, 1 },
- { "inforefnodename", 0, 1 },
- { "inforefrefname", 0, 1 },
- { "inforefinfoname", 0, 1 },
-
- { "uref", 0, 1 },
- { "urefurl", 0, 1 },
- { "urefdesc", 0, 1 },
- { "urefreplacement", 0, 1 },
-
- { "email", 0, 1 },
- { "emailaddress", 0, 1 },
- { "emailname", 0, 1 },
-
- { "group", 0, 0 },
-
- { "printindex", 0, 0 },
- { "anchor", 0, 1 },
- { "image", 0, 1 },
- { "", 0, 1 }, /* PRIMARY (docbook) */
- { "", 0, 1 }, /* SECONDARY (docbook) */
- { "", 0, 0 }, /* INFORMALFIGURE (docbook) */
- { "", 0, 0 }, /* MEDIAOBJECT (docbook) */
- { "", 0, 0 }, /* IMAGEOBJECT (docbook) */
- { "", 0, 0 }, /* IMAGEDATA (docbook) */
- { "", 0, 0 }, /* TEXTOBJECT (docbook) */
- { "", 0, 0 }, /* INDEXENTRY (docbook) */
- { "", 0, 0 }, /* PRIMARYIE (docbook) */
- { "", 0, 0 }, /* SECONDARYIE (docbook) */
- { "", 0, 0 }, /* INDEXDIV (docbook) */
- { "multitable", 0, 0 },
- { "", 0, 0 }, /* TGROUP (docbook) */
- { "columnfraction", 0, 0 },
- { "", 0, 0 }, /* TBODY (docbook) */
- { "entry", 0, 0 }, /* ENTRY (docbook) */
- { "row", 0, 0 }, /* ROW (docbook) */
- { "", 0, 0 }, /* BOOKINFO (docbook) */
- { "", 0, 0 }, /* ABSTRACT (docbook) */
- { "", 0, 0 }, /* REPLACEABLE (docbook) */
- { "", 0, 0 }, /* ENVAR (docbook) */
- { "", 0, 0 }, /* COMMENT (docbook) */
- { "", 0, 0 }, /* FUNCTION (docbook) */
- { "", 0, 0 }, /* LEGALNOTICE (docbook) */
-
- { "para", 0, 0 } /* Must be last */
- /* name / contains para / contained in para */
+ { "texinfo", 1, 0, 0 },
+ { "setfilename", 0, 0, 0 },
+ { "titlefont", 0, 0, 0 },
+ { "settitle", 0, 0, 0 },
+ { "documentdescription", 1, 0, 0 },
+
+ { "node", 1, 0, 0 },
+ { "nodenext", 0, 0, 0 },
+ { "nodeprev", 0, 0, 0 },
+ { "nodeup", 0, 0, 0 },
+
+ { "chapter", 1, 0, 0 },
+ { "section", 1, 0, 0 },
+ { "subsection", 1, 0, 0 },
+ { "subsubsection", 1, 0, 0 },
+
+ { "top", 1, 0, 0 },
+ { "unnumbered", 1, 0, 0 },
+ { "unnumberedsec", 1, 0, 0 },
+ { "unnumberedsubsec", 1, 0, 0 },
+ { "unnumberedsubsubsec", 1, 0, 0 },
+
+ { "appendix", 1, 0, 0 },
+ { "appendixsec", 1, 0, 0 },
+ { "appendixsubsec", 1, 0, 0 },
+ { "appendixsubsubsec", 1, 0, 0 },
+
+ { "majorheading", 0, 0, 0 },
+ { "chapheading", 0, 0, 0 },
+ { "heading", 0, 0, 0 },
+ { "subheading", 0, 0, 0 },
+ { "subsubheading", 0, 0, 0 },
+
+ { "titlepage", 1, 0, 0 },
+ { "author", 0, 0, 0 },
+ { "booktitle", 0, 0, 0 },
+ { "booksubtitle", 0, 0, 0 },
+
+ { "menu", 1, 0, 0 },
+ { "detailmenu", 1, 0, 0 },
+ { "menuentry", 0, 0, 0 },
+ { "menutitle", 0, 0, 0 },
+ { "menucomment", 0, 0, 0 },
+ { "menunode", 0, 0, 0 },
+ { "nodename", 0, 0, 0 },
+
+ { "acronym", 0, 1, 0 },
+ { "acronymword", 0, 1, 0 },
+ { "acronymdesc", 0, 1, 0 },
+
+ { "abbrev", 0, 1, 0 },
+ { "abbrevword", 0, 1, 0 },
+ { "abbrevdesc", 0, 1, 0 },
+
+ { "tt", 0, 1, 0 },
+ { "code", 0, 1, 0 },
+ { "command", 0, 1, 0 },
+ { "env", 0, 1, 0 },
+ { "file", 0, 1, 0 },
+ { "option", 0, 1, 0 },
+ { "samp", 0, 1, 0 },
+ { "kbd", 0, 1, 0 },
+ { "url", 0, 1, 0 },
+ { "key", 0, 1, 0 },
+ { "var", 0, 1, 0 },
+ { "sc", 0, 1, 0 },
+ { "dfn", 0, 1, 0 },
+ { "emph", 0, 1, 0 },
+ { "strong", 0, 1, 0 },
+ { "cite", 0, 1, 0 },
+ { "notfixedwidth", 0, 1, 0 },
+ { "i", 0, 1, 0 },
+ { "b", 0, 1, 0 },
+ { "r", 0, 1, 0 },
+ { "slanted", 0, 1, 0 },
+ { "sansserif", 0, 1, 0 },
+
+ { "exdent", 0, 0, 0 },
+
+ { "title", 0, 0, 0 },
+ { "ifinfo", 1, 0, 0 },
+ { "sp", 0, 0, 0 },
+ { "center", 1, 0, 0 },
+ { "dircategory", 0, 0, 0 },
+ { "quotation", 1, 0, 0 },
+ { "example", 0, 0, 1 },
+ { "smallexample", 0, 0, 1 },
+ { "lisp", 0, 0, 1 },
+ { "smalllisp", 0, 0, 1 },
+ { "cartouche", 1, 0, 0 },
+ { "copying", 1, 0, 0 },
+ { "format", 0, 0, 1 },
+ { "smallformat", 0, 0, 1 },
+ { "display", 0, 0, 1 },
+ { "smalldisplay", 0, 0, 1 },
+ { "verbatim", 0, 0, 1 },
+ { "footnote", 0, 1, 0 },
+ { "", 0, 1, 0 }, /* LINEANNOTATION (docbook) */
+
+ { "", 1, 0, 0 }, /* TIP (docbook) */
+ { "", 1, 0, 0 }, /* NOTE (docbook) */
+ { "", 1, 0, 0 }, /* IMPORTANT (docbook) */
+ { "", 1, 0, 0 }, /* WARNING (docbook) */
+ { "", 1, 0, 0 }, /* CAUTION (docbook) */
+
+ { "itemize", 0, 0, 0 },
+ { "itemfunction", 0, 0, 0 },
+ { "item", 1, 0, 0 },
+ { "enumerate", 0, 0, 0 },
+ { "table", 0, 0, 0 },
+ { "tableitem", 0, 0, 0 },
+ { "tableterm", 0, 0, 0 },
+
+ { "indexterm", 0, 1, 0 },
+
+ { "math", 0, 1, 0 },
+
+ { "dmn", 0, 1, 0 },
+
+ { "xref", 0, 1, 0 },
+ { "xrefnodename", 0, 1, 0 },
+ { "xrefinfoname", 0, 1, 0 },
+ { "xrefprinteddesc", 0, 1, 0 },
+ { "xrefinfofile", 0, 1, 0 },
+ { "xrefprintedname", 0, 1, 0 },
+
+ { "inforef", 0, 1, 0 },
+ { "inforefnodename", 0, 1, 0 },
+ { "inforefrefname", 0, 1, 0 },
+ { "inforefinfoname", 0, 1, 0 },
+
+ { "uref", 0, 1, 0 },
+ { "urefurl", 0, 1, 0 },
+ { "urefdesc", 0, 1, 0 },
+ { "urefreplacement", 0, 1, 0 },
+
+ { "email", 0, 1, 0 },
+ { "emailaddress", 0, 1, 0 },
+ { "emailname", 0, 1, 0 },
+
+ { "group", 0, 0, 0 },
+ { "float", 1, 0, 0 },
+ { "floattype", 0, 0, 0 },
+ { "floatpos", 0, 0, 0 },
+ { "caption", 0, 0, 0 },
+ { "shortcaption", 0, 0, 0 },
+
+ { "", 0, 0, 0 }, /* TABLE (docbook) */
+ { "", 0, 0, 0 }, /* FIGURE (docbook) */
+ { "", 0, 0, 0 }, /* EXAMPLE (docbook) */
+ { "", 1, 0, 0 }, /* SIDEBAR (docbook) */
+
+ { "printindex", 0, 0, 0 },
+ { "listoffloats", 0, 0, 0 },
+ { "anchor", 0, 1, 0 },
+
+ { "image", 0, 0, 0 },
+ { "inlineimage", 0, 1, 0 },
+ { "alttext", 0, 1, 0 },
+
+ { "", 0, 1, 0 }, /* PRIMARY (docbook) */
+ { "", 0, 1, 0 }, /* SECONDARY (docbook) */
+ { "", 0, 0, 0 }, /* INFORMALFIGURE (docbook) */
+ { "", 0, 0, 0 }, /* MEDIAOBJECT (docbook) */
+ { "", 0, 0, 0 }, /* IMAGEOBJECT (docbook) */
+ { "", 0, 0, 0 }, /* IMAGEDATA (docbook) */
+ { "", 0, 0, 0 }, /* TEXTOBJECT (docbook) */
+ { "", 0, 0, 0 }, /* INDEXENTRY (docbook) */
+ { "", 0, 0, 0 }, /* PRIMARYIE (docbook) */
+ { "", 0, 0, 0 }, /* SECONDARYIE (docbook) */
+ { "", 0, 0, 0 }, /* INDEXDIV (docbook) */
+ { "multitable", 0, 0, 0 },
+ { "", 0, 0, 0 }, /* TGROUP (docbook) */
+ { "columnfraction", 0, 0, 0 },
+ { "thead", 0, 0, 0 },
+ { "tbody", 0, 0, 0 },
+ { "entry", 0, 0, 0 },
+ { "row", 0, 0, 0 },
+ { "", 0, 0, 0 }, /* BOOKINFO (docbook) */
+ { "", 0, 0, 0 }, /* ABSTRACT (docbook) */
+ { "", 0, 0, 0 }, /* REPLACEABLE (docbook) */
+ { "", 0, 0, 0 }, /* ENVAR (docbook) */
+ { "", 0, 0, 0 }, /* COMMENT (docbook) */
+ { "", 0, 0, 0 }, /* FUNCTION (docbook) */
+ { "", 0, 0, 0 }, /* LEGALNOTICE (docbook) */
+
+ { "contents", 0, 0, 0 },
+ { "shortcontents", 0, 0, 0 },
+ { "documentlanguage", 0, 0, 0 },
+
+ { "setvalue", 0, 0, 0 },
+ { "clearvalue", 0, 0, 0 },
+
+ { "definition", 0, 0, 0 },
+ { "definitionterm", 0, 0, 0 },
+ { "definitionitem", 1, 0, 0 },
+ { "defcategory", 0, 0, 0 },
+ { "deffunction", 0, 0, 0 },
+ { "defvariable", 0, 0, 0 },
+ { "defparam", 0, 0, 0 },
+ { "defdelimiter", 0, 0, 0 },
+ { "deftype", 0, 0, 0 },
+ { "defparamtype", 0, 0, 0 },
+ { "defdatatype", 0, 0, 0 },
+ { "defclass", 0, 0, 0 },
+ { "defclassvar", 0, 0, 0 },
+ { "defoperation", 0, 0, 0 },
+
+ { "para", 0, 0, 0 } /* Must be last */
+ /* name / contains para / contained in para / preserve space */
};
element docbook_element_list [] = {
- { "book", 0, 0 }, /* TEXINFO */
- { "", 0, 0 }, /* SETFILENAME */
- { "", 0, 0 }, /* TITLEINFO */
- { "title", 0, 0 }, /* SETTITLE */
-
- { "", 1, 0 }, /* NODE */
- { "", 0, 0 }, /* NODENEXT */
- { "", 0, 0 }, /* NODEPREV */
- { "", 0, 0 }, /* NODEUP */
-
- { "chapter", 1, 0 },
- { "sect1", 1, 0 }, /* SECTION */
- { "sect2", 1, 0 }, /* SUBSECTION */
- { "sect3", 1, 0 }, /* SUBSUBSECTION */
-
- { "chapter", 1, 0 }, /* TOP */
- { "chapter", 1, 0 }, /* UNNUMBERED */
- { "sect1", 1, 0 }, /* UNNUMBEREDSEC */
- { "sect2", 1, 0 }, /* UNNUMBEREDSUBSEC */
- { "sect3", 1, 0 }, /* UNNUMBEREDSUBSUBSEC */
-
- { "appendix", 1, 0 },
- { "sect1", 1, 0 }, /* APPENDIXSEC */
- { "sect2", 1, 0 }, /* APPENDIXSUBSEC */
- { "sect3", 1, 0 }, /* APPENDIXSUBSUBSEC */
-
- { "chapter", 1, 0 }, /* MAJORHEADING */
- { "chapter", 1, 0 }, /* CHAPHEADING */
- { "sect1", 1, 0 }, /* HEADING */
- { "sect2", 1, 0 }, /* SUBHEADING */
- { "simplesect", 1, 0 }, /* SUBSUBHEADING */
-
- { "", 1, 0 }, /* MENU */
- { "", 1, 0 }, /* MENUENTRY */
- { "", 0, 0 }, /* MENUTITLE */
- { "", 1, 0 }, /* MENUCOMMENT */
- { "", 0, 0 }, /* MENUNODE */
- { "anchor", 0, 0 }, /* NODENAME */
-
- { "acronym", 0, 1 },
- { "wordasword", 0, 1 }, /* TT */
- { "command", 0, 1 }, /* CODE */
- { "userinput", 0, 1 }, /* KBD */
- { "wordasword", 0, 1 }, /* URL */
- { "keycap", 0, 1 }, /* KEY */
- { "varname", 0, 1 }, /* VAR */
- { "", 0, 1 }, /* SC */
- { "firstterm", 0, 1 }, /* DFN */
- { "emphasis", 0, 1 }, /* EMPH */
- { "emphasis", 0, 1 }, /* STRONG */
- { "citation", 0, 1 }, /* CITE */
- { "", 0, 1 }, /* NOTFIXEDWIDTH */
- { "wordasword", 0, 1 }, /* I */
- { "wordasword", 0, 1 }, /* B */
- { "", 0, 1 }, /* R */
-
- { "title", 0, 0 },
- { "", 1, 0 }, /* IFINFO */
- { "", 0, 0 }, /* SP */
- { "", 1, 0 }, /* CENTER */
- { "", 0, 0 }, /* DIRCATEGORY */
- { "blockquote", 1, 0 }, /* QUOTATION */
- { "screen", 0, 1 },
- { "screen", 0, 1 }, /* SMALLEXAMPLE */
- { "screen", 0, 1 }, /* LISP */
- { "screen", 0, 1 }, /* SMALLLISP */
- { "", 1, 0 }, /* CARTOUCHE */
- { "", 1, 0 }, /* COPYING */
- { "screen", 0, 1 }, /* FORMAT */
- { "screen", 0, 1 }, /* SMALLFORMAT */
- { "screen", 0, 1 }, /* DISPLAY */
- { "screen", 0, 1 }, /* SMALLDISPLAY */
- { "footnote", 0, 1 },
-
- { "itemizedlist", 0, 0 }, /* ITEMIZE */
- { "", 0, 0 }, /* ITEMFUNCTION */
- { "listitem", 1, 0 }, /* ITEM */
- { "orderedlist", 0, 0 }, /* ENUMERATE */
- { "variablelist", 0, 0 }, /* TABLE */
- { "varlistentry", 0, 0 }, /* TABLEITEM */
- { "term", 0, 0 }, /* TABLETERM */
-
- { "indexterm", 0, 1 }, /* INDEXTERM */
-
- { "xref", 0, 1 }, /* XREF */
- { "link", 0, 1 }, /* XREFNODENAME */
- { "", 0, 1 }, /* XREFINFONAME */
- { "", 0, 1 }, /* XREFPRINTEDDESC */
- { "", 0, 1 }, /* XREFINFOFILE */
- { "", 0, 1 }, /* XREFPRINTEDNAME */
-
- { "", 0, 1 }, /* INFOREF */
- { "", 0, 1 }, /* INFOREFNODENAME */
- { "", 0, 1 }, /* INFOREFREFNAME */
- { "", 0, 1 }, /* INFOREFINFONAME */
-
- { "", 0, 1 }, /* UREF */
- { "", 0, 1 }, /* UREFURL */
- { "", 0, 1 }, /* UREFDESC */
- { "", 0, 1 }, /* UREFREPLACEMENT */
-
- { "ulink", 0, 1 }, /* EMAIL */
- { "", 0, 1 }, /* EMAILADDRESS */
- { "", 0, 1 }, /* EMAILNAME */
-
- { "", 0, 0 }, /* GROUP */
-
- { "index", 0, 1 }, /* PRINTINDEX */
- { "", 0, 1 }, /* ANCHOR */
- { "", 0, 1 }, /* IMAGE */
- { "primary", 0, 1 }, /* PRIMARY */
- { "secondary", 0, 1 },
- { "informalfigure", 0, 0 },
- { "mediaobject", 0, 0 },
- { "imageobject", 0, 0 },
- { "imagedata", 0, 0 },
- { "textobject", 0, 0 },
- { "indexentry", 0, 0 },
- { "primaryie", 0, 0 },
- { "secondaryie", 0, 0 },
- { "indexdiv", 0, 0 },
- { "informaltable", 0, 0 },
- { "tgroup", 0, 0 },
- { "colspec", 0, 0 },
- { "tbody", 0, 0 },
- { "entry", 0, 0 },
- { "row", 0, 0 },
- { "bookinfo", 0, 0 },
- { "abstract", 1, 0 },
- { "replaceable", 0, 0 },
- { "envar", 0, 1 },
- { "comment", 0, 0 },
- { "function", 0, 1 },
- { "legalnotice", 1, 0 },
-
- { "para", 0, 0 } /* Must be last */
- /* name / contains para / contained in para */
+ { "book", 0, 0, 0 }, /* TEXINFO */
+ { "", 0, 0, 0 }, /* SETFILENAME */
+ { "", 0, 0, 0 }, /* TITLEINFO */
+ { "title", 0, 0, 0 }, /* SETTITLE */
+ { "", 1, 0, 0 }, /* DOCUMENTDESCRIPTION (?) */
+
+ { "", 1, 0, 0 }, /* NODE */
+ { "", 0, 0, 0 }, /* NODENEXT */
+ { "", 0, 0, 0 }, /* NODEPREV */
+ { "", 0, 0, 0 }, /* NODEUP */
+
+ { "chapter", 1, 0, 0 },
+ { "sect1", 1, 0, 0 }, /* SECTION */
+ { "sect2", 1, 0, 0 }, /* SUBSECTION */
+ { "sect3", 1, 0, 0 }, /* SUBSUBSECTION */
+
+ { "chapter", 1, 0, 0 }, /* TOP */
+ { "chapter", 1, 0, 0 }, /* UNNUMBERED */
+ { "sect1", 1, 0, 0 }, /* UNNUMBEREDSEC */
+ { "sect2", 1, 0, 0 }, /* UNNUMBEREDSUBSEC */
+ { "sect3", 1, 0, 0 }, /* UNNUMBEREDSUBSUBSEC */
+
+ { "appendix", 1, 0, 0 },
+ { "sect1", 1, 0, 0 }, /* APPENDIXSEC */
+ { "sect2", 1, 0, 0 }, /* APPENDIXSUBSEC */
+ { "sect3", 1, 0, 0 }, /* APPENDIXSUBSUBSEC */
+
+ { "bridgehead", 0, 0, 0 }, /* MAJORHEADING */
+ { "bridgehead", 0, 0, 0 }, /* CHAPHEADING */
+ { "bridgehead", 0, 0, 0 }, /* HEADING */
+ { "bridgehead", 0, 0, 0 }, /* SUBHEADING */
+ { "bridgehead", 0, 0, 0 }, /* SUBSUBHEADING */
+
+ { "", 0, 0, 0 }, /* TITLEPAGE */
+ { "", 0, 0, 0 }, /* AUTHOR */
+ { "", 0, 0, 0 }, /* BOOKTITLE */
+ { "", 0, 0, 0 }, /* BOOKSUBTITLE */
+
+ { "", 1, 0, 0 }, /* MENU */
+ { "", 1, 0, 0 }, /* DETAILMENU */
+ { "", 1, 0, 0 }, /* MENUENTRY */
+ { "", 0, 0, 0 }, /* MENUTITLE */
+ { "", 1, 0, 0 }, /* MENUCOMMENT */
+ { "", 0, 0, 0 }, /* MENUNODE */
+ { "anchor", 0, 0, 0 }, /* NODENAME */
+
+ { "acronym", 0, 1, 0 },
+ { "", 0, 1, 0 }, /* ACRONYMWORD */
+ { "", 0, 1, 0 }, /* ACRONYMDESC */
+
+ { "abbrev", 0, 1, 0 },
+ { "", 0, 1, 0 }, /* ABBREVWORD */
+ { "", 0, 1, 0 }, /* ABBREVDESC */
+
+ { "literal", 0, 1, 0 }, /* TT */
+ { "literal", 0, 1, 0 }, /* CODE */
+ { "command", 0, 1, 0 }, /* COMMAND */
+ { "envar", 0, 1, 0 }, /* ENV */
+ { "filename", 0, 1, 0 }, /* FILE */
+ { "option", 0, 1, 0 }, /* OPTION */
+ { "literal", 0, 1, 0 }, /* SAMP */
+ { "userinput", 0, 1, 0 }, /* KBD */
+ { "wordasword", 0, 1, 0 }, /* URL */
+ { "keycap", 0, 1, 0 }, /* KEY */
+ { "replaceable", 0, 1, 0 }, /* VAR */
+ { "", 0, 1, 0 }, /* SC */
+ { "firstterm", 0, 1, 0 }, /* DFN */
+ { "emphasis", 0, 1, 0 }, /* EMPH */
+ { "emphasis", 0, 1, 0 }, /* STRONG */
+ { "citetitle", 0, 1, 0 }, /* CITE */
+ { "", 0, 1, 0 }, /* NOTFIXEDWIDTH */
+ { "wordasword", 0, 1, 0 }, /* I */
+ { "emphasis", 0, 1, 0 }, /* B */
+ { "", 0, 1, 0 }, /* R */
+
+ { "", 0, 0, 0 }, /* EXDENT */
+
+ { "title", 0, 0, 0 },
+ { "", 1, 0, 0 }, /* IFINFO */
+ { "", 0, 0, 0 }, /* SP */
+ { "", 1, 0, 0 }, /* CENTER */
+ { "", 0, 0, 0 }, /* DIRCATEGORY */
+ { "blockquote", 1, 0, 0 }, /* QUOTATION */
+ { "screen", 0, 0, 1 }, /* EXAMPLE */
+ { "screen", 0, 0, 1 }, /* SMALLEXAMPLE */
+ { "programlisting", 0, 0, 1 }, /* LISP */
+ { "programlisting", 0, 0, 1 }, /* SMALLLISP */
+ { "", 1, 0, 0 }, /* CARTOUCHE */
+ { "", 1, 0, 0 }, /* COPYING */
+ { "screen", 0, 1, 1 }, /* FORMAT */
+ { "screen", 0, 1, 1 }, /* SMALLFORMAT */
+ { "literallayout", 0, 1, 1 }, /* DISPLAY */
+ { "literallayout", 0, 1, 1 }, /* SMALLDISPLAY */
+ { "screen", 0, 0, 1 }, /* VERBATIM */
+ { "footnote", 0, 1, 0 },
+ { "lineannotation", 0, 1, 0 },
+
+ { "tip", 1, 0, 0 },
+ { "note", 1, 0, 0 },
+ { "important", 1, 0, 0 },
+ { "warning", 1, 0, 0 },
+ { "caution", 1, 0, 0 },
+
+ { "itemizedlist", 0, 0, 0 }, /* ITEMIZE */
+ { "", 0, 0, 0 }, /* ITEMFUNCTION */
+ { "listitem", 1, 0, 0 }, /* ITEM */
+ { "orderedlist", 0, 0, 0 }, /* ENUMERATE */
+ { "variablelist", 0, 0, 0 }, /* TABLE */
+ { "varlistentry", 0, 0, 0 }, /* TABLEITEM */
+ { "term", 0, 0, 0 }, /* TABLETERM */
+
+ { "indexterm", 0, 1, 0 }, /* INDEXTERM */
+
+ { "", 0, 1, 0 }, /* MATH */
+
+ { "", 0, 1, 0 }, /* DIMENSION */
+
+ { "xref", 0, 1, 0 }, /* XREF */
+ { "link", 0, 1, 0 }, /* XREFNODENAME */
+ { "", 0, 1, 0 }, /* XREFINFONAME */
+ { "", 0, 1, 0 }, /* XREFPRINTEDDESC */
+ { "", 0, 1, 0 }, /* XREFINFOFILE */
+ { "", 0, 1, 0 }, /* XREFPRINTEDNAME */
+
+ { "", 0, 1, 0 }, /* INFOREF */
+ { "", 0, 1, 0 }, /* INFOREFNODENAME */
+ { "", 0, 1, 0 }, /* INFOREFREFNAME */
+ { "", 0, 1, 0 }, /* INFOREFINFONAME */
+
+ { "ulink", 0, 1, 0 }, /* UREF */
+ { "", 0, 1, 0 }, /* UREFURL */
+ { "", 0, 1, 0 }, /* UREFDESC */
+ { "", 0, 1, 0 }, /* UREFREPLACEMENT */
+
+ { "ulink", 0, 1, 0 }, /* EMAIL */
+ { "", 0, 1, 0 }, /* EMAILADDRESS */
+ { "", 0, 1, 0 }, /* EMAILNAME */
+
+ { "", 0, 0, 0 }, /* GROUP */
+ { "", 1, 0, 0 }, /* FLOAT */
+ { "", 0, 0, 0 }, /* FLOATTYPE */
+ { "", 0, 0, 0 }, /* FLOATPOS */
+ { "", 0, 0, 0 }, /* CAPTION */
+ { "", 0, 0, 0 }, /* SHORTCAPTION */
+
+ { "table", 0, 1, 0 },
+ { "figure", 0, 1, 0 },
+ { "example", 1, 1, 0 },
+ { "sidebar", 1, 0, 0 },
+
+ { "index", 0, 1, 0 }, /* PRINTINDEX */
+ { "", 0, 1, 0 }, /* LISTOFFLOATS */
+ { "", 0, 1, 0 }, /* ANCHOR */
+
+ { "", 0, 0, 0 }, /* IMAGE */
+ { "inlinemediaobject", 0, 1, 0 }, /* INLINEIMAGE */
+ { "", 0, 0, 0 }, /* IMAGEALTTEXT */
+
+ { "primary", 0, 1, 0 }, /* PRIMARY */
+ { "secondary", 0, 1, 0 },
+ { "informalfigure", 0, 0, 0 },
+ { "mediaobject", 0, 0, 0 },
+ { "imageobject", 0, 1, 0 },
+ { "imagedata", 0, 1, 0 },
+ { "textobject", 0, 1, 0 },
+ { "indexentry", 0, 0, 0 },
+ { "primaryie", 0, 0, 0 },
+ { "secondaryie", 0, 0, 0 },
+ { "indexdiv", 0, 0, 0 },
+ { "informaltable", 0, 0, 0 },
+ { "tgroup", 0, 0, 0 },
+ { "colspec", 0, 0, 0 },
+ { "thead", 0, 0, 0 },
+ { "tbody", 0, 0, 0 },
+ { "entry", 0, 0, 0 },
+ { "row", 0, 0, 0 },
+ { "bookinfo", 0, 0, 0 },
+ { "abstract", 1, 0, 0 },
+ { "replaceable", 0, 0, 0 },
+ { "envar", 0, 1, 0 },
+ { "comment", 0, 0, 0 },
+ { "function", 0, 1, 0 },
+ { "legalnotice", 1, 0, 0 },
+
+ { "", 0, 0, 0 }, /* CONTENTS (xml) */
+ { "", 0, 0, 0 }, /* SHORTCONTENTS (xml) */
+ { "", 0, 0, 0 }, /* DOCUMENT LANGUAGE (xml) */
+
+ { "", 0, 0, 0 }, /* SETVALUE (xml) */
+ { "", 0, 0, 0 }, /* CLEARVALUE (xml) */
+
+ { "blockquote", 1, 0, 0 }, /* DEFINITION */
+ { "screen", 0, 0, 1 }, /* DEFINITIONTERM */
+ { "", 0, 0, 0 }, /* DEFINITIONITEM (xml) */
+ { "", 0, 0, 0 }, /* DEFCATEGORY (xml) */
+ { "function", 0, 0, 0 }, /* DEFFUNCTION */
+ { "varname", 0, 0, 0 }, /* DEFVARIABLE */
+ { "varname", 0, 0, 0 }, /* DEFPARAM */
+ { "", 0, 0, 0 }, /* DEFDELIMITER (xml) */
+ { "returnvalue", 0, 0, 0 }, /* DEFTYPE */
+ { "type", 0, 0, 0 }, /* DEFPARAMTYPE */
+ { "structname", 0, 0, 0 }, /* DEFDATATYPE */
+ { "classname", 0, 0, 0 }, /* DEFCLASS */
+ { "property", 0, 0, 0 }, /* DEFCLASSVAR */
+ { "methodname", 0, 0, 0 }, /* DEFOPERATION */
+
+ { "para", 0, 0, 0 } /* Must be last */
+ /* name / contains para / contained in para / preserve space */
};
element *xml_element_list = NULL;
@@ -352,8 +496,19 @@ replace_element replace_elements [] = {
{ VAR, B, EMPH},
{ B, CODE, ENVAR},
{ CODE, I, EMPH},
+ { SAMP, VAR, -1 },
{ FORMAT, BOOKINFO, ABSTRACT },
{ QUOTATION, ABSTRACT, -1},
+ { LINEANNOTATION, LINEANNOTATION, -1 },
+ { LEGALNOTICE, ABSTRACT, -1 },
+ { QUOTATION, QUOTATION, -1 },
+ /* Formal versions of table and image elements. */
+ { MULTITABLE, FLOAT, FLOATTABLE },
+ { INFORMALFIGURE, FLOAT, FLOATFIGURE },
+ { CARTOUCHE, FLOAT, FLOATCARTOUCHE },
+ /* Unnecessary markup in @defun blocks. */
+ { VAR, DEFPARAM, -1 },
+ { CODE, DEFTYPE, -1 },
/* Add your elements to replace here */
{-1, 0, 0}
};
@@ -364,6 +519,9 @@ int xml_node_open = 0;
int xml_node_level = -1;
int xml_in_para = 0;
int xml_just_after_element = 0;
+int xml_keep_space = 0;
+
+int xml_no_indent = 0;
int xml_no_para = 0;
char *xml_node_id = NULL;
@@ -374,50 +532,55 @@ int xml_in_bookinfo = 0;
int xml_in_book_title = 0;
int xml_in_abstract = 0;
+/* Non-zero if we are handling an element that can appear between
+ @item and @itemx, @deffn and @deffnx. */
+int xml_dont_touch_items_defs = 0;
+
+/* We need to keep footnote state, because elements inside footnote may try
+ to close the previous parent para. */
+static int xml_in_footnote = 0;
+
static int xml_after_table_term = 0;
static int book_started = 0;
static int first_section_opened = 0;
+static int xml_in_tableitem[256];
static int xml_in_item[256];
static int xml_table_level = 0;
+static int xml_in_def_item[256];
+static int xml_definition_level = 0;
+int xml_after_def_term = 0;
+
static int in_table_title = 0;
static int in_indexentry = 0;
static int in_secondary = 0;
static int in_indexterm = 0;
-
-static int xml_current_element ();
-
-void
-#if defined (VA_FPRINTF) && __STDC__
-xml_insert_element_with_attribute (int elt, int arg, char *format, ...);
-#else
-xml_insert_element_with_attribute ();
-#endif
-
+
char *
-xml_id (id)
- char *id;
+xml_id (char *id)
{
char *tem = xmalloc (strlen (id) + 1);
char *p = tem;
strcpy (tem, id);
while (*p)
- {
- if (strchr ("~ &/+^;?()%<>\"'$¿", *p))
+ { /* Check if a character is allowed in ID attributes. This list differs
+ slightly from XML specs that it doesn't contain underscores.
+ See http://xml.coverpages.org/sgmlsyn/sgmlsyn.htm, ``9.3 Name'' */
+ if (!strchr ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.", *p))
*p = '-';
p++;
}
p = tem;
- if (*p == '-')
+ /* First character can only be a letter. */
+ if (!strchr ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", *p))
*p = 'i';
return tem;
}
int
-xml_element (name)
- char *name;
+xml_element (char *name)
{
int i;
for (i=0; i<=PARA; i++)
@@ -430,30 +593,55 @@ xml_element (name)
}
void
-xml_begin_document (output_filename)
- char *output_filename;
+xml_begin_document (char *output_filename)
{
if (book_started)
return;
book_started = 1;
+
+ /* Make sure this is the very first string of the output document. */
+ output_paragraph_offset = 0;
+
+ insert_string ("<?xml version=\"1.0\"");
+
+ /* At this point, we register a delayed writing for document encoding,
+ so in the end, proper encoding attribute will be inserted here.
+ Since the user is unaware that we are implicitly executing this
+ command, we should disable warnings temporarily, in order to avoid
+ possible confusion. (ie. if the output is not seekable,
+ register_delayed_write issues a warning.) */
+ {
+ extern int print_warnings;
+ int save_print_warnings = print_warnings;
+ print_warnings = 0;
+ register_delayed_write ("@documentencoding");
+ print_warnings = save_print_warnings;
+ }
+
+ insert_string ("?>\n");
+
if (docbook)
{
- insert_string ("<!DOCTYPE Book PUBLIC \"-//OASIS//DTD DocBook V3.1//EN\">");
+ insert_string ("<!DOCTYPE book PUBLIC \"-//OASIS//DTD DocBook XML V4.2//EN\" \"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd\" [\n <!ENTITY tex \"TeX\">\n <!ENTITY latex \"LaTeX\">\n]>");
xml_element_list = docbook_element_list;
}
else
{
- insert_string ("<!DOCTYPE texinfo SYSTEM \"texinfo.dtd\">");
+ insert_string ("<!DOCTYPE texinfo PUBLIC \"-//GNU//DTD TexinfoML V");
+ insert_string (VERSION);
+ insert_string ("//EN\" \"http://www.gnu.org/software/texinfo/dtd/");
+ insert_string (VERSION);
+ insert_string ("/texinfo.dtd\">");
xml_element_list = texinfoml_element_list;
}
- if (docbook)
+ if (language_code != last_language_code)
{
- if (language_code != last_language_code)
+ if (docbook)
xml_insert_element_with_attribute (TEXINFO, START, "lang=\"%s\"", language_table[language_code].abbrev);
+ else
+ xml_insert_element_with_attribute (TEXINFO, START, "xml:lang=\"%s\"", language_table[language_code].abbrev);
}
- else
- xml_insert_element (TEXINFO, START);
if (!docbook)
{
xml_insert_element (SETFILENAME, START);
@@ -466,9 +654,14 @@ xml_begin_document (output_filename)
static int element_stack[256];
static int element_stack_index = 0;
+static int
+xml_current_element (void)
+{
+ return element_stack[element_stack_index-1];
+}
+
static void
-xml_push_current_element (elt)
- int elt;
+xml_push_current_element (int elt)
{
element_stack[element_stack_index++] = elt;
if (element_stack_index > 200)
@@ -477,8 +670,8 @@ xml_push_current_element (elt)
xml_element_list[elt].name);
}
-void
-xml_pop_current_element ()
+static void
+xml_pop_current_element (void)
{
element_stack_index--;
if (element_stack_index < 0)
@@ -487,31 +680,67 @@ xml_pop_current_element ()
xml_current_element());
}
-static int
-xml_current_element ()
+int
+xml_current_stack_index (void)
{
- return element_stack[element_stack_index-1];
+ return element_stack_index;
}
-static void
-xml_indent ()
+void
+xml_end_current_element (void)
{
- int i;
- insert ('\n');
- for (i = 0; i < element_stack_index; i++)
- insert (' ');
+ xml_insert_element (xml_current_element (), END);
}
static void
-xml_indent_end_para ()
+xml_indent (void)
{
- int i;
- for (i = 0; i < element_stack_index; i++)
- insert (' ');
+ if (xml_indentation_increment > 0)
+ {
+ int i;
+ if (output_paragraph[output_paragraph_offset-1] != '\n')
+ insert ('\n');
+ for (i = 0; i < element_stack_index * xml_indentation_increment; i++)
+ insert (' ');
+ }
+}
+
+void
+xml_start_para (void)
+{
+ if (xml_in_para || xml_in_footnote
+ || !xml_element_list[xml_current_element()].contains_para)
+ return;
+
+ while (output_paragraph[output_paragraph_offset-1] == '\n')
+ output_paragraph_offset--;
+ xml_indent ();
+
+ insert_string ("<para");
+ if (xml_no_indent)
+ insert_string (" role=\"continues\"");
+ insert_string (">");
+ xml_no_indent = 0;
+ xml_in_para = 1;
}
void
-xml_end_document ()
+xml_end_para (void)
+{
+ if (!xml_in_para || xml_in_footnote)
+ return;
+
+ while (cr_or_whitespace(output_paragraph[output_paragraph_offset-1]))
+ output_paragraph_offset--;
+
+ insert_string ("</para>");
+ if (xml_indentation_increment > 0)
+ insert ('\n');
+ xml_in_para = 0;
+}
+
+void
+xml_end_document (void)
{
if (xml_node_open)
{
@@ -526,7 +755,8 @@ xml_end_document ()
xml_close_sections (xml_node_level);
xml_insert_element (TEXINFO, END);
- insert_string ("\n");
+ if (xml_indentation_increment == 0)
+ insert ('\n');
insert_string ("<!-- Keep this comment at the end of the file\n\
Local variables:\n\
mode: sgml\n\
@@ -590,51 +820,72 @@ xml_insert_element_with_attribute (elt, arg, format, va_alist)
}
if (!book_started)
- return;
+ return;
- if (xml_after_table_term && elt != TABLETERM)
+ if (!xml_dont_touch_items_defs && arg == START)
{
- xml_after_table_term = 0;
- xml_insert_element (ITEM, START);
+ if (xml_after_table_term && elt != TABLETERM && xml_table_level
+ && !xml_in_item[xml_table_level])
+ {
+ xml_after_table_term = 0;
+ xml_insert_element (ITEM, START);
+ xml_in_item[xml_table_level] = 1;
+ }
+ else if (xml_after_def_term && elt != DEFINITIONTERM)
+ {
+ xml_after_def_term = 0;
+ xml_insert_element (DEFINITIONITEM, START);
+ xml_in_def_item[xml_definition_level] = 1;
+ }
}
if (docbook && !only_macro_expansion && (in_menu || in_detailmenu))
return;
- if (!xml_element_list[elt].name || !strlen (xml_element_list[elt].name))
+ if (executing_string && arg == END)
+ switch (elt)
+ {
+ case TABLEITEM:
+ xml_in_tableitem[xml_table_level] = 0;
+ break;
+ case ITEM:
+ xml_in_item[xml_table_level] = 0;
+ break;
+ case DEFINITIONTERM:
+ xml_in_def_item[xml_definition_level] = 0;
+ break;
+ }
+
+ /* We are special-casing FIGURE element for docbook. It does appear in
+ the tag stack, but not in the output. This is to make element replacement
+ work beautifully. */
+ if (docbook && elt == FLOAT)
{
- /*printf ("Warning: Inserting empty element %d\n", elt);*/
+ if (arg == START)
+ xml_push_current_element (elt);
+ else
+ xml_pop_current_element ();
return;
}
- if (arg == START && !xml_in_para && !xml_no_para
- && xml_element_list[elt].contained_in_para
- && xml_element_list[xml_current_element()].contains_para )
+ if (!xml_element_list[elt].name || !strlen (xml_element_list[elt].name))
{
- xml_indent ();
- insert_string ("<para>");
- xml_in_para = 1;
+ /*printf ("Warning: Inserting empty element %d\n", elt);*/
+ return;
}
+ if (arg == START && !xml_in_para && !xml_no_para
+ && xml_element_list[elt].contained_in_para)
+ xml_start_para ();
if (arg == START && xml_in_para && !xml_element_list[elt].contained_in_para)
- {
- xml_indent_end_para ();
- insert_string ("</para>");
- xml_in_para = 0;
- }
+ xml_end_para ();
if (arg == END && xml_in_para && !xml_element_list[elt].contained_in_para)
- {
- xml_indent_end_para ();
- insert_string ("</para>");
- xml_in_para = 0;
- }
-
- if (arg == START && !xml_in_para && !xml_element_list[elt].contained_in_para)
- xml_indent ();
+ xml_end_para ();
- if (docbook && xml_table_level && !xml_in_item[xml_table_level] && !in_table_title
+ if (docbook && xml_table_level && !in_table_title
+ && !xml_in_tableitem[xml_table_level] && !xml_in_item[xml_table_level]
&& arg == START && elt != TABLEITEM && elt != TABLETERM
&& !in_indexterm && xml_current_element() == TABLE)
{
@@ -642,12 +893,40 @@ xml_insert_element_with_attribute (elt, arg, format, va_alist)
xml_insert_element (TITLE, START);
}
+ if (arg == START && !xml_in_para && !xml_keep_space
+ && !xml_element_list[elt].contained_in_para)
+ xml_indent ();
if (arg == START)
xml_push_current_element (elt);
else
xml_pop_current_element ();
+ /* Eat one newline before </example> and the like. */
+ if (!docbook && arg == END
+ && (xml_element_list[elt].keep_space || elt == GROUP)
+ && output_paragraph[output_paragraph_offset-1] == '\n')
+ output_paragraph_offset--;
+
+ /* And eat whitespace before </entry> in @multitables. */
+ if (arg == END && elt == ENTRY)
+ while (cr_or_whitespace(output_paragraph[output_paragraph_offset-1]))
+ output_paragraph_offset--;
+
+ /* Indent elements that can contain <para>. */
+ if (arg == END && !xml_in_para && !xml_keep_space
+ && xml_element_list[elt].contains_para)
+ xml_indent ();
+
+ /* Here are the elements we want indented. These do not contain <para>
+ directly. */
+ if (arg == END && (elt == MENUENTRY || elt == ITEMIZE || elt == ENUMERATE
+ || elt == TABLEITEM || elt == TABLE
+ || elt == MULTITABLE || elt == TGROUP || elt == THEAD || elt == TBODY
+ || elt == ROW || elt == INFORMALFIGURE
+ || (!docbook && (elt == DEFINITION || elt == DEFINITIONTERM))))
+ xml_indent ();
+
insert ('<');
if (arg == END)
insert ('/');
@@ -677,13 +956,29 @@ xml_insert_element_with_attribute (elt, arg, format, va_alist)
{
insert_string (" id=\"");
insert_string (xml_node_id);
- insert_string ("\"");
+ insert ('"');
free (xml_node_id);
xml_node_id = NULL;
}
+ if (xml_element_list[elt].keep_space)
+ {
+ if (arg == START)
+ {
+ if (!docbook)
+ insert_string (" xml:space=\"preserve\"");
+ xml_keep_space++;
+ }
+ else
+ xml_keep_space--;
+ }
+
insert ('>');
+ if (!xml_in_para && !xml_element_list[elt].contained_in_para
+ && xml_element_list[elt].contains_para && xml_indentation_increment > 0)
+ insert ('\n');
+
xml_just_after_element = 1;
}
@@ -708,15 +1003,13 @@ xml_insert_entity (char *entity_name)
if (!xml_in_para && !xml_no_para && !only_macro_expansion
&& xml_element_list[xml_current_element ()].contains_para
&& !in_fixed_width_font)
- {
- insert_string ("<para>");
- xml_in_para = 1;
- }
+ xml_start_para ();
+
escape_html = 0;
- insert ('&');
+ add_char ('&');
escape_html = saved_escape_html;
insert_string (entity_name);
- insert (';');
+ add_char (';');
}
typedef struct _xml_section xml_section;
@@ -729,7 +1022,7 @@ struct _xml_section {
xml_section *last_section = NULL;
void
-xml_begin_node ()
+xml_begin_node (void)
{
first_section_opened = 1;
if (xml_in_abstract)
@@ -756,8 +1049,7 @@ xml_begin_node ()
}
void
-xml_close_sections (level)
- int level;
+xml_close_sections (int level)
{
if (!first_section_opened)
{
@@ -786,9 +1078,7 @@ xml_close_sections (level)
}
void
-xml_open_section (level, name)
- int level;
- char *name;
+xml_open_section (int level, char *name)
{
xml_section *sect = (xml_section *) xmalloc (sizeof (xml_section));
@@ -803,8 +1093,7 @@ xml_open_section (level, name)
}
void
-xml_start_menu_entry (tem)
- char *tem;
+xml_start_menu_entry (char *tem)
{
char *string;
discard_until ("* ");
@@ -849,12 +1138,13 @@ xml_start_menu_entry (tem)
free (string);
}
input_text_offset++; /* discard the second colon or the period */
+ skip_whitespace_and_newlines();
xml_insert_element (MENUCOMMENT, START);
xml_in_menu_entry_comment ++;
}
void
-xml_end_menu ()
+xml_end_menu (void)
{
if (xml_in_menu_entry)
{
@@ -872,15 +1162,15 @@ xml_end_menu ()
static int xml_last_character;
void
-xml_add_char (character)
- int character;
+xml_add_char (int character)
{
if (!book_started)
return;
if (docbook && !only_macro_expansion && (in_menu || in_detailmenu))
return;
- if (docbook && xml_table_level && !xml_in_item[xml_table_level] && !in_table_title
+ if (docbook && xml_table_level && !in_table_title
+ && !xml_in_item[xml_table_level] && !xml_in_tableitem[xml_table_level]
&& !cr_or_whitespace (character) && !in_indexterm)
{
in_table_title = 1;
@@ -888,7 +1178,8 @@ xml_add_char (character)
}
if (!first_section_opened && !xml_in_abstract && !xml_in_book_title
- && !xml_no_para && character != '\r' && character != '\n' && character != ' ')
+ && !xml_no_para && character != '\r' && character != '\n'
+ && character != ' ' && !is_in_insertion_of_type (copying))
{
if (!xml_in_bookinfo)
{
@@ -899,10 +1190,21 @@ xml_add_char (character)
xml_in_abstract = 1;
}
- if (xml_after_table_term && !xml_sort_index && !xml_in_xref_token)
+ if (!xml_sort_index && !xml_in_xref_token && !xml_dont_touch_items_defs)
{
- xml_after_table_term = 0;
- xml_insert_element (ITEM, START);
+ if (xml_after_table_term && xml_table_level
+ && !xml_in_item[xml_table_level])
+ {
+ xml_after_table_term = 0;
+ xml_insert_element (ITEM, START);
+ xml_in_item[xml_table_level] = 1;
+ }
+ else if (xml_after_def_term)
+ {
+ xml_after_def_term = 0;
+ xml_insert_element (DEFINITIONITEM, START);
+ xml_in_def_item[xml_definition_level] = 1;
+ }
}
if (xml_just_after_element && !xml_in_para && !inhibit_paragraph_indentation)
@@ -915,34 +1217,29 @@ xml_add_char (character)
if (xml_element_list[xml_current_element()].contains_para
&& !xml_in_para && !only_macro_expansion && !xml_no_para
&& !cr_or_whitespace (character) && !in_fixed_width_font)
+ xml_start_para ();
+
+ if (xml_in_para && character == '\n' && xml_last_character == '\n'
+ && !only_macro_expansion && !xml_no_para
+ && xml_element_list[xml_current_element()].contains_para )
{
- xml_indent ();
- insert_string ("<para>\n");
- xml_in_para = 1;
+ xml_end_para ();
+ xml_just_after_element = 1;
+ return;
}
- if (xml_in_para)
+ if (xml_in_menu_entry_comment && character == '\n' && xml_last_character == '\n')
{
- if (character == '\n')
- {
- if (xml_last_character == '\n' && !only_macro_expansion && !xml_no_para
- && xml_element_list[xml_current_element()].contains_para )
- {
- xml_indent_end_para ();
- insert_string ("</para>");
- xml_in_para = 0;
- xml_just_after_element = 1;
- if (xml_in_menu_entry_comment)
- {
- xml_insert_element (MENUCOMMENT, END);
- xml_in_menu_entry_comment = 0;
- xml_insert_element (MENUENTRY, END);
- xml_in_menu_entry = 0;
- }
- }
- }
+ xml_insert_element (MENUCOMMENT, END);
+ xml_in_menu_entry_comment = 0;
+ xml_insert_element (MENUENTRY, END);
+ xml_in_menu_entry = 0;
}
+ if (xml_in_menu_entry_comment && whitespace(character)
+ && cr_or_whitespace(xml_last_character))
+ return;
+
if (character == '\n' && !xml_in_para && !inhibit_paragraph_indentation)
return;
@@ -952,6 +1249,13 @@ xml_add_char (character)
insert_string ("&amp;");
else if (character == '<' && escape_html)
insert_string ("&lt;");
+ else if (character == '\n' && !xml_keep_space)
+ {
+ if (!xml_in_para && xml_just_after_element && !multitable_active)
+ return;
+ else
+ insert (docbook ? '\n' : ' ');
+ }
else
insert (character);
@@ -959,24 +1263,125 @@ xml_add_char (character)
}
void
-xml_insert_footnote (note)
- char *note;
+xml_insert_footnote (char *note)
{
+ if (!xml_in_para)
+ xml_start_para ();
+
+ xml_in_footnote = 1;
xml_insert_element (FOOTNOTE, START);
insert_string ("<para>");
execute_string ("%s", note);
insert_string ("</para>");
xml_insert_element (FOOTNOTE, END);
+ xml_in_footnote = 0;
}
+/* We need to keep the quotation stack ourself, because insertion_stack
+ loses item_function when we are closing the block, so we don't know
+ what to close then. */
+typedef struct quotation_elt
+{
+ struct quotation_elt *next;
+ char *type;
+} QUOTATION_ELT;
+
+static QUOTATION_ELT *quotation_stack = NULL;
+
+void
+xml_insert_quotation (char *type, int arg)
+{
+ int quotation_started = 0;
+
+ if (arg == START)
+ {
+ QUOTATION_ELT *new = xmalloc (sizeof (QUOTATION_ELT));
+ new->type = xstrdup (type);
+ new->next = quotation_stack;
+ quotation_stack = new;
+ }
+ else
+ type = quotation_stack->type;
+
+ /* Make use of special quotation styles of Docbook if we can. */
+ if (docbook && strlen(type))
+ {
+ /* Let's assume it started. */
+ quotation_started = 1;
+
+ if (strcasecmp (type, "tip") == 0)
+ xml_insert_element (TIP, arg);
+ else if (strcasecmp (type, "note") == 0)
+ xml_insert_element (NOTE, arg);
+ else if (strcasecmp (type, "important") == 0)
+ xml_insert_element (IMPORTANT, arg);
+ else if (strcasecmp (type, "warning") == 0)
+ xml_insert_element (WARNING, arg);
+ else if (strcasecmp (type, "caution") == 0)
+ xml_insert_element (CAUTION, arg);
+ else
+ /* Didn't find a known quotation type :\ */
+ quotation_started = 0;
+ }
+
+ if (!quotation_started)
+ {
+ xml_insert_element (QUOTATION, arg);
+ if (strlen(type) && arg == START)
+ execute_string ("@b{%s:} ", type);
+ }
+
+ if (arg == END)
+ {
+ QUOTATION_ELT *temp = quotation_stack;
+ if (temp == NULL)
+ return;
+ quotation_stack = quotation_stack->next;
+ free(temp->type);
+ free(temp);
+ }
+}
+
+/* Starting generic docbook floats. Just starts elt with correct label
+ and id attributes, and inserts title. */
+void
+xml_begin_docbook_float (int elt)
+{
+ if (current_float_used_title ()) /* in a nested float */
+ {
+ xml_insert_element (elt, START); /* just insert the tag */
+ return;
+ }
+
+
+ /* OK, need the title, tag, etc. */
+ if (elt == CARTOUCHE) /* no labels on <sidebar> */
+ {
+ if (strlen (current_float_id ()) == 0)
+ xml_insert_element (elt, START);
+ else
+ xml_insert_element_with_attribute (elt, START,
+ "id=\"%s\"", xml_id (current_float_id ()));
+ }
+ else if (strlen (current_float_id ()) == 0)
+ xml_insert_element_with_attribute (elt, START, "label=\"\"");
+ else
+ xml_insert_element_with_attribute (elt, START,
+ "id=\"%s\" label=\"%s\"", xml_id (current_float_id ()),
+ current_float_number ());
+
+ xml_insert_element (TITLE, START);
+ execute_string ("%s", current_float_title ());
+ xml_insert_element (TITLE, END);
+
+ current_float_set_title_used (); /* mark this title, tag, etc used */
+}
/*
* Lists and Tables
*/
void
-xml_begin_table (type, item_function)
- enum insertion_type type;
- char *item_function;
+xml_begin_table (int type, char *item_function)
{
switch (type)
{
@@ -987,7 +1392,9 @@ xml_begin_table (type, item_function)
{
xml_insert_element (TABLE, START);
xml_table_level ++;
+ xml_in_tableitem[xml_table_level] = 0;
xml_in_item[xml_table_level] = 0;
+ xml_after_table_term = 0;
}
break;
case itemize:
@@ -1019,25 +1426,27 @@ xml_begin_table (type, item_function)
}
void
-xml_end_table (type)
- enum insertion_type type;
+xml_end_table (int type)
{
switch (type)
{
case ftable:
case vtable:
case table:
- /* if (docbook)*/ /* 05-08 */
+ if (xml_in_item[xml_table_level])
{
- if (xml_in_item[xml_table_level])
- {
- xml_insert_element (ITEM, END);
- xml_insert_element (TABLEITEM, END);
- xml_in_item[xml_table_level] = 0;
- }
- xml_insert_element (TABLE, END);
- xml_table_level --;
+ xml_insert_element (ITEM, END);
+ xml_in_item[xml_table_level] = 0;
}
+ if (xml_in_tableitem[xml_table_level])
+ {
+ xml_insert_element (TABLEITEM, END);
+ xml_in_tableitem[xml_table_level] = 0;
+ }
+ xml_insert_element (TABLE, END);
+ xml_after_table_term = 0;
+ xml_table_level --;
+
break;
case itemize:
if (xml_in_item[xml_table_level])
@@ -1058,7 +1467,7 @@ xml_end_table (type)
}
void
-xml_begin_item ()
+xml_begin_item (void)
{
if (xml_in_item[xml_table_level])
xml_insert_element (ITEM, END);
@@ -1068,15 +1477,15 @@ xml_begin_item ()
}
void
-xml_begin_table_item ()
+xml_begin_table_item (void)
{
if (!xml_after_table_term)
{
if (xml_in_item[xml_table_level])
- {
- xml_insert_element (ITEM, END);
- xml_insert_element (TABLEITEM, END);
- }
+ xml_insert_element (ITEM, END);
+ if (xml_in_tableitem[xml_table_level])
+ xml_insert_element (TABLEITEM, END);
+
if (in_table_title)
{
in_table_title = 0;
@@ -1085,51 +1494,58 @@ xml_begin_table_item ()
xml_insert_element (TABLEITEM, START);
}
xml_insert_element (TABLETERM, START);
- xml_in_item[xml_table_level] = 1;
+ xml_in_tableitem[xml_table_level] = 1;
+ xml_in_item[xml_table_level] = 0;
xml_after_table_term = 0;
}
void
-xml_continue_table_item ()
+xml_continue_table_item (void)
{
xml_insert_element (TABLETERM, END);
xml_after_table_term = 1;
+ xml_in_item[xml_table_level] = 0;
}
void
-xml_begin_enumerate (enum_arg)
- char *enum_arg;
+xml_begin_enumerate (char *enum_arg)
{
if (!docbook)
xml_insert_element_with_attribute (ENUMERATE, START, "first=\"%s\"", enum_arg);
else
{
if (isdigit (*enum_arg))
- {
- if (enum_arg[0] == '1')
- xml_insert_element_with_attribute (ENUMERATE, START,
- "numeration=\"arabic\"", NULL);
- else
- xml_insert_element_with_attribute (ENUMERATE, START,
- "continuation=\"continues\" numeration=\"arabic\"", NULL);
- }
+ {
+ int enum_val = atoi (enum_arg);
+
+ /* Have to check the value, not just the first digit. */
+ if (enum_val == 0)
+ xml_insert_element_with_attribute (ENUMERATE, START,
+ "numeration=\"arabic\" role=\"0\"", NULL);
+ else if (enum_val == 1)
+ xml_insert_element_with_attribute (ENUMERATE, START,
+ "numeration=\"arabic\"", NULL);
+ else
+ xml_insert_element_with_attribute (ENUMERATE, START,
+ "continuation=\"continues\" numeration=\"arabic\"", NULL);
+ }
else if (isupper (*enum_arg))
{
- if (enum_arg[0] == 'A')
- xml_insert_element_with_attribute (ENUMERATE, START,
- "numeration=\"upperalpha\"", NULL);
- else
- xml_insert_element_with_attribute (ENUMERATE, START,
- "continuation=\"continues\" numeration=\"upperalpha\"", NULL);
- }
+ if (enum_arg[0] == 'A')
+ xml_insert_element_with_attribute (ENUMERATE, START,
+ "numeration=\"upperalpha\"", NULL);
+ else
+ xml_insert_element_with_attribute (ENUMERATE, START,
+ "continuation=\"continues\" numeration=\"upperalpha\"", NULL);
+ }
else
{
if (enum_arg[0] == 'a')
- xml_insert_element_with_attribute (ENUMERATE, START,
- "numeration=\"loweralpha\"", NULL);
- else
- xml_insert_element_with_attribute (ENUMERATE, START,
- "continuation=\"continues\" numeration=\"loweralpha\"", NULL);
+ xml_insert_element_with_attribute (ENUMERATE, START,
+ "numeration=\"loweralpha\"", NULL);
+ else
+ xml_insert_element_with_attribute (ENUMERATE, START,
+ "continuation=\"continues\" numeration=\"loweralpha\"", NULL);
}
}
xml_table_level ++;
@@ -1137,7 +1553,7 @@ xml_begin_enumerate (enum_arg)
}
void
-xml_end_enumerate ()
+xml_end_enumerate (void)
{
if (xml_in_item[xml_table_level])
{
@@ -1149,8 +1565,7 @@ xml_end_enumerate ()
}
static void
-xml_insert_text_file (name_arg)
- char *name_arg;
+xml_insert_text_file (char *name_arg)
{
char *fullname = xmalloc (strlen (name_arg) + 4 + 1);
FILE *image_file;
@@ -1193,31 +1608,78 @@ xml_insert_text_file (name_arg)
free (fullname);
}
-void
-xml_insert_docbook_image (name_arg)
- char *name_arg;
-{
- xml_insert_element (INFORMALFIGURE, START);
- xml_insert_element (MEDIAOBJECT, START);
+/* If NAME.EXT is accessible or FORCE is nonzero, insert a docbook
+ imagedata element for FMT. Return 1 if inserted something, 0 else. */
- xml_insert_element (IMAGEOBJECT, START);
- xml_insert_element_with_attribute (IMAGEDATA, START, "fileref=\"%s.eps\" format=\"eps\"", name_arg);
- xml_pop_current_element ();
- xml_insert_element (IMAGEOBJECT, END);
+static int
+try_docbook_image (const char *name, const char *ext, const char *fmt,
+ int force)
+{
+ int used = 0;
+ char *fullname = xmalloc (strlen (name) + 1 + strlen (ext) + 1);
+ sprintf (fullname, "%s.%s", name, ext);
+
+ if (force || access (fullname, R_OK) == 0)
+ {
+ xml_insert_element (IMAGEOBJECT, START);
+ xml_insert_element_with_attribute (IMAGEDATA, START,
+ "fileref=\"%s\" format=\"%s\"", fullname, fmt);
+ xml_insert_element (IMAGEDATA, END);
+ xml_insert_element (IMAGEOBJECT, END);
+ used = 1;
+ }
+
+ free (fullname);
+ return used;
+}
- xml_insert_element (IMAGEOBJECT, START);
- xml_insert_element_with_attribute (IMAGEDATA, START, "fileref=\"%s.jpg\" format=\"jpg\"", name_arg);
- xml_pop_current_element ();
- xml_insert_element (IMAGEOBJECT, END);
+void
+xml_insert_docbook_image (char *name_arg)
+{
+ int found = 0;
+ int elt = xml_in_para ? INLINEIMAGE : MEDIAOBJECT;
+
+ if (is_in_insertion_of_type (floatenv))
+ xml_begin_docbook_float (INFORMALFIGURE);
+ else if (!xml_in_para)
+ xml_insert_element (INFORMALFIGURE, START);
+
+ xml_no_para++;
+
+ xml_insert_element (elt, START);
+
+ /* A selected few from http://docbook.org/tdg/en/html/imagedata.html. */
+ if (try_docbook_image (name_arg, "eps", "EPS", 0))
+ found++;
+ if (try_docbook_image (name_arg, "gif", "GIF", 0))
+ found++;
+ if (try_docbook_image (name_arg, "jpg", "JPG", 0))
+ found++;
+ if (try_docbook_image (name_arg, "jpeg", "JPEG", 0))
+ found++;
+ if (try_docbook_image (name_arg, "pdf", "PDF", 0))
+ found++;
+ if (try_docbook_image (name_arg, "png", "PNG", 0))
+ found++;
+ if (try_docbook_image (name_arg, "svg", "SVG", 0))
+ found++;
+
+ /* If no luck so far, just assume we'll eventually have a jpg. */
+ if (!found)
+ try_docbook_image (name_arg, "jpg", "JPG", 1);
+
xml_insert_text_file (name_arg);
+ xml_insert_element (elt, END);
+
+ xml_no_para--;
- xml_insert_element (MEDIAOBJECT, END);
- xml_insert_element (INFORMALFIGURE, END);
+ if (elt == MEDIAOBJECT)
+ xml_insert_element (INFORMALFIGURE, END);
}
void
-xml_asterisk ()
+xml_asterisk (void)
{
}
@@ -1229,22 +1691,40 @@ xml_asterisk ()
to have real multilivel indexing support, not just string analysis. */
#define INDEX_SEP "@this string will never appear@" /* was , */
+typedef struct
+{
+ char *from;
+ char *to;
+} XML_SYNONYM;
+
+static XML_SYNONYM **xml_synonyms = NULL;
+static int xml_synonyms_count = 0;
+
void
-xml_insert_indexterm (indexterm, index)
- char *indexterm;
- char *index;
+xml_insert_indexterm (char *indexterm, char *index)
{
+ /* @index commands can appear between @item and @itemx, @deffn and @deffnx. */
if (!docbook)
{
+ /* Check to see if we need to do index redirection per @synindex. */
+ int i;
+ for (i = 0; i < xml_synonyms_count; i++)
+ {
+ if (STREQ (xml_synonyms[i]->from, index))
+ index = xstrdup (xml_synonyms[i]->to);
+ }
+
+ xml_dont_touch_items_defs++;
xml_insert_element_with_attribute (INDEXTERM, START, "index=\"%s\"", index);
in_indexterm = 1;
execute_string ("%s", indexterm);
xml_insert_element (INDEXTERM, END);
in_indexterm = 0;
+ xml_dont_touch_items_defs--;
}
else
{
- char *primary = NULL, *secondary;
+ char *primary = NULL, *secondary = NULL;
if (strstr (indexterm+1, INDEX_SEP))
{
primary = xmalloc (strlen (indexterm) + 1);
@@ -1257,14 +1737,14 @@ xml_insert_indexterm (indexterm, index)
in_indexterm = 1;
xml_insert_element (PRIMARY, START);
if (primary)
- execute_string (primary);
+ execute_string ("%s", primary);
else
- execute_string (indexterm);
+ execute_string ("%s", indexterm);
xml_insert_element (PRIMARY, END);
if (primary)
{
xml_insert_element (SECONDARY, START);
- execute_string (secondary);
+ execute_string ("%s", secondary);
xml_insert_element (SECONDARY, END);
}
xml_insert_element (INDEXTERM, END);
@@ -1279,7 +1759,7 @@ static char index_primary[2000]; /** xx no fixed limit */
static int indexdivempty = 0;
static void
-xml_close_indexentry ()
+xml_close_indexentry (void)
{
if (!in_indexentry)
return;
@@ -1291,58 +1771,92 @@ xml_close_indexentry ()
}
void
-xml_begin_index ()
+xml_begin_index (void)
{
- /*
- We assume that we just opened a section, and so that the last output is
- <SECTION ID="node-name"><TITLE>Title</TITLE>
- where SECTION can be CHAPTER, ...
- */
-
- xml_section *temp = last_section;
-
- int l = output_paragraph_offset-xml_last_section_output_position;
- char *tmp = xmalloc (l+1);
- char *p = tmp;
- strncpy (tmp, output_paragraph, l);
-
- /* We remove <SECTION */
- tmp[l] = '\0';
- while (*p != '<')
- p++;
- while (*p != ' ')
- p++;
-
- output_paragraph_offset = xml_last_section_output_position;
- xml_last_section_output_position = 0;
-
- xml_pop_current_element (); /* remove section element from elements stack */
-
- if (last_section)
- last_section = last_section->prev; /* remove section from sections stack */
- if (temp)
- {
- free (temp->name);
- free (temp);
- }
+ typedef struct xml_index_title {
+ struct xml_index_title *next;
+ char *title;
+ } XML_INDEX_TITLE;
- /* We put <INDEX> */
- xml_insert_element (PRINTINDEX, START);
- /* Remove the final > */
- output_paragraph_offset--;
+ static XML_INDEX_TITLE *xml_index_titles = NULL;
- /* and put ID="node-name"><TITLE>Title</TITLE> */
- insert_string (p);
+ if (!handling_delayed_writes)
+ { /* We assume that we just opened a section, and so that the last output is
+ <SECTION ID="node-name"><TITLE>Title</TITLE>
+ where SECTION can be CHAPTER, ... */
- if (xml_index_divisions)
+ XML_INDEX_TITLE *new = xmalloc (sizeof (XML_INDEX_TITLE));
+ xml_section *temp = last_section;
+
+ int l = output_paragraph_offset-xml_last_section_output_position;
+ char *tmp = xmalloc (l+1);
+ char *p = tmp;
+ strncpy (tmp, (char *) output_paragraph, l);
+
+ /* We remove <SECTION */
+ tmp[l] = '\0';
+ while (*p != '<')
+ p++;
+ while (*p != ' ')
+ p++;
+ /* ... and its label attribute. */
+ if (strncmp (p, " label=", 7) == 0)
+ {
+ p++;
+ while (*p != ' ')
+ p++;
+ }
+
+ output_paragraph_offset = xml_last_section_output_position;
+ xml_last_section_output_position = 0;
+
+ xml_pop_current_element (); /* remove section element from elements stack */
+
+ if (last_section)
+ last_section = last_section->prev; /* remove section from sections stack */
+ if (temp)
+ {
+ free (temp->name);
+ free (temp);
+ }
+
+ new->title = xstrdup (p);
+ new->next = xml_index_titles;
+ xml_index_titles = new;
+ }
+ else
{
- xml_insert_element (INDEXDIV, START);
- indexdivempty = 1;
+ static int xml_index_titles_reversed = 0;
+
+ if (!xml_index_titles_reversed)
+ {
+ xml_index_titles = (XML_INDEX_TITLE *) reverse_list
+ ((GENERIC_LIST *) xml_index_titles);
+ xml_index_titles_reversed = 1;
+ }
+
+ /* We put <INDEX> */
+ xml_insert_element (PRINTINDEX, START);
+ if (xml_index_titles)
+ {
+ /* Remove the final > */
+ output_paragraph_offset--;
+ /* and put ID="node-name"><TITLE>Title</TITLE> */
+ insert_string (xml_index_titles->title);
+ free (xml_index_titles->title);
+ xml_index_titles = xml_index_titles->next;
+ }
+
+ if (xml_index_divisions)
+ {
+ xml_insert_element (INDEXDIV, START);
+ indexdivempty = 1;
+ }
}
}
void
-xml_end_index ()
+xml_end_index (void)
{
xml_close_indexentry ();
if (xml_index_divisions)
@@ -1350,9 +1864,8 @@ xml_end_index ()
xml_insert_element (PRINTINDEX, END);
}
-void
-xml_index_divide (entry)
- char *entry;
+static void
+xml_index_divide (char *entry)
{
char c;
if (strlen (entry) > (strlen (xml_element_list[CODE].name) + 2) &&
@@ -1376,9 +1889,7 @@ xml_index_divide (entry)
}
void
-xml_insert_indexentry (entry, node)
- char *entry;
- char *node;
+xml_insert_indexentry (char *entry, char *node)
{
char *primary = NULL, *secondary;
if (xml_index_divisions)
@@ -1397,7 +1908,7 @@ xml_insert_indexentry (entry, node)
{
xml_insert_element (SECONDARYIE, END);
xml_insert_element (SECONDARYIE, START);
- execute_string (secondary);
+ execute_string ("%s", secondary);
}
else
{
@@ -1405,10 +1916,10 @@ xml_insert_indexentry (entry, node)
xml_insert_element (INDEXENTRY, START);
in_indexentry = 1;
xml_insert_element (PRIMARYIE, START);
- execute_string (primary);
+ execute_string ("%s", primary);
xml_insert_element (PRIMARYIE, END);
xml_insert_element (SECONDARYIE, START);
- execute_string (secondary);
+ execute_string ("%s", secondary);
in_secondary = 1;
}
}
@@ -1418,11 +1929,20 @@ xml_insert_indexentry (entry, node)
xml_insert_element (INDEXENTRY, START);
in_indexentry = 1;
xml_insert_element (PRIMARYIE, START);
- execute_string (entry);
+ execute_string ("%s", entry);
}
- add_word_args (", %s", _("see "));
- xml_insert_element_with_attribute (XREF, START, "linkend=\"%s\"", xml_id (node));
- xml_pop_current_element ();
+ add_word (", ");
+
+ /* Don't link to @unnumbered sections directly.
+ We are disabling warnings temporarily, otherwise these xrefs
+ will cause bogus warnings about missing punctuation. */
+ {
+ extern int print_warnings;
+ int save_print_warnings = print_warnings;
+ print_warnings = 0;
+ execute_string ("%cxref{%s}", COMMAND_PREFIX, xstrdup (node));
+ print_warnings = save_print_warnings;
+ }
if (primary)
{
@@ -1437,25 +1957,56 @@ xml_insert_indexentry (entry, node)
/* xml_insert_element (INDEXENTRY, END); */
}
+void
+xml_synindex (char *from, char *to)
+{
+ int i, slot;
+
+ slot = -1;
+ for (i = 0; i < xml_synonyms_count; i++)
+ if (!xml_synonyms[i])
+ {
+ slot = i;
+ break;
+ }
+
+ if (slot < 0)
+ {
+ slot = xml_synonyms_count;
+ xml_synonyms_count++;
+
+ xml_synonyms = (XML_SYNONYM **) xrealloc (xml_synonyms,
+ (xml_synonyms_count + 1) * sizeof (XML_SYNONYM *));
+ }
+
+ xml_synonyms[slot] = xmalloc (sizeof (XML_SYNONYM));
+ xml_synonyms[slot]->from = xstrdup (from);
+ xml_synonyms[slot]->to = xstrdup (to);
+}
+
/*
* MULTITABLE
*/
+
+static int multitable_columns_count;
+static int *multitable_column_widths;
+
void
-xml_begin_multitable (ncolumns, column_widths)
- int ncolumns;
- int *column_widths;
+xml_begin_multitable (int ncolumns, int *column_widths)
{
int i;
if (docbook)
{
- xml_insert_element (MULTITABLE, START);
- xml_insert_element_with_attribute (TGROUP, START, "cols=\"%d\"", ncolumns);
- for (i=0; i<ncolumns; i++)
- {
- xml_insert_element_with_attribute (COLSPEC, START, "colwidth=\"%d*\"", column_widths[i]);
- xml_pop_current_element ();
- }
- xml_insert_element (TBODY, START);
+ if (is_in_insertion_of_type (floatenv))
+ xml_begin_docbook_float (MULTITABLE);
+ else
+ xml_insert_element (MULTITABLE, START);
+
+ multitable_columns_count = ncolumns;
+ multitable_column_widths = xmalloc (sizeof (int) * ncolumns);
+ memcpy (multitable_column_widths, column_widths,
+ sizeof (int) * ncolumns);
+
xml_no_para = 1;
}
else
@@ -1471,43 +2022,307 @@ xml_begin_multitable (ncolumns, column_widths)
}
}
+static void
+xml_begin_multitable_group (void)
+{
+ int i;
+
+ xml_insert_element_with_attribute (TGROUP, START, "cols=\"%d\"",
+ multitable_columns_count);
+
+ for (i=0; i < multitable_columns_count; i++)
+ {
+ xml_insert_element_with_attribute (COLSPEC, START,
+ "colwidth=\"%d*\"", multitable_column_widths[i]);
+ xml_insert_element (COLSPEC, END);
+ }
+}
+
void
-xml_end_multitable_row (first_row)
- int first_row;
+xml_end_multitable_row (int first_row)
{
if (!first_row)
{
xml_insert_element (ENTRY, END);
xml_insert_element (ROW, END);
}
+
+ if (headitem_flag)
+ {
+ if (!first_row)
+ {
+ if (after_headitem)
+ xml_insert_element (THEAD, END);
+ else
+ xml_insert_element (TBODY, END);
+ xml_insert_element (TGROUP, END);
+ }
+
+ xml_begin_multitable_group ();
+ xml_insert_element (THEAD, START);
+ }
+ else if (first_row)
+ {
+ xml_begin_multitable_group ();
+ xml_insert_element (TBODY, START);
+ }
+ else if (after_headitem)
+ {
+ xml_insert_element (THEAD, END);
+ xml_insert_element (TBODY, START);
+ }
+ else if (first_row)
+ xml_insert_element (TBODY, START);
+
xml_insert_element (ROW, START);
xml_insert_element (ENTRY, START);
}
void
-xml_end_multitable_column ()
+xml_end_multitable_column (void)
{
xml_insert_element (ENTRY, END);
xml_insert_element (ENTRY, START);
}
void
-xml_end_multitable ()
+xml_end_multitable (void)
{
- if (docbook)
+ xml_insert_element (ENTRY, END);
+ xml_insert_element (ROW, END);
+
+ if (after_headitem)
{
- xml_insert_element (ENTRY, END);
- xml_insert_element (ROW, END);
- xml_insert_element (TBODY, END);
- xml_insert_element (TGROUP, END);
- xml_insert_element (MULTITABLE, END);
- xml_no_para = 0;
+ if (docbook)
+ warning (_("@headitem as the last item of @multitable produces invalid Docbook documents"));
+ xml_insert_element (THEAD, END);
}
else
+ xml_insert_element (TBODY, END);
+
+ if (docbook)
+ xml_insert_element (TGROUP, END);
+
+ xml_insert_element (MULTITABLE, END);
+ xml_no_para = 0;
+}
+
+/*
+ * Parameters in @def definitions
+ */
+
+#define DEFUN_SELF_DELIMITING(c) \
+ ((c) == '(' || (c) == ')' || (c) == '[' || (c) == ']')
+
+void
+xml_process_defun_args (char **defun_args, int auto_var_p)
+{
+ int pending_space = 0;
+ int just_after_paramtype = 0;
+
+ for (;;)
{
- xml_insert_element (ENTRY, END);
- xml_insert_element (ROW, END);
- xml_insert_element (MULTITABLE, END);
- xml_no_para = 0;
+ char *defun_arg = *defun_args++;
+
+ if (defun_arg == NULL)
+ break;
+
+ if (defun_arg[0] == ' ')
+ {
+ pending_space = 1;
+ continue;
+ }
+
+ if (pending_space)
+ {
+ add_char (' ');
+ pending_space = 0;
+ }
+
+ if (DEFUN_SELF_DELIMITING (defun_arg[0]))
+ {
+ xml_insert_element (DEFDELIMITER, START);
+ add_char (defun_arg[0]);
+ xml_insert_element (DEFDELIMITER, END);
+ just_after_paramtype = 0;
+ }
+ else if (defun_arg[0] == '&')
+ {
+ xml_insert_element (DEFPARAM, START);
+ add_word (defun_arg);
+ xml_insert_element (DEFPARAM, END);
+ just_after_paramtype = 0;
+ }
+ else if (defun_arg[0] == COMMAND_PREFIX || just_after_paramtype)
+ {
+ xml_insert_element (DEFPARAM, START);
+ execute_string ("%s", defun_arg);
+ xml_insert_element (DEFPARAM, END);
+ just_after_paramtype = 0;
+ }
+ else if (defun_arg[0] == ',' || defun_arg[0] == ';')
+ {
+ xml_insert_element (DEFDELIMITER, START);
+ add_word (defun_arg);
+ xml_insert_element (DEFDELIMITER, END);
+ just_after_paramtype = 0;
+ }
+ else if (auto_var_p)
+ {
+ xml_insert_element (DEFPARAM, START);
+ add_word (defun_arg);
+ xml_insert_element (DEFPARAM, END);
+ just_after_paramtype = 0;
+ }
+ else
+ {
+ xml_insert_element (DEFPARAMTYPE, START);
+ add_word (defun_arg);
+ xml_insert_element (DEFPARAMTYPE, END);
+ just_after_paramtype = 1;
+ }
}
}
+
+void
+xml_begin_definition (void)
+{
+ xml_insert_element (DEFINITION, START);
+ xml_definition_level ++;
+ xml_in_def_item[xml_definition_level] = 0;
+}
+
+void
+xml_end_definition (void)
+{
+ if (xml_in_def_item[xml_definition_level])
+ {
+ xml_insert_element (DEFINITIONITEM, END);
+ xml_in_def_item[xml_definition_level] = 0;
+ }
+ xml_after_def_term = 0;
+ xml_insert_element (DEFINITION, END);
+ xml_definition_level --;
+}
+
+void
+xml_begin_def_term (int base_type, const char *category,
+ char *defined_name, char *type_name, char *type_name2)
+{
+ xml_after_def_term = 0;
+ xml_insert_element (DEFINITIONTERM, START);
+
+ /* Index entry */
+ switch (base_type)
+ {
+ case deffn:
+ case deftypefn:
+ execute_string ("@findex %s\n", defined_name);
+ break;
+ case defvr:
+ case deftypevr:
+ case defcv:
+ execute_string ("@vindex %s\n", defined_name);
+ break;
+ case deftypecv:
+ case deftypeivar:
+ execute_string ("@vindex %s %s %s\n", defined_name, _("of"), type_name);
+ break;
+ case deftypemethod:
+ case defop:
+ case deftypeop:
+ execute_string ("@findex %s %s %s\n", defined_name, _("on"), type_name);
+ break;
+ case deftp:
+ execute_string ("@tindex %s\n", defined_name);
+ break;
+ }
+
+ /* Start with category. */
+ xml_insert_element (DEFCATEGORY, START);
+ execute_string (docbook ? "--- %s:" : "%s", category);
+ xml_insert_element (DEFCATEGORY, END);
+ add_char(' ');
+
+ /* Output type name first for typed definitions. */
+ switch (base_type)
+ {
+ case deffn:
+ case defvr:
+ case deftp:
+ break;
+
+ case deftypefn:
+ case deftypevr:
+ xml_insert_element (DEFTYPE, START);
+ execute_string ("%s", type_name);
+ xml_insert_element (DEFTYPE, END);
+ add_char (' ');
+ break;
+
+ case deftypecv:
+ case deftypeivar:
+ case deftypemethod:
+ case deftypeop:
+ xml_insert_element (DEFTYPE, START);
+ execute_string ("%s", type_name2);
+ xml_insert_element (DEFTYPE, END);
+ add_char (' ');
+ break;
+
+ default:
+ xml_insert_element (DEFCLASS, START);
+ execute_string ("%s", type_name);
+ xml_insert_element (DEFCLASS, END);
+ add_char (' ');
+ break;
+ }
+
+ /* Categorize rest of the definitions. */
+ switch (base_type)
+ {
+ case deffn:
+ case deftypefn:
+ xml_insert_element (DEFFUNCTION, START);
+ execute_string ("%s", defined_name);
+ xml_insert_element (DEFFUNCTION, END);
+ break;
+
+ case defvr:
+ case deftypevr:
+ xml_insert_element (DEFVARIABLE, START);
+ execute_string ("%s", defined_name);
+ xml_insert_element (DEFVARIABLE, END);
+ break;
+
+ case deftp:
+ xml_insert_element (DEFDATATYPE, START);
+ execute_string ("%s", defined_name);
+ xml_insert_element (DEFDATATYPE, END);
+ break;
+
+ case defcv:
+ case deftypecv:
+ case deftypeivar:
+ xml_insert_element (DEFCLASSVAR, START);
+ execute_string ("%s", defined_name);
+ xml_insert_element (DEFCLASSVAR, END);
+ break;
+
+ case defop:
+ case deftypeop:
+ case deftypemethod:
+ /* Operation / Method */
+ xml_insert_element (DEFOPERATION, START);
+ execute_string ("%s", defined_name);
+ xml_insert_element (DEFOPERATION, END);
+ break;
+ }
+}
+
+void
+xml_end_def_term (void)
+{
+ xml_insert_element (DEFINITIONTERM, END);
+ xml_after_def_term = 1;
+}
diff --git a/contrib/texinfo/makeinfo/xml.h b/contrib/texinfo/makeinfo/xml.h
index 35be066..f82b483 100644
--- a/contrib/texinfo/makeinfo/xml.h
+++ b/contrib/texinfo/makeinfo/xml.h
@@ -1,7 +1,7 @@
/* xml.h -- xml output declarations.
- $Id: xml.h,v 1.6 2002/11/11 12:37:34 feloy Exp $
+ $Id: xml.h,v 1.24 2004/11/26 00:48:35 karl Exp $
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- Written by Philippe Martin <feloy@free.fr>. */
+ Originally written by Philippe Martin <feloy@free.fr>. */
#ifndef XML_H
#define XML_H
@@ -28,6 +28,8 @@
extern int xml_index_divisions;
extern int xml_sort_index;
+extern int xml_no_indent;
+
extern int xml_node_open;
extern int xml_no_para;
extern char *xml_node_id;
@@ -38,49 +40,120 @@ extern int xml_in_bookinfo;
extern int xml_in_book_title;
extern int xml_in_abstract;
+/* Non-zero if we are handling an element that can appear between
+ @item and @itemx, @deffn and @deffnx. */
+extern int xml_dont_touch_items_defs;
+
+/* Non-zero if whitespace in the source document should be kept as-is. */
+extern int xml_keep_space;
+
enum xml_element
{
- TEXINFO=0, SETFILENAME, TITLEFONT, SETTITLE,
+ TEXINFO=0, SETFILENAME, TITLEFONT, SETTITLE, DOCUMENTDESCRIPTION,
/* Node */
- NODE /* 4 */, NODENEXT, NODEPREV, NODEUP,
+ NODE, NODENEXT, NODEPREV, NODEUP,
/* Structuring */
- CHAPTER /* 8 */, SECTION, SUBSECTION, SUBSUBSECTION,
- TOP /* 12 */, UNNUMBERED, UNNUMBEREDSEC, UNNUMBEREDSUBSEC,
+ CHAPTER, SECTION, SUBSECTION, SUBSUBSECTION,
+ TOP, UNNUMBERED, UNNUMBEREDSEC, UNNUMBEREDSUBSEC,
UNNUMBEREDSUBSUBSEC,
- APPENDIX /* 17 */, APPENDIXSEC, APPENDIXSUBSEC, APPENDIXSUBSUBSEC,
- MAJORHEADING /* 21 */, CHAPHEADING, HEADING, SUBHEADING, SUBSUBHEADING,
+ APPENDIX, APPENDIXSEC, APPENDIXSUBSEC, APPENDIXSUBSUBSEC,
+ MAJORHEADING, CHAPHEADING, HEADING, SUBHEADING, SUBSUBHEADING,
+ /* Titlepage */
+ TITLEPAGE, AUTHOR, BOOKTITLE, BOOKSUBTITLE,
/* Menu */
- MENU /* 26 */, MENUENTRY, MENUTITLE, MENUCOMMENT, MENUNODE, NODENAME,
+ MENU, DETAILMENU, MENUENTRY, MENUTITLE, MENUCOMMENT, MENUNODE,
+ NODENAME,
/* -- */
- ACRONYM/* 32 */, TT, CODE, KBD, URL, KEY, VAR, SC, DFN, EMPH, STRONG,
- CITE, NOTFIXEDWIDTH, I, B, R,
+ ACRONYM, ACRONYMWORD, ACRONYMDESC,
+ ABBREV, ABBREVWORD, ABBREVDESC,
+ TT, CODE, COMMAND_TAG, ENV, FILE_TAG, OPTION, SAMP, KBD, URL, KEY,
+ VAR, SC, DFN, EMPH, STRONG, CITE, NOTFIXEDWIDTH, I, B, R, SLANTED, SANSSERIF,
+ EXDENT,
TITLE,
IFINFO,
SP, CENTER,
DIRCATEGORY,
QUOTATION, EXAMPLE, SMALLEXAMPLE, LISP, SMALLLISP, CARTOUCHE,
- COPYING, FORMAT, SMALLFORMAT, DISPLAY, SMALLDISPLAY,
- FOOTNOTE,
+ COPYING, FORMAT, SMALLFORMAT, DISPLAY, SMALLDISPLAY, VERBATIM,
+ FOOTNOTE, LINEANNOTATION,
+ TIP, NOTE, IMPORTANT, WARNING, CAUTION,
ITEMIZE, ITEMFUNCTION, ITEM, ENUMERATE, TABLE, TABLEITEM, TABLETERM,
INDEXTERM,
+ MATH, DIMENSION,
XREF, XREFNODENAME, XREFINFONAME, XREFPRINTEDDESC, XREFINFOFILE,
XREFPRINTEDNAME,
INFOREF, INFOREFNODENAME, INFOREFREFNAME, INFOREFINFONAME,
UREF, UREFURL, UREFDESC, UREFREPLACEMENT,
EMAIL, EMAILADDRESS, EMAILNAME,
- GROUP,
- PRINTINDEX,
+ GROUP, FLOAT, FLOATTYPE, FLOATPOS, CAPTION, SHORTCAPTION,
+ FLOATTABLE, FLOATFIGURE, FLOATEXAMPLE, FLOATCARTOUCHE,
+ PRINTINDEX, LISTOFFLOATS,
ANCHOR,
- IMAGE,
+ IMAGE, INLINEIMAGE, IMAGEALTTEXT,
PRIMARY, SECONDARY, INFORMALFIGURE, MEDIAOBJECT, IMAGEOBJECT,
IMAGEDATA, TEXTOBJECT,
INDEXENTRY, PRIMARYIE, SECONDARYIE, INDEXDIV,
- MULTITABLE, TGROUP, COLSPEC, TBODY, ENTRY, ROW,
+ MULTITABLE, TGROUP, COLSPEC, THEAD, TBODY, ENTRY, ROW,
BOOKINFO, ABSTRACT, REPLACEABLE, ENVAR, COMMENT, FUNCTION, LEGALNOTICE,
+ CONTENTS, SHORTCONTENTS, DOCUMENTLANGUAGE,
+ SETVALUE, CLEARVALUE,
+ DEFINITION, DEFINITIONTERM, DEFINITIONITEM,
+ DEFCATEGORY, DEFFUNCTION, DEFVARIABLE, DEFPARAM, DEFDELIMITER, DEFTYPE,
+ DEFPARAMTYPE, DEFDATATYPE, DEFCLASS, DEFCLASSVAR, DEFOPERATION,
PARA
};
-extern void xml_insert_element (/* int name, int arg */);
-extern char *xml_id (/* char *id */);
+extern void xml_add_char (int character),
+ xml_asterisk (void),
+ xml_insert_element (int elt, int arg),
+ xml_insert_entity (char *entity_name),
+ xml_insert_footnote (char *note),
+ xml_insert_quotation (char *type, int arg),
+ xml_insert_indexentry (char *entry, char *node),
+ xml_insert_indexterm (char *indexterm, char *index),
+ xml_insert_docbook_image (char *name_arg),
+ xml_synindex (char *from, char *to),
+ xml_start_para (void),
+ xml_end_para (void),
+ xml_begin_document (char *output_filename),
+ xml_end_document (void),
+ xml_start_menu_entry (char *tem),
+ xml_end_menu (void),
+ xml_end_current_element (void),
+ xml_open_section (int level, char *name),
+ xml_close_sections (int level),
+ xml_begin_node (void),
+ xml_begin_index (void),
+ xml_end_index (void),
+ xml_begin_multitable (int ncolumns, int *column_widths),
+ xml_end_multitable (void),
+ xml_end_multitable_row (int first_row),
+ xml_end_multitable_column (void),
+ xml_begin_table (int type, char *item_function),
+ xml_end_table (int type),
+ xml_begin_item (void),
+ xml_begin_table_item (void),
+ xml_continue_table_item (void),
+ xml_begin_enumerate (char *enum_arg),
+ xml_end_enumerate (void),
+ xml_begin_docbook_float (int elt);
+
+extern char *xml_id (char *id);
+
+extern void xml_begin_definition (void),
+ xml_end_definition (void),
+ xml_process_defun_args (char **defun_args, int auto_var_p),
+ xml_begin_def_term (int base_type, const char *category,
+ char *defined_name, char *type_name, char *type_name2),
+ xml_end_def_term (void);
+
+extern int xml_current_stack_index (void),
+ xml_element (char *name);
+
+#if defined (VA_FPRINTF) && __STDC__
+void xml_insert_element_with_attribute (int elt, int arg, char *format, ...);
+#else
+void xml_insert_element_with_attribute ();
+#endif
#endif /* XML_H */
diff --git a/contrib/texinfo/makeinfo/xref.c b/contrib/texinfo/makeinfo/xref.c
new file mode 100644
index 0000000..314d4a0
--- /dev/null
+++ b/contrib/texinfo/makeinfo/xref.c
@@ -0,0 +1,620 @@
+/* xref.c -- cross references for Texinfo.
+ $Id: xref.c,v 1.4 2004/12/21 17:28:35 karl Exp $
+
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "system.h"
+#include "cmds.h"
+#include "float.h"
+#include "html.h"
+#include "index.h"
+#include "macro.h"
+#include "makeinfo.h"
+#include "node.h"
+#include "xml.h"
+#include "xref.h"
+
+/* Flags which control initial output string for xrefs. */
+int px_ref_flag = 0;
+int ref_flag = 0;
+
+/* Called in the multiple-argument case to make sure we generate a valid
+ Info reference. In the single-argument case, the :: we output
+ suffices for the Info readers to find the end of the reference. */
+static void
+add_xref_punctuation (void)
+{
+ if (px_ref_flag || ref_flag) /* user inserts punct after @xref */
+ {
+ /* Check if there's already punctuation. */
+ int next_char = next_nonwhitespace_character ();
+
+ if (next_char == -1)
+ /* EOF while looking for punctuation, let's
+ insert a period instead of crying. */
+ add_char ('.');
+ else if (next_char != ',' && next_char != '.')
+ /* period and comma terminate xrefs, and nothing else. Instead
+ of generating an Info reference that can't be followed,
+ though, just insert a period. Not pretty, but functional. */
+ add_char ('.');
+ }
+}
+
+/* Return next comma-delimited argument, but do not cross a close-brace
+ boundary. Clean up whitespace, too. If EXPAND is nonzero, replace
+ the entire brace-delimited argument list with its expansion before
+ looking for the next comma. */
+char *
+get_xref_token (int expand)
+{
+ char *string = 0;
+
+ if (docbook)
+ xml_in_xref_token = 1;
+
+ if (expand)
+ {
+ int old_offset = input_text_offset;
+ int old_lineno = line_number;
+
+ get_until_in_braces ("}", &string);
+ if (curchar () == '}') /* as opposed to end of text */
+ input_text_offset++;
+ if (input_text_offset > old_offset)
+ {
+ int limit = input_text_offset;
+
+ input_text_offset = old_offset;
+ line_number = old_lineno;
+ only_macro_expansion++;
+ replace_with_expansion (input_text_offset, &limit);
+ only_macro_expansion--;
+ }
+ free (string);
+ }
+
+ get_until_in_braces (",", &string);
+ if (curchar () == ',')
+ input_text_offset++;
+ fix_whitespace (string);
+
+ if (docbook)
+ xml_in_xref_token = 0;
+
+ return string;
+}
+
+
+/* NOTE: If you wonder why the HTML output is produced with such a
+ peculiar mix of calls to add_word and execute_string, here's the
+ reason. get_xref_token (1) expands all macros in a reference, but
+ any other commands, like @value, @@, etc., are left intact. To
+ expand them, we need to run the arguments through execute_string.
+ However, characters like <, &, > and others cannot be let into
+ execute_string, because they will be escaped. See the mess? */
+
+/* Make a cross reference. */
+void
+cm_xref (int arg)
+{
+ if (arg == START)
+ {
+ char *arg1 = get_xref_token (1); /* expands all macros in xref */
+ char *arg2 = get_xref_token (0);
+ char *arg3 = get_xref_token (0);
+ char *arg4 = get_xref_token (0);
+ char *arg5 = get_xref_token (0);
+ char *tem;
+
+ /* "@xref{,Foo,, Bar, Baz} is not valid usage of @xref. The
+ first argument must never be blank." --rms.
+ We hereby comply by disallowing such constructs. */
+ if (!*arg1)
+ line_error (_("First argument to cross-reference may not be empty"));
+
+ if (docbook)
+ {
+ if (!ref_flag)
+ add_word (px_ref_flag || printing_index
+ ? (char *) _("see ") : (char *) _("See "));
+
+ if (!*arg4 && !*arg5)
+ {
+ char *arg1_id = xml_id (arg1);
+
+ if (*arg2 || *arg3)
+ {
+ xml_insert_element_with_attribute (XREFNODENAME, START,
+ "linkend=\"%s\"", arg1_id);
+ free (arg1_id);
+ execute_string ("%s", *arg3 ? arg3 : arg2);
+ xml_insert_element (XREFNODENAME, END);
+ }
+ else
+ {
+ xml_insert_element_with_attribute (XREF, START,
+ "linkend=\"%s\"", arg1_id);
+ xml_insert_element (XREF, END);
+ free (arg1_id);
+ }
+ }
+ else if (*arg5)
+ {
+ add_word_args (_("See section ``%s'' in "), *arg3 ? arg3 : arg1);
+ xml_insert_element (CITE, START);
+ add_word (arg5);
+ xml_insert_element (CITE, END);
+ }
+ else if (*arg4)
+ {
+ /* Very sad, we are losing xrefs made to ``info only'' books. */
+ }
+ }
+ else if (xml)
+ {
+ if (!ref_flag)
+ add_word_args ("%s", px_ref_flag ? _("see ") : _("See "));
+
+ xml_insert_element (XREF, START);
+ xml_insert_element (XREFNODENAME, START);
+ execute_string ("%s", arg1);
+ xml_insert_element (XREFNODENAME, END);
+ if (*arg2)
+ {
+ xml_insert_element (XREFINFONAME, START);
+ execute_string ("%s", arg2);
+ xml_insert_element (XREFINFONAME, END);
+ }
+ if (*arg3)
+ {
+ xml_insert_element (XREFPRINTEDDESC, START);
+ execute_string ("%s", arg3);
+ xml_insert_element (XREFPRINTEDDESC, END);
+ }
+ if (*arg4)
+ {
+ xml_insert_element (XREFINFOFILE, START);
+ execute_string ("%s", arg4);
+ xml_insert_element (XREFINFOFILE, END);
+ }
+ if (*arg5)
+ {
+ xml_insert_element (XREFPRINTEDNAME, START);
+ execute_string ("%s", arg5);
+ xml_insert_element (XREFPRINTEDNAME, END);
+ }
+ xml_insert_element (XREF, END);
+ }
+ else if (html)
+ {
+ if (!ref_flag)
+ add_word_args ("%s", px_ref_flag ? _("see ") : _("See "));
+ }
+ else
+ add_word_args ("%s", px_ref_flag ? "*note " : "*Note ");
+
+ if (!xml)
+ {
+ if (*arg5 || *arg4)
+ {
+ /* arg1 - node name
+ arg2 - reference name
+ arg3 - title or topic (and reference name if arg2 is NULL)
+ arg4 - info file name
+ arg5 - printed manual title */
+ char *ref_name;
+
+ if (!*arg2)
+ {
+ if (*arg3)
+ ref_name = arg3;
+ else
+ ref_name = arg1;
+ }
+ else
+ ref_name = arg2;
+
+ if (html)
+ { /* More to do eventually, down to Unicode
+ Normalization Form C. See the HTML Xref nodes in
+ the manual. */
+ char *file_arg = arg4;
+ add_html_elt ("<a href=");
+
+ {
+ /* If there's a directory part, ignore it. */
+ char *p = strrchr (file_arg, '/');
+ if (p)
+ file_arg = p + 1;
+
+ /* If there's a dot, make it a NULL terminator, so the
+ extension does not get into the way. */
+ p = strrchr (file_arg , '.');
+ if (p != NULL)
+ *p = 0;
+ }
+
+ if (! *file_arg)
+ warning (_("Empty file name for HTML cross reference in `%s'"),
+ arg4);
+
+ /* Note that if we are splitting, and the referenced
+ tag is an anchor rather than a node, we will
+ produce a reference to a file whose name is
+ derived from the anchor name. However, only
+ nodes create files, so we are referencing a
+ non-existent file. cm_anchor, which see, deals
+ with that problem. */
+ if (splitting)
+ execute_string ("\"../%s/", file_arg);
+ else
+ execute_string ("\"%s.html", file_arg);
+ /* Do not collapse -- to -, etc., in references. */
+ in_fixed_width_font++;
+ tem = expansion (arg1, 0); /* expand @-commands in node */
+ in_fixed_width_font--;
+ add_anchor_name (tem, 1);
+ free (tem);
+ add_word ("\">");
+ execute_string ("%s",ref_name);
+ add_word ("</a>");
+ }
+ else
+ {
+ execute_string ("%s:", ref_name);
+ in_fixed_width_font++;
+ execute_string (" (%s)%s", arg4, arg1);
+ add_xref_punctuation ();
+ in_fixed_width_font--;
+ }
+
+ /* Free all of the arguments found. */
+ if (arg1) free (arg1);
+ if (arg2) free (arg2);
+ if (arg3) free (arg3);
+ if (arg4) free (arg4);
+ if (arg5) free (arg5);
+ return;
+ }
+ else
+ remember_node_reference (arg1, line_number, followed_reference);
+
+ if (*arg3)
+ {
+ if (html)
+ {
+ add_html_elt ("<a href=\"");
+ in_fixed_width_font++;
+ tem = expansion (arg1, 0);
+ in_fixed_width_font--;
+ add_anchor_name (tem, 1);
+ free (tem);
+ add_word ("\">");
+ execute_string ("%s", *arg2 ? arg2 : arg3);
+ add_word ("</a>");
+ }
+ else
+ {
+ execute_string ("%s:", *arg2 ? arg2 : arg3);
+ in_fixed_width_font++;
+ execute_string (" %s", arg1);
+ add_xref_punctuation ();
+ in_fixed_width_font--;
+ }
+ }
+ else
+ {
+ if (html)
+ {
+ add_html_elt ("<a href=\"");
+ in_fixed_width_font++;
+ tem = expansion (arg1, 0);
+ in_fixed_width_font--;
+ add_anchor_name (tem, 1);
+ free (tem);
+ add_word ("\">");
+ if (*arg2)
+ execute_string ("%s", arg2);
+ else
+ {
+ char *fref = get_float_ref (arg1);
+ execute_string ("%s", fref ? fref : arg1);
+ free (fref);
+ }
+ add_word ("</a>");
+ }
+ else
+ {
+ if (*arg2)
+ {
+ execute_string ("%s:", arg2);
+ in_fixed_width_font++;
+ execute_string (" %s", arg1);
+ add_xref_punctuation ();
+ in_fixed_width_font--;
+ }
+ else
+ {
+ char *fref = get_float_ref (arg1);
+ if (fref)
+ { /* Reference is being made to a float. */
+ execute_string ("%s:", fref);
+ in_fixed_width_font++;
+ execute_string (" %s", arg1);
+ add_xref_punctuation ();
+ in_fixed_width_font--;
+ }
+ else
+ {
+ in_fixed_width_font++;
+ execute_string ("%s::", arg1);
+ in_fixed_width_font--;
+ }
+ }
+ }
+ }
+ }
+ /* Free all of the arguments found. */
+ if (arg1) free (arg1);
+ if (arg2) free (arg2);
+ if (arg3) free (arg3);
+ if (arg4) free (arg4);
+ if (arg5) free (arg5);
+ }
+ else
+ { /* Check that the next non-whitespace character is valid to follow
+ an xref (so Info readers can find the node names).
+ `input_text_offset' is pointing at the "}" which ended the xref
+ command. This is not used for @pxref or @ref, since we insert
+ the necessary punctuation above, if needed. */
+ int temp = next_nonwhitespace_character ();
+
+ if (temp == -1)
+ warning (_("End of file reached while looking for `.' or `,'"));
+ else if (temp != '.' && temp != ',')
+ warning (_("`.' or `,' must follow @%s, not `%c'"), command, temp);
+ }
+}
+
+void
+cm_pxref (int arg)
+{
+ if (arg == START)
+ {
+ px_ref_flag++;
+ cm_xref (arg);
+ px_ref_flag--;
+ }
+ /* cm_xref isn't called with arg == END, which disables the code near
+ the end of cm_xref that checks for `.' or `,' after the
+ cross-reference. This is because cm_xref generates the required
+ character itself (when needed) if px_ref_flag is set. */
+}
+
+void
+cm_ref (int arg)
+{
+ /* See the comments in cm_pxref about the checks for punctuation. */
+ if (arg == START)
+ {
+ ref_flag++;
+ cm_xref (arg);
+ ref_flag--;
+ }
+}
+
+void
+cm_inforef (int arg)
+{
+ if (arg == START)
+ {
+ char *node = get_xref_token (1); /* expands all macros in inforef */
+ char *pname = get_xref_token (0);
+ char *file = get_xref_token (0);
+
+ /* (see comments at cm_xref). */
+ if (!*node)
+ line_error (_("First argument to @inforef may not be empty"));
+
+ if (xml && !docbook)
+ {
+ xml_insert_element (INFOREF, START);
+ xml_insert_element (INFOREFNODENAME, START);
+ execute_string ("%s", node);
+ xml_insert_element (INFOREFNODENAME, END);
+ if (*pname)
+ {
+ xml_insert_element (INFOREFREFNAME, START);
+ execute_string ("%s", pname);
+ xml_insert_element (INFOREFREFNAME, END);
+ }
+ xml_insert_element (INFOREFINFONAME, START);
+ execute_string ("%s", file);
+ xml_insert_element (INFOREFINFONAME, END);
+
+ xml_insert_element (INFOREF, END);
+ }
+ else if (html)
+ {
+ char *tem;
+
+ add_word ((char *) _("see "));
+ /* html fixxme: revisit this */
+ add_html_elt ("<a href=");
+ if (splitting)
+ execute_string ("\"../%s/", file);
+ else
+ execute_string ("\"%s.html", file);
+ tem = expansion (node, 0);
+ add_anchor_name (tem, 1);
+ add_word ("\">");
+ execute_string ("%s", *pname ? pname : tem);
+ add_word ("</a>");
+ free (tem);
+ }
+ else
+ {
+ if (*pname)
+ execute_string ("*note %s: (%s)%s", pname, file, node);
+ else
+ execute_string ("*note (%s)%s::", file, node);
+ }
+
+ free (node);
+ free (pname);
+ free (file);
+ }
+}
+
+/* A URL reference. */
+void
+cm_uref (int arg)
+{
+ if (arg == START)
+ {
+ extern int printing_index;
+ char *url = get_xref_token (1); /* expands all macros in uref */
+ char *desc = get_xref_token (0);
+ char *replacement = get_xref_token (0);
+
+ if (docbook)
+ {
+ xml_insert_element_with_attribute (UREF, START, "url=\"%s\"",
+ text_expansion (url));
+ if (*replacement)
+ execute_string ("%s", replacement);
+ else if (*desc)
+ execute_string ("%s", desc);
+ else
+ execute_string ("%s", url);
+ xml_insert_element (UREF, END);
+ }
+ else if (xml)
+ {
+ xml_insert_element (UREF, START);
+ xml_insert_element (UREFURL, START);
+ execute_string ("%s", url);
+ xml_insert_element (UREFURL, END);
+ if (*desc)
+ {
+ xml_insert_element (UREFDESC, START);
+ execute_string ("%s", desc);
+ xml_insert_element (UREFDESC, END);
+ }
+ if (*replacement)
+ {
+ xml_insert_element (UREFREPLACEMENT, START);
+ execute_string ("%s", replacement);
+ xml_insert_element (UREFREPLACEMENT, END);
+ }
+ xml_insert_element (UREF, END);
+ }
+ else if (html)
+ { /* never need to show the url */
+ add_html_elt ("<a href=");
+ /* don't collapse `--' etc. in the url */
+ in_fixed_width_font++;
+ execute_string ("\"%s\"", url);
+ in_fixed_width_font--;
+ add_word (">");
+ execute_string ("%s", *replacement ? replacement
+ : (*desc ? desc : url));
+ add_word ("</a>");
+ }
+ else if (*replacement) /* do not show the url */
+ execute_string ("%s", replacement);
+ else if (*desc) /* show both text and url */
+ {
+ execute_string ("%s ", desc);
+ in_fixed_width_font++;
+ execute_string ("(%s)", url);
+ in_fixed_width_font--;
+ }
+ else /* no text at all, so have the url to show */
+ {
+ in_fixed_width_font++;
+ execute_string ("%s%s%s",
+ printing_index ? "" : "`",
+ url,
+ printing_index ? "" : "'");
+ in_fixed_width_font--;
+ }
+ if (url)
+ free (url);
+ if (desc)
+ free (desc);
+ if (replacement)
+ free (replacement);
+ }
+}
+
+/* An email reference. */
+void
+cm_email (int arg)
+{
+ if (arg == START)
+ {
+ char *addr = get_xref_token (1); /* expands all macros in email */
+ char *name = get_xref_token (0);
+
+ if (xml && docbook)
+ {
+ xml_insert_element_with_attribute (EMAIL, START, "url=\"mailto:%s\"", addr);
+ if (*name)
+ execute_string ("%s", name);
+ xml_insert_element (EMAIL, END);
+ }
+ else if (xml)
+ {
+ xml_insert_element (EMAIL, START);
+ xml_insert_element (EMAILADDRESS, START);
+ execute_string ("%s", addr);
+ xml_insert_element (EMAILADDRESS, END);
+ if (*name)
+ {
+ xml_insert_element (EMAILNAME, START);
+ execute_string ("%s", name);
+ xml_insert_element (EMAILNAME, END);
+ }
+ xml_insert_element (EMAIL, END);
+ }
+ else if (html)
+ {
+ add_html_elt ("<a href=");
+ /* don't collapse `--' etc. in the address */
+ in_fixed_width_font++;
+ execute_string ("\"mailto:%s\"", addr);
+ in_fixed_width_font--;
+ add_word (">");
+ execute_string ("%s", *name ? name : addr);
+ add_word ("</a>");
+ }
+ else
+ {
+ execute_string ("%s%s", name, *name ? " " : "");
+ in_fixed_width_font++;
+ execute_string ("<%s>", addr);
+ in_fixed_width_font--;
+ }
+
+ if (addr)
+ free (addr);
+ if (name)
+ free (name);
+ }
+}
diff --git a/contrib/texinfo/makeinfo/xref.h b/contrib/texinfo/makeinfo/xref.h
new file mode 100644
index 0000000..8f2711b
--- /dev/null
+++ b/contrib/texinfo/makeinfo/xref.h
@@ -0,0 +1,30 @@
+/* xref.h -- declarations for the cross references.
+ $Id: xref.h,v 1.1 2004/04/11 17:56:47 karl Exp $
+
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef XREF_H
+#define XREF_H
+
+enum reftype
+{
+ menu_reference, followed_reference
+};
+
+extern char *get_xref_token (int expand);
+
+#endif /* not XREF_H */
OpenPOWER on IntegriCloud