diff options
author | Ruslan Ermilov <ru@FreeBSD.org> | 2002-03-25 13:08:32 +0000 |
---|---|---|
committer | Ruslan Ermilov <ru@FreeBSD.org> | 2002-03-25 13:08:32 +0000 |
commit | 093e96ffd940616ae8b6bdc4f3802d834d0c8501 (patch) | |
tree | d30298f299d26f72720470ee4dada5442da671c8 /contrib/texinfo/makeinfo | |
parent | 2a2c967152dcdac4684aaf9106ef99dc445cc7de (diff) | |
parent | 3423f6a2cba6d3cc1f5f66cdb873f30d92afbffb (diff) |
This commit was generated by cvs2svn to compensate for changes in r93139,
which included commits to RCS files with non-trunk default branches.
Notes
Notes:
svn path=/head/; revision=93140
Diffstat (limited to 'contrib/texinfo/makeinfo')
27 files changed, 4802 insertions, 647 deletions
diff --git a/contrib/texinfo/makeinfo/README b/contrib/texinfo/makeinfo/README index a6f97ebed4c5..1b45f02c4b21 100644 --- a/contrib/texinfo/makeinfo/README +++ b/contrib/texinfo/makeinfo/README @@ -2,7 +2,7 @@ makeinfo is a standalone program to convert Texinfo source into Info files readable with standalone info or M-x info in Emacs. makeinfo can also output plain ASCII (with --no-headers) -or HTML (with --html). +or HTML (with --html) or XML (with --xml). The Emacs function M-x texinfo-format-buffer does more or less the same job, but makeinfo is faster and gives better error messages. diff --git a/contrib/texinfo/makeinfo/cmds.c b/contrib/texinfo/makeinfo/cmds.c index 65d382e8d4ba..968bc8f0afb9 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.57 1999/09/19 16:39:35 karl Exp $ + $Id: cmds.c,v 1.69 2002/02/09 00:54:51 karl Exp $ - Copyright (C) 1998, 99 Free Software Foundation, Inc. + Copyright (C) 1998, 99, 2000, 01 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 @@ -29,6 +29,7 @@ #include "node.h" #include "sectioning.h" #include "toc.h" +#include "xml.h" #ifdef TM_IN_SYS_TIME #include <sys/time.h> @@ -45,7 +46,8 @@ void 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_strong (), cm_var (), cm_sc (), cm_w (), cm_email (), cm_url (), + cm_verb (), cm_documentdescription (); void cm_anchor (), cm_node (), cm_menu (), cm_xref (), cm_ftable (), @@ -61,7 +63,8 @@ void 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_tt (); + cm_multitable (), cm_settitle (), cm_titlefont (), cm_tt (), + cm_verbatim (), cm_verbatiminclude (), cm_titlepage (); /* Conditionals. */ void cm_set (), cm_clear (), cm_ifset (), cm_ifclear (); @@ -80,7 +83,7 @@ static const char small_tag[] = "small"; COMMAND command_table[] = { { "\t", insert_space, NO_BRACE_ARGS }, { "\n", insert_space, NO_BRACE_ARGS }, - { " ", insert_self, NO_BRACE_ARGS }, + { " ", insert_space, NO_BRACE_ARGS }, { "!", insert_self, NO_BRACE_ARGS }, { "\"", cm_accent_umlaut, MAYBE_BRACE_ARGS }, { "'", cm_accent_acute, MAYBE_BRACE_ARGS }, @@ -108,7 +111,10 @@ COMMAND command_table[] = { { "aa", cm_special_char, BRACE_ARGS }, { "acronym", cm_acronym, BRACE_ARGS }, { "ae", cm_special_char, BRACE_ARGS }, + { "afivepaper", cm_ignore_line, NO_BRACE_ARGS }, + { "afourlatex", cm_ignore_line, NO_BRACE_ARGS }, { "afourpaper", cm_ignore_line, NO_BRACE_ARGS }, + { "afourwide", cm_ignore_line, NO_BRACE_ARGS }, { "alias", cm_alias, NO_BRACE_ARGS }, { "anchor", cm_anchor, BRACE_ARGS }, { "appendix", cm_appendix, NO_BRACE_ARGS }, @@ -182,6 +188,7 @@ COMMAND command_table[] = { { "direntry", cm_direntry, NO_BRACE_ARGS }, { "display", cm_display, NO_BRACE_ARGS }, { "dmn", cm_no_op, BRACE_ARGS }, + { "documentdescription", cm_documentdescription, NO_BRACE_ARGS }, { "documentencoding", cm_documentencoding, NO_BRACE_ARGS }, { "documentlanguage", cm_documentlanguage, NO_BRACE_ARGS }, { "dotaccent", cm_accent, MAYBE_BRACE_ARGS }, @@ -294,7 +301,7 @@ COMMAND command_table[] = { { "subsection", cm_subsection, NO_BRACE_ARGS }, { "subsubheading", cm_subsubheading, NO_BRACE_ARGS }, { "subsubsection", cm_subsubsection, NO_BRACE_ARGS }, - { "summarycontents", cm_no_op, NO_BRACE_ARGS }, + { "summarycontents", cm_shortcontents, NO_BRACE_ARGS }, { "syncodeindex", cm_synindex, NO_BRACE_ARGS }, { "synindex", cm_synindex, NO_BRACE_ARGS }, { "t", cm_tt, BRACE_ARGS }, @@ -320,6 +327,9 @@ COMMAND command_table[] = { { "v", cm_accent, MAYBE_BRACE_ARGS }, { "value", cm_value, BRACE_ARGS }, { "var", cm_var, BRACE_ARGS }, + { "verb", cm_verb, NO_BRACE_ARGS }, + { "verbatim", cm_verbatim, NO_BRACE_ARGS }, + { "verbatiminclude", cm_verbatiminclude, NO_BRACE_ARGS }, { "vindex", cm_vindex, NO_BRACE_ARGS }, { "vtable", cm_vtable, NO_BRACE_ARGS }, { "w", cm_w, BRACE_ARGS }, @@ -363,7 +373,12 @@ insert_space (arg) int arg; { if (arg == START) - add_char (' '); + { + if (xml && !docbook) + xml_insert_entity ("space"); + else + add_char (' '); + } } /* Force a line break in the output. */ @@ -372,6 +387,10 @@ cm_asterisk () { if (html) add_word ("<br>"); + else if (xml && !docbook) + xml_insert_entity ("linebreak"); + else if (docbook) + xml_asterisk (); else { close_single_paragraph (); @@ -385,7 +404,14 @@ cm_dots (arg) int arg; { if (arg == START) - add_word (html ? "<small>...</small>" : "..."); + { + if (xml && !docbook) + xml_insert_entity ("dots"); + else if (docbook) + xml_insert_entity ("hellip"); + else + add_word (html ? "<small>...</small>" : "..."); + } } /* Insert ellipsis for sentence end. */ @@ -394,7 +420,17 @@ cm_enddots (arg) int arg; { if (arg == START) - add_word (html ? "<small>...</small>." : "...."); + { + if (xml && !docbook) + xml_insert_entity ("enddots"); + else if (docbook) + { + xml_insert_entity ("hellip"); + add_char ('.'); + } + else + add_word (html ? "<small>...</small>." : "...."); + } } void @@ -405,6 +441,10 @@ cm_bullet (arg) { if (html) add_word ("•"); + else if (xml && !docbook) + xml_insert_entity ("bullet"); + else if (docbook) + xml_insert_entity ("bull"); else add_char ('*'); } @@ -415,7 +455,12 @@ cm_minus (arg) int arg; { if (arg == START) - add_char ('-'); + { + if (xml) + xml_insert_entity ("minus"); + else + add_char ('-'); + } } /* Insert "TeX". */ @@ -424,7 +469,12 @@ cm_TeX (arg) int arg; { if (arg == START) - add_word ("TeX"); + { + if (xml && ! docbook) + xml_insert_entity ("tex"); + else + add_word ("TeX"); + } } /* Copyright symbol. */ @@ -433,10 +483,16 @@ cm_copyright (arg) int arg; { if (arg == START) + { if (html) add_word ("©"); + else if (xml && !docbook) + xml_insert_entity ("copyright"); + else if (docbook) + xml_insert_entity ("copy"); else add_word ("(C)"); + } } void @@ -462,6 +518,8 @@ cm_acronym (arg) { if (html) insert_html_tag (arg, small_tag); + else if (xml) + xml_insert_element (ACRONYM, arg); } void @@ -471,12 +529,18 @@ cm_tt (arg) /* @t{} is a no-op in Info. */ if (html) insert_html_tag (arg, "tt"); + else if (xml) + xml_insert_element (TT, arg); } void cm_code (arg) int arg; { + if (xml) + xml_insert_element (CODE, arg); + else + { extern int printing_index; if (arg == START) @@ -495,13 +559,16 @@ cm_code (arg) if (!printing_index) add_meta_char ('\''); } + } } void cm_kbd (arg) int arg; { - if (html) + if (xml) + xml_insert_element (KBD, arg); + else if (html) { /* Seems like we should increment in_fixed_width_font for Info format too, but then the quote-omitting special case gets confused. Punt. */ @@ -520,7 +587,9 @@ cm_kbd (arg) void cm_url (arg, start, end) { - if (html) + if (xml) + xml_insert_element (URL, arg); + else if (html) { if (arg == START) add_word ("<<code>"); @@ -538,7 +607,9 @@ void cm_key (arg) int arg; { - if (html) + if (xml) + xml_insert_element (KEY, arg); + else if (html) add_word (arg == START ? "<" : ">"); else add_char (arg == START ? '<' : '>'); @@ -558,6 +629,10 @@ void cm_var (arg, start_pos, end_pos) int arg, start_pos, end_pos; { + if (xml) + xml_insert_element (VAR, arg); + else + { not_fixed_width (arg); if (html) @@ -573,12 +648,17 @@ cm_var (arg, start_pos, end_pos) start_pos++; } } + } } void cm_sc (arg, start_pos, end_pos) int arg, start_pos, end_pos; { + if (xml) + xml_insert_element (SC, arg); + else + { not_fixed_width (arg); if (arg == START) @@ -588,11 +668,15 @@ cm_sc (arg, start_pos, end_pos) } else { - int all_upper = 1; + int all_upper; if (html) start_pos += sizeof (small_tag) + 2 - 1; /* skip <small> */ + /* 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]; @@ -607,35 +691,111 @@ cm_sc (arg, start_pos, end_pos) if (html) insert_html_tag (arg, small_tag); } + } } void cm_dfn (arg, position) int arg, position; { + if (xml) + xml_insert_element (DFN, arg); + else + { if (html) insert_html_tag (arg, "dfn"); else if (arg == START) add_char ('"'); else add_meta_char ('"'); + } } void cm_emph (arg) int arg; { - if (html) + if (xml) + xml_insert_element (EMPH, arg); + else if (html) insert_html_tag (arg, "em"); else add_char ('_'); } void +cm_verb (arg) + int arg; +{ + int character; + int delimiter; + int seen_end = 0; + + in_fixed_width_font++; + /* are these necessary ? */ + last_char_was_newline = 0; + + if (html) + add_word ("<pre>"); + + if (input_text_offset < input_text_length) + { + character = curchar (); + if (character == '{') + input_text_offset++; + else + line_error (_("`{' expected, but saw `%c'"), character); + } + + if (input_text_offset < input_text_length) + { + delimiter = curchar (); + input_text_offset++; + } + + while (input_text_offset < input_text_length) + { + character = curchar (); + + if (character == '\n') + line_number++; + /* + Assume no newlines in END_VERBATIM + */ + else if (character == delimiter) + { + seen_end = 1; + input_text_offset++; + break; + } + + add_char (character); + input_text_offset++; + } + + if (!seen_end) + warning (_("end of file inside verb block")); + + if (input_text_offset < input_text_length) + { + character = curchar (); + if (character == '}') + input_text_offset++; + else + line_error (_("`}' expected, but saw `%c'"), character); + } + + if (html) + add_word ("</pre>"); +} + +void cm_strong (arg, position) int arg, position; { - if (html) + if (xml) + xml_insert_element (STRONG, arg); + else if (html) insert_html_tag (arg, "strong"); else add_char ('*'); @@ -645,7 +805,9 @@ void cm_cite (arg, position) int arg, position; { - if (html) + if (xml) + xml_insert_element (CITE, arg); + else if (html) insert_html_tag (arg, "cite"); else { @@ -661,6 +823,8 @@ void cm_not_fixed_width (arg, start, end) int arg, start, end; { + if (xml) + xml_insert_element (NOTFIXEDWIDTH, arg); not_fixed_width (arg); } @@ -668,7 +832,9 @@ void cm_i (arg) int arg; { - if (html) + if (xml) + xml_insert_element (I, arg); + else if (html) insert_html_tag (arg, "i"); else not_fixed_width (arg); @@ -678,7 +844,9 @@ void cm_b (arg) int arg; { - if (html) + if (xml) + xml_insert_element (B, arg); + else if (html) insert_html_tag (arg, "b"); else not_fixed_width (arg); @@ -688,32 +856,40 @@ void cm_r (arg) int arg; { - extern int printing_index; - - /* People use @r{} in index entries like this: - - @findex foo@r{, some text} - - This is supposed to produce output as if the entry were saying - "@code{foo}, some text", since the "fn" index is typeset as - @code. The following attempts to do the same in HTML. Note that - this relies on the fact that only @code bumps up the variable - in_fixed_width_font while processing index entries in HTML mode. */ - if (html && printing_index) + if (xml) + xml_insert_element (R, arg); + else { - int level = in_fixed_width_font; + extern int printing_index; - while (level--) - insert_html_tag (arg == START ? END : START, "code"); + /* People use @r{} in index entries like this: + + @findex foo@r{, some text} + + This is supposed to produce output as if the entry were saying + "@code{foo}, some text", since the "fn" index is typeset as + @code. The following attempts to do the same in HTML. Note that + this relies on the fact that only @code bumps up the variable + in_fixed_width_font while processing index entries in HTML mode. */ + if (html && printing_index) + { + int level = in_fixed_width_font; + + while (level--) + insert_html_tag (arg == START ? END : START, "code"); + } + + not_fixed_width (arg); } - - not_fixed_width (arg); } void cm_titlefont (arg) int arg; { + if (xml) + xml_insert_element (TITLEFONT, arg); + else not_fixed_width (arg); } @@ -776,15 +952,27 @@ cm_setfilename () char *filename; get_rest_of_line (1, &filename); /* warning ("`@%s %s' encountered and ignored", command, filename); */ + if (xml) + add_word_args ("<setfilename>%s</setfilename>", filename); free (filename); } void cm_settitle () { - get_rest_of_line (0, &title); + if (xml) + { + xml_begin_document (); + xml_insert_element (SETTITLE, START); + get_rest_of_line (0, &title); + execute_string ("%s", title); + xml_insert_element (SETTITLE, END); + } + else + get_rest_of_line (0, &title); } + /* Ignore argument in braces. */ void cm_ignore_arg (arg, start_pos, end_pos) @@ -813,7 +1001,16 @@ cm_sp () if (sscanf (line, "%d", &lines) != 1 || lines <= 0) line_error (_("@sp requires a positive numeric argument, not `%s'"), line); else - { /* Must disable filling since otherwise multiple newlines is like + { + if (xml) + { + xml_insert_element_with_attribute (SP, START, "lines=\"%s\"", line); + /* insert_string (line);*/ + xml_insert_element (SP, END); + } + 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; @@ -821,6 +1018,9 @@ cm_sp () close_paragraph (); + if (lines && html && !executing_string) + html_output_head (); + while (lines--) { if (html) @@ -831,6 +1031,7 @@ cm_sp () filling_enabled = save_filling_enabled; } + } free (line); } @@ -840,8 +1041,16 @@ cm_dircategory () { char *line; - if (html) + if (html || docbook) cm_ignore_line (); + else if (xml) + { + xml_insert_element (DIRCATEGORY, START); + get_rest_of_line (1, &line); + insert_string (line); + free (line); + xml_insert_element (DIRCATEGORY, END); + } else { get_rest_of_line (1, &line); @@ -860,23 +1069,33 @@ cm_dircategory () /* Start a new line with just this text on it. Then center the line of text. - This always ends the current paragraph. */ + */ void cm_center () { + if (xml) + { + unsigned char *line; + xml_insert_element (CENTER, START); + get_rest_of_line (0, (char **)&line); + execute_string ("%s", (char *)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; - close_paragraph (); filling_enabled = indented_fill = 0; cm_noindent (); start = output_paragraph_offset; if (html) - add_word ("<p align=\"center\">"); + add_word ("<div align=\"center\">"); inhibit_output_flushing (); get_rest_of_line (0, (char **)&line); @@ -884,7 +1103,7 @@ cm_center () free (line); uninhibit_output_flushing (); if (html) - add_word ("</p>"); + add_word ("</div>"); else { @@ -914,9 +1133,9 @@ cm_center () } insert ('\n'); - close_paragraph (); filling_enabled = save_filling_enabled; indented_fill = save_indented_fill; + } } /* Show what an expression returns. */ @@ -1012,10 +1231,14 @@ cm_exdent () in_fixed_width_font = save_in_fixed_width_font; } - -/* Remember this file, and move onto the next. */ -void -cm_include () +/* + Read include-filename, process the include-file: + verbatim_include == 0: process through reader_loop + verbatim_include != 0: process through handle_verbatim_environment + */ +static void +handle_include (verbatim_include) + int verbatim_include; { char *filename; @@ -1041,7 +1264,7 @@ cm_include () i *= 2; printf ("%*s", i, ""); - printf ("%c%s %s\n", COMMAND_PREFIX, command, filename); + printf ("%c%s `%s'\n", COMMAND_PREFIX, command, filename); fflush (stdout); } @@ -1052,8 +1275,8 @@ cm_include () popfile (); line_number--; - /* Cannot "@include foo", in line 5 of "/wh/bar". */ - line_error ("%c%s %s: %s", COMMAND_PREFIX, command, filename, + /* /wh/bar:5: @include/@verbatiminclude `foo': No such file or dir */ + line_error ("%c%s `%s': %s", COMMAND_PREFIX, command, filename, strerror (errno)); free (filename); @@ -1062,14 +1285,34 @@ cm_include () else { if (macro_expansion_output_stream && !executing_string) - remember_itext (input_text, input_text_offset); - reader_loop (); + remember_itext (input_text, input_text_offset); + + if (!verbatim_include) + reader_loop (); + else + handle_verbatim_environment (0); } free (filename); popfile (); } +/* Include file as if put in @verbatim environment */ +void +cm_verbatiminclude () +{ + handle_include (1); +} + + +/* Remember this file, and move onto the next. */ +void +cm_include () +{ + handle_include (0); +} + + /* @bye: Signals end of processing. Easy to make this happen. */ void diff --git a/contrib/texinfo/makeinfo/defun.c b/contrib/texinfo/makeinfo/defun.c index c62aba791d37..b261a9918cfb 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.11 1999/07/11 16:50:19 karl Exp $ + $Id: defun.c,v 1.18 2002/01/22 18:01:24 karl Exp $ - Copyright (C) 1998, 99 Free Software Foundation, Inc. + Copyright (C) 1998, 99, 2000, 01, 02 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,6 +19,7 @@ #include "system.h" #include "defun.h" +#include "docbook.h" #include "insertion.h" #include "makeinfo.h" @@ -395,9 +396,9 @@ defun_internal (type, x_p) type_name = next_nonwhite_defun_arg (&scan_args); /* The type name for typed languages. */ - if (base_type == deftypemethod - || base_type == deftypeivar - || base_type == deftypeop + if ((base_type == deftypemethod) + || (base_type == deftypeivar) + || (base_type == deftypeop) ) type_name2 = next_nonwhite_defun_arg (&scan_args); @@ -422,6 +423,13 @@ defun_internal (type, x_p) defined_name = tem; } + /* It's easy to write @defun foo(arg1 arg2), but a following ( is + misparsed by texinfo.tex and this is next to impossible to fix. + Warn about it. */ + if (*scan_args && **scan_args && **scan_args == '(') + warning ("`%c' follows defined name `%s' instead of whitespace", + **scan_args, defined_name); + if (!x_p) begin_insertion (type); @@ -430,11 +438,15 @@ defun_internal (type, x_p) current_indent -= default_indentation_increment; start_paragraph (); - if (html && !x_p) + if (!x_p) { /* Start the definition on new paragraph. */ - add_word ("<p>\n"); + if (html) + add_word ("<p>\n"); + if (docbook) + docbook_begin_paragraph (); + } - if (!html) + if (!html && !docbook) switch (base_type) { case deffn: @@ -473,13 +485,16 @@ defun_internal (type, x_p) /* 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_word ("<table width=\"100%\">\n"); + { + 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_word ("<td align=\"left\">"); + add_html_elt ("<td align=\"left\">"); switch (base_type) { @@ -487,24 +502,61 @@ defun_internal (type, x_p) case defvr: case deftp: /* <i> is for the following function arguments. */ - add_word_args ("<b>%s</b><i>", defined_name); + add_word ("<b>"); + execute_string ("%s", defined_name); + add_word ("</b><i>"); break; case deftypefn: case deftypevr: - add_word_args ("%s <b>%s</b><i>", type_name, defined_name); + execute_string ("%s ", type_name); + add_word ("<b>"); + execute_string ("%s", defined_name); + add_word ("</b><i>"); break; case defcv: case defop: - add_word_args ("<b>%s</b><i>", defined_name); + add_word ("<b>"); + execute_string ("%s", defined_name); + add_word ("</b><i>"); break; case deftypemethod: case deftypeop: case deftypeivar: - add_word_args ("%s <b>%s</b><i>", type_name2, defined_name); + execute_string ("%s ", type_name2); + add_word ("<b>"); + execute_string ("%s", defined_name); + add_word ("</b><i>"); break; } } /* if (html)... */ + if (docbook) + { + switch (base_type) + { + case deffn: + case defvr: + case deftp: + case defcv: + case defop: + add_word_args ("<%s>%s</%s>", DB_FUNCTION, defined_name, + DB_FUNCTION); + break; + case deftypefn: + case deftypevr: + add_word_args ("%s <%s>%s</%s>", type_name, DB_FUNCTION, + defined_name, DB_FUNCTION); + break; + case deftypemethod: + case deftypeop: + case deftypeivar: + add_word_args ("%s <%s>%s</%s>", type_name2, DB_FUNCTION, + defined_name, DB_FUNCTION); + break; + } + + } /* if (docbook)... */ + current_indent += default_indentation_increment; /* Now process the function arguments, if any. If these carry onto @@ -548,32 +600,37 @@ defun_internal (type, x_p) case deftypevr: add_word ("</i>"); /* close italic area for arguments */ /* put the rest into the second column */ - add_word_args ("</td>\n<td align=\"right\">%s", category); + add_word ("</td>\n"); + add_html_elt ("<td align=\"right\">"); + execute_string ("%s", category); break; - - case defcv: - add_word ("</td>\n<td align=\"right\">"); - add_word_args ("%s %s %s", category, _("of"), type_name); - break; - - case defop: - case deftypemethod: - case deftypeop: - add_word ("</i>"); - add_word ("</td>\n<td align=\"right\">"); - add_word_args ("%s %s %s", category, _("on"), type_name); - break; - - case deftypeivar: - add_word ("</i>"); - add_word ("</td>\n<td align=\"right\">"); - add_word_args ("%s %s %s", category, _("of"), type_name); - break; - } /* switch (base_type)... */ - + + 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: + add_word ("</i>"); + add_word ("</td>\n"); + add_html_elt ("<td align=\"right\">"); + execute_string ("%s %s %s", category, _("on"), type_name); + break; + + case deftypeivar: + add_word ("</i>"); + add_word ("</td>\n"); + add_html_elt ("<td align=\"right\">"); + execute_string ("%s %s %s", category, _("of"), type_name); + break; + } /* switch (base_type)... */ + 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. @@ -588,10 +645,10 @@ defun_internal (type, x_p) if (!looking_at ("@def")) { add_word ("</table>\n"); - add_word ("<table width=\"95%\" align=\"center\">\n"); - add_word ("<tr><td>\n"); + add_html_elt ("<table width=\"95%\" align=\"center\">"); + add_word ("\n<tr><td>\n"); } - + } /* if (html)... */ /* Make an entry in the appropriate index. */ diff --git a/contrib/texinfo/makeinfo/docbook.c b/contrib/texinfo/makeinfo/docbook.c new file mode 100644 index 000000000000..c9b05c2d8f85 --- /dev/null +++ b/contrib/texinfo/makeinfo/docbook.c @@ -0,0 +1,492 @@ +/* docbook.c -- docbook output. + $Id: docbook.c,v 1.3 2001/12/31 16:52:17 karl Exp $ + + Copyright (C) 2001 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 "docbook.h" +#include "insertion.h" +#include "lang.h" +#include "makeinfo.h" +#include "macro.h" +#include "sectioning.h" + +int docbook_version_inserted = 0; +int docbook_first_chapter_found = 0; +int docbook_must_insert_node_anchor = 0; +int docbook_begin_book_p = 0; +int docbook_no_new_paragraph = 0; + +static int section_level = -1; +static int in_docbook_paragraph = 0; +static int in_list = 0; + +static int in_table = 0; +static int in_term = 0; +static int in_entry = 0; +static int in_varlistitem = 0; + +static int in_example = 0; + +void +docbook_begin_section (level, cmd) + int level; + char *cmd; +{ + int i, old_no_indent; + char *temp, *tem; + static char *last_chap = NULL; + + close_paragraph (); + docbook_first_chapter_found = 1; + filling_enabled = indented_fill = 0; + old_no_indent = no_indent; + no_indent = 1; + + if (!docbook_begin_book_p) + docbook_begin_book (); + + if (macro_expansion_output_stream && !executing_string) + append_to_expansion_output (input_text_offset + 1); + + get_rest_of_line (0, &temp); + + if (in_docbook_paragraph) + { + insert_string ("\n</para>\n\n"); + adjust_braces_following (0, 10); + } + in_docbook_paragraph = 0; + docbook_no_new_paragraph++; + + if (level > section_level + 1) + level = section_level + 1; + + for (i = section_level; i >= level ; i--) + { + if (i == 0) + { + if (last_chap && strcmp(last_chap, "appendix") == 0) + add_word ("</appendix>\n\n"); + else + add_word ("</chapter>\n\n"); + } + else + add_word_args ("</sect%d>\n\n", i); + } + + section_level = level; + + if (level == 0) + { + if (strcmp(cmd, "appendix") == 0) + add_word ("<appendix"); + else + add_word ("<chapter"); + last_chap = cmd; + } + else + add_word_args ("<sect%d", level); + + if (docbook_must_insert_node_anchor) + { + add_word (" id=\""); + tem = expansion (current_node, 0); + add_escaped_anchor_name (tem, 0); + free (tem); + add_word ("\""); + docbook_must_insert_node_anchor = 0; + } + add_word (">\n"); + add_word ("<title>"); + + if (macro_expansion_output_stream && !executing_string) + { + char *temp1 = xmalloc (2 + strlen (temp)); + sprintf (temp1, "%s", temp); + remember_itext (input_text, input_text_offset); + me_execute_string (temp1); + free (temp1); + } + else + execute_string ("%s", temp); + + free (temp); + + add_word ("</title>\n"); + + close_paragraph (); + filling_enabled = 1; + no_indent = old_no_indent; + docbook_no_new_paragraph--; + insert_string("\n<para>"); + in_docbook_paragraph = 1; +} + +void +docbook_begin_paragraph () +{ + if (!docbook_first_chapter_found) + return; + + if (in_example) + return; + + if (in_table && !in_term) + { + if (!in_varlistitem) + insert_string ("\n<listitem><para>\n"); + else + insert_string ("\n</para>\n\n<para>\n"); + in_varlistitem = 1; + + return; + } + if (in_list) + return; + if (in_docbook_paragraph) + { + insert_string ("\n</para>\n\n"); + adjust_braces_following (0, 10); + } + +#if 0 + if (docbook_must_insert_node_anchor) + { + char *tem; + insert_string ("<para id=\""); + adjust_braces_following (0, 10); + tem = expansion (current_node, 0); + add_escaped_anchor_name (tem, 0); + free (tem); + add_word ("\">\n"); + docbook_must_insert_node_anchor = 0; + } + else +#endif + { + insert_string ("<para>\n"); + adjust_braces_following (0, 7); + } + in_docbook_paragraph = 1; +} + +void +docbook_begin_book () +{ + if (!docbook_begin_book_p) + docbook_begin_book_p = 1; + else + return; + + ++docbook_no_new_paragraph; + add_word_args ("<!DOCTYPE book PUBLIC \"-//Davenport//DTD DocBook V3.0//EN\">\n\ +<book>\n<title>%s</title>\n", title); + --docbook_no_new_paragraph; +} + +void +docbook_end_book () +{ + int i; + if (in_docbook_paragraph) + { + insert_string ("\n</para>\n\n"); + } + + for (i = section_level; i >= 0 ; i--) + { + if (i == 0) + add_word ("</chapter>\n"); + else + add_word_args ("</sect%d>\n", i); + } + + add_word ("</book>\n"); +} + +void +docbook_insert_tag (start_or_end, tag) + int start_or_end; + char *tag; +{ + if (!paragraph_is_open && start_or_end == START) + docbook_begin_paragraph (); + + add_char ('<'); + if (start_or_end == START) + add_word (tag); + else + { + add_char ('/'); + for (; *tag && *tag != ' '; tag++) + add_char(*tag); + } + add_meta_char ('>'); +} + +void +docbook_xref1 (node_name) + char *node_name; +{ + char *tem; + add_word ("<xref linkend=\""); + tem = expansion (node_name, 0); + add_escaped_anchor_name (tem, 1); + free (tem); + add_word ("\"/>"); +} + +void +docbook_xref2 (node_name, ref_name) + char *node_name; + char *ref_name; +{ + char *tem; + add_word ("<xref linkend=\""); + tem = expansion (node_name, 0); + add_escaped_anchor_name (tem, 1); + free (tem); + add_word ("\"/>"); +} + +int +docbook_quote (character) + int character; +{ + switch (language_code) + { + case fr: + if (character == '`') + { + add_word ("« "); + return ';'; + } + else + { + add_word (" "); + return '»'; + } + break; + + default: + if (character == '`') + { + add_word ("&ldquo"); + return ';'; + } + else + { + add_word ("&rdquo"); + return ';'; + } + break; + } +} + +#define IS_BLANK(c) (c == ' ' || c == '\t' || c == '\n') + +int +docbook_is_punctuation (character, next) + int character; + int next; +{ + return ( (character == ';' + || character == ':' + || character == '?' + || character == '!') + && IS_BLANK (next)); +} + +void +docbook_punctuation (character) + int character; +{ + switch (language_code) + { + case fr: + while (output_paragraph[output_paragraph_offset-1] == ' ') + output_paragraph_offset--; + add_word (" "); + break; + } +} + +static int in_item = 0; + +void +docbook_begin_itemize () +{ + if (in_docbook_paragraph) + insert_string ("\n</para>\n"); + + in_docbook_paragraph = 0; + insert_string ("\n<itemizedlist>\n"); + in_item = 0; + in_list = 1; +} + +void +docbook_end_itemize () +{ + if (in_item) + { + insert_string ("\n</para></listitem>\n"); + in_item = 0; + } + insert_string ("\n</itemizedlist>\n\n<para>\n"); + in_docbook_paragraph = 1; + in_list = 0; +} + +void +docbook_begin_enumerate () +{ + if (in_docbook_paragraph) + insert_string ("\n</para>\n"); + in_docbook_paragraph = 0; + insert_string ("\n<orderedlist>\n"); + in_item = 0; + in_list = 1; +} + +void +docbook_end_enumerate () +{ + if (in_item) + { + insert_string ("\n</para></listitem>\n"); + in_item = 0; + } + insert_string ("\n</orderedlist>\n\n<para>\n"); + in_docbook_paragraph = 1; + in_list = 0; +} + +void +docbook_begin_table () +{ +#if 0 + if (in_docbook_paragraph) + insert_string ("\n</para>\n\n"); + in_docbook_paragraph = 0; +#endif + + add_word ("\n<variablelist>\n"); + in_table ++; + in_varlistitem = 0; + in_entry = 0; +} + +void +docbook_end_table () +{ + if (!in_varlistitem) + docbook_begin_paragraph (); + insert_string ("\n</para></listitem>\n</varlistentry>\n\n</variablelist>\n"); +#if 0 + if (in_table == 1) + { + insert_string ("\n</para>\n\n"); + in_docbook_paragraph = 0; + } + else + { + insert_string ("\n<para>\n\n"); + in_docbook_paragraph = 1; + } +#endif + in_table --; + in_list = 0; +} + +void +docbook_add_item () +{ + if (in_item) + insert_string ("\n</para></listitem>\n"); + insert_string ("\n<listitem><para>\n"); + in_docbook_paragraph = 1; + in_item = 1; +} + +void +docbook_add_table_item () +{ + if (in_varlistitem) + { + insert_string ("\n</para></listitem>\n</varlistentry>\n\n"); + in_entry = 0; + in_varlistitem = 0; + } + if (!in_entry) + { + insert_string ("<varlistentry>\n"); + in_entry = 1; + } + insert_string ("<term>"); + in_list = 1; + in_term = 1; +} + +void +docbook_close_table_item () +{ + insert_string ("</term>"); + in_list = 1; + in_term = 0; +} + +void +docbook_add_anchor (anchor) + char *anchor; +{ + add_word ("<anchor id=\""); + add_anchor_name (anchor, 0); + add_word ("\">"); +} + +void +docbook_footnote (note) + char *note; +{ + /* add_word_args ("<footnote><para>\n%s\n</para></footnote>\n", note); */ + add_word ("<footnote><para>\n"); + execute_string("%s", note); + add_word("\n</para></footnote>\n"); +} + +void +docbook_begin_index () +{ + add_word ("<variablelist>\n"); +} + +void +docbook_begin_example () +{ + add_word ("\n\n<screen>\n"); + in_example = 1; +} + +void +docbook_end_example () +{ + in_example = 0; + add_word ("</screen>\n\n"); +} diff --git a/contrib/texinfo/makeinfo/docbook.h b/contrib/texinfo/makeinfo/docbook.h new file mode 100644 index 000000000000..6f0ca49c6af1 --- /dev/null +++ b/contrib/texinfo/makeinfo/docbook.h @@ -0,0 +1,81 @@ +/* docbook.h -- docbook declarations. + $Id: docbook.h,v 1.2 2001/12/31 16:51:32 karl Exp $ + + Copyright (C) 2001 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 DOCBOOK_H +#define DOCBOOK_H + +#define DB_B "emphasis role=\"bold\"" +#define DB_CITE "citetitle" +#define DB_CODE "literal" +#define DB_COMMAND "command" +#define DB_DFN "firstterm" +#define DB_EMPH "emphasis" +#define DB_ENV "envar" +#define DB_FILE "filename" +#define DB_FUNCTION "function" +#define DB_I "emphasis" +#define DB_KBD "userinput" +#define DB_KEY "keycap" +#define DB_OPTION "option" +#define DB_STRONG "emphasis role=\"bold\"" +#define DB_TT "literal" +#define DB_URL "systemitem role=\"sitename\"" +#define DB_VAR "replaceable" + +extern int docbook_version_inserted; +extern int docbook_begin_book_p; +extern int docbook_first_chapter_found; +extern int docbook_must_insert_node_anchor; +extern int docbook_no_new_paragraph; + +void docbook_begin_section (); +void docbook_begin_paragraph (); +void docbook_begin_book (); +void docbook_end_book (); + +void docbook_insert_tag (); + +void docbook_xref1 (); +void docbook_xref2 (); + +int docbook_quote (); + +int docbook_is_punctuation (); +void docbook_punctuation (); + +void docbook_begin_itemize (); +void docbook_end_itemize (); +void docbook_begin_enumerate (); +void docbook_end_enumerate (); + +void docbook_begin_table (); +void docbook_end_table (); +void docbook_add_item (); +void docbook_add_table_item (); +void docbook_close_table_item (); +void docbook_add_anchor (); + +void docbook_footnote (); + +void docbook_begin_index (); + +void docbook_begin_example (); +void docbook_end_example (); + +#endif /* DOCBOOK_H */ diff --git a/contrib/texinfo/makeinfo/files.c b/contrib/texinfo/makeinfo/files.c index ce8ace014de3..83c00e1b2866 100644 --- a/contrib/texinfo/makeinfo/files.c +++ b/contrib/texinfo/makeinfo/files.c @@ -1,7 +1,7 @@ -/* files.c -- file-related functions for Texinfo. - $Id: files.c,v 1.5 1999/03/23 21:42:44 karl Exp $ +/* files.c -- file-related functions for makeinfo. + $Id: files.c,v 1.10 2002/01/16 15:52:45 karl Exp $ - Copyright (C) 1998, 99 Free Software Foundation, Inc. + Copyright (C) 1998, 99, 2000, 01, 02 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 @@ -139,9 +139,7 @@ find_and_load (filename) long file_size; int file = -1, count = 0; char *fullpath, *result; -#if O_BINARY || defined (VMS) - int n; -#endif + int n, bytes_to_read; result = fullpath = NULL; @@ -163,28 +161,18 @@ find_and_load (filename) /* VMS stat lies about the st_size value. The actual number of readable bytes is always less than this value. The arcane mysteries of VMS/RMS are too much to probe, so this hack - suffices to make things work. */ -#if O_BINARY || defined (VMS) -#ifdef VMS - while ((n = read (file, result + count, file_size)) > 0) -#else /* !VMS */ -#ifndef WIN32 - while ((n = read (file, result + count, file_size)) > 0) -#else /* WIN32 */ - /* Does WIN32 really need reading 1 character at a time?? */ - while ((n = read (file, result + count, 1)) > 0) -#endif /* WIN32 */ -#endif /* !VMS */ - count += n; + suffices to make things work. It's also needed on Cygwin. And so + we might as well use it everywhere. */ + bytes_to_read = file_size; + while ((n = read (file, result + count, bytes_to_read)) > 0) + { + count += n; + bytes_to_read -= n; + } if (0 < count && count < file_size) result = xrealloc (result, count + 2); /* why waste the slack? */ else if (n == -1) -#else /* !VMS && !O_BINARY */ - count = file_size; - if (read (file, result, file_size) != file_size) -#endif /* !VMS && !WIN32 */ - - error_exit: +error_exit: { if (result) free (result); @@ -527,3 +515,62 @@ output_name_from_input_name (name) { return expand_filename (NULL, name); } + + +/* Modify the file name FNAME so that it fits the limitations of the + underlying filesystem. In particular, truncate the file name as it + would be truncated by the filesystem. We assume the result can + 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; +{ + int maxlen; + char orig[PATH_MAX + 1]; + int i; + char *lastdot, *p; + +#ifdef _PC_NAME_MAX + maxlen = pathconf (fname, _PC_NAME_MAX); + if (maxlen < 1) +#endif + maxlen = PATH_MAX; + + i = skip_directory_part (fname); + if (fname[i] == '\0') + return fname; /* only a directory name -- don't modify */ + strcpy (orig, fname + i); + + switch (maxlen) + { + case 12: /* MS-DOS 8+3 filesystem */ + if (orig[0] == '.') /* leading dots are not allowed */ + orig[0] = '_'; + lastdot = strrchr (orig, '.'); + if (!lastdot) + lastdot = orig + strlen (orig); + strncpy (fname + i, orig, lastdot - orig); + for (p = fname + i; + p < fname + i + (lastdot - orig) && p < fname + i + 8; + p++) + if (*p == '.') + *p = '_'; + *p = '\0'; + if (*lastdot == '.') + strncat (fname + i, lastdot, 4); + break; + case 14: /* old Unix systems with 14-char limitation */ + strcpy (fname + i, orig); + if (strlen (fname + i) > 14) + fname[i + 14] = '\0'; + break; + default: + strcpy (fname + i, orig); + if (strlen (fname) > maxlen - 1) + fname[maxlen - 1] = '\0'; + break; + } + + return fname; +} diff --git a/contrib/texinfo/makeinfo/files.h b/contrib/texinfo/makeinfo/files.h index d96c444f2a85..88ae209801a8 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.1 1998/10/24 21:37:25 karl Exp $ + $Id: files.h,v 1.2 2002/01/16 15:52:45 karl Exp $ - Copyright (C) 1998 Free Software Foundation, Inc. + Copyright (C) 1998, 2002 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 @@ -41,5 +41,6 @@ extern char *output_name_from_input_name (); extern char *expand_filename (); extern char *filename_part (); extern char *pathname_part (); +extern char *normalize_filename (); #endif /* !FILES_H */ diff --git a/contrib/texinfo/makeinfo/footnote.c b/contrib/texinfo/makeinfo/footnote.c index c1a056d6e32c..d9f2525c1761 100644 --- a/contrib/texinfo/makeinfo/footnote.c +++ b/contrib/texinfo/makeinfo/footnote.c @@ -1,7 +1,7 @@ /* footnote.c -- footnotes for Texinfo. - $Id: footnote.c,v 1.10 1999/09/20 12:20:52 karl Exp $ + $Id: footnote.c,v 1.13 2002/03/02 15:05:21 karl Exp $ - Copyright (C) 1998, 99 Free Software Foundation, Inc. + Copyright (C) 1998, 99, 2002 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 +21,7 @@ #include "footnote.h" #include "macro.h" #include "makeinfo.h" +#include "xml.h" /* Nonzero means that the footnote style for this document was set on the command line, which overrides any other settings. */ @@ -200,6 +201,18 @@ cm_footnote () return; } + /* output_pending_notes is non-reentrant (it uses a global data + structure pending_notes, which it frees before it returns), and + TeX doesn't grok footnotes inside footnotes anyway. Disallow + that. */ + if (already_outputting_pending_notes) + { + line_error (_("Footnotes inside footnotes are not allowed")); + free (marker); + free (note); + return; + } + if (!*marker) { free (marker); @@ -213,14 +226,21 @@ cm_footnote () marker = xstrdup ("*"); } + if (xml) + xml_insert_footnote (note); + else + { remember_note (marker, note); /* fixme: html: footnote processing needs work; we currently ignore the style requested; we could clash with a node name of the form `fn-<n>', though that's unlikely. */ if (html) - add_word_args ("<a rel=footnote href=\"#fn-%d\"><sup>%s</sup></a>", - current_footnote_number, marker); + { + add_html_elt ("<a rel=footnote href="); + add_word_args ("\"#fn-%d\"><sup>%s</sup></a>", + current_footnote_number, marker); + } else /* Your method should at least insert MARKER. */ switch (footnote_style) @@ -255,7 +275,7 @@ cm_footnote () break; } current_footnote_number++; - + } free (marker); free (note); } @@ -328,7 +348,9 @@ output_pending_notes () /* Make the text of every footnote begin a separate paragraph. */ add_word_args ("<li><a name=\"fn-%d\"></a>\n<p>", footnote->number); + already_outputting_pending_notes++; execute_string ("%s", footnote->note); + already_outputting_pending_notes--; add_word ("</p>\n"); } else diff --git a/contrib/texinfo/makeinfo/html.c b/contrib/texinfo/makeinfo/html.c index f2e53e510db6..b7a8d59802a3 100644 --- a/contrib/texinfo/makeinfo/html.c +++ b/contrib/texinfo/makeinfo/html.c @@ -1,7 +1,7 @@ /* html.c -- html-related utilities. - $Id: html.c,v 1.5 1999/09/18 19:27:41 karl Exp $ + $Id: html.c,v 1.19 2002/02/23 19:12:15 karl Exp $ - Copyright (C) 1999 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 01, 02 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,27 +30,40 @@ int html_output_head_p = 0; void html_output_head () { - char *html_title; - + static char *html_title = NULL; + static int html_title_written = 0; + if (html_output_head_p) return; html_output_head_p = 1; - /* The <title> should not have markup. */ - html_title = title ? text_expansion (title) : _("Untitled"); + /* 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\"><head>\n<title>%s</title>\n", + 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) - add_word_args ("; charset=%s", document_encoding); + if (document_encoding_code != no_encoding) + add_word_args ("; charset=%s", + encoding_table[document_encoding_code].ecname); add_word ("\">\n"); - - add_word_args ("<meta name=description content=\"%s\">\n", html_title); + + 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); add_word ("<link href=\"http://texinfo.org/\" rel=generator-home>\n"); - add_word ("</head><body>\n\n"); + add_word ("</head>\n<body>\n"); + + if (title && !html_title_written) + { + add_word_args ("<h1>%s</h1>\n", html_title); + html_title_written = 1; + } } @@ -78,13 +91,12 @@ escape_string (string) default: newlen++; } - i++; } - while (string[i]); + while (string[i++]); if (newlen == i) return string; /* Already OK. */ - newstring = xmalloc (newlen + 2); + newstring = xmalloc (newlen); i = 0; do { @@ -109,7 +121,7 @@ escape_string (string) } while (string[i++]); free (string); - return newstring - newlen -1; + return newstring - newlen; } /* Open or close TAG according to START_OR_END. */ @@ -136,14 +148,16 @@ insert_html_tag (start_or_end, tag) /* Output an HTML <link> to the filename for NODE, including the other string as extra attributes. */ void -add_link (node, attributes) - char *node, *attributes; +add_link (nodename, attributes) + char *nodename, *attributes; { - if (node) + if (nodename) { - add_word_args ("<link %s href=\"", attributes); - add_anchor_name (node, 1); - add_word ("\">\n"); + add_html_elt ("<link "); + add_word_args ("%s", attributes); + add_word_args (" href=\""); + add_anchor_name (nodename, 1); + add_word ("\"></a>\n"); } } @@ -176,7 +190,170 @@ add_anchor_name (nodename, href) int href; { if (href) - add_char ('#'); + { + if (splitting) + add_url_name (nodename, href); + add_char ('#'); + } + /* Always add NODENAME, so that the reference would pinpoint the + exact node on its file. This is so several nodes could share the + same file, in case of file-name clashes, but also for more + accurate browser positioning. */ + if (strcasecmp (nodename, "(dir)") == 0) + /* Strip the parens, but keep the original letter-case. */ + add_word_args ("%.3s", nodename + 1); + else + add_escaped_anchor_name (nodename); +} + +/* 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_nodename_to_filename (nodename, href); +} + +/* Only allow [-0-9a-zA-Z_.] when nodifying filenames. This may + result in filename clashes; e.g., + + @node Foo ],,, + @node Foo [,,, + + 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++) + { + if (!(isalnum (*p) || strchr ("-._", *p))) + *p = '-'; + } +} + +/* As we can't look-up a (forward-referenced) nodes' html filename + from the tentry, we take the easy way out. We assume that + 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; +{ + char *p; + char *filename; + char dirname[PATH_MAX]; - add_escaped_anchor_name (nodename); + if (strcasecmp (nodename, "Top") == 0) + { + /* We want to convert references to the Top node into + "index.html#Top". */ + if (href) + filename = xstrdup ("index.html"); /* "#Top" is added by our callers */ + else + filename = xstrdup ("Top"); + } + else if (strcasecmp (nodename, "(dir)") == 0) + /* We want to convert references to the (dir) node into + "../index.html". */ + filename = xstrdup ("../index.html"); + else + { + filename = xmalloc (PATH_MAX); + dirname[0] = '\0'; + *filename = '\0'; + + /* Check for external reference: ``(info-document)node-name'' + Assume this node lives at: ``../info-document/node-name.html'' + + We need to handle the special case (sigh): ``(info-document)'', + ie, an external top-node, which should translate to: + ``../info-document/info-document.html'' */ + + p = nodename; + if (*nodename == '(') + { + int length; + + p = strchr (nodename, ')'); + if (p == NULL) + { + line_error (_("Invalid node name: `%s'"), nodename); + exit (1); + } + + length = p - nodename - 1; + if (length > 5 && + FILENAME_CMPN (p - 5, ".info", 5) == 0) + length -= 5; + /* This is for DOS, and also for Windows and GNU/Linux + systems that might have Info files copied from a DOS 8+3 + filesystem. */ + if (length > 4 && + FILENAME_CMPN (p - 4, ".inf", 4) == 0) + length -= 4; + strcpy (filename, "../"); + strncpy (dirname, nodename + 1, length); + *(dirname + length) = '\0'; + fix_filename (dirname); + strcat (filename, dirname); + strcat (filename, "/"); + p++; + } + + /* In the case of just (info-document), there will be nothing + remaining, and we will refer to ../info-document/, which will + work fine. */ + strcat (filename, p); + if (*p) + { + /* Hmm */ + fix_filename (filename + strlen (filename) - strlen (p)); + strcat (filename, ".html"); + } + } + + /* Produce a file name suitable for the underlying filesystem. */ + normalize_filename (filename); + +#if 0 + /* We add ``#Nodified-filename'' anchor to external references to be + prepared for non-split HTML support. Maybe drop this. */ + if (href && *dirname) + { + strcat (filename, "#"); + strcat (filename, p); + /* Hmm, again */ + fix_filename (filename + strlen (filename) - strlen (p)); + } +#endif + + return filename; +} + +/* If necessary, ie, if current filename != filename of node, output + the node name. */ +void +add_nodename_to_filename (nodename, href) + char *nodename; + int href; +{ + /* for now, don't check: always output filename */ + char *filename = nodename_to_filename_1 (nodename, href); + add_word (filename); + free (filename); +} + +char * +nodename_to_filename (nodename) + 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. */ + return nodename_to_filename_1 (nodename, 1); } diff --git a/contrib/texinfo/makeinfo/html.h b/contrib/texinfo/makeinfo/html.h index 2d68c77308dd..cd24ce271d07 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.1 1999/04/25 20:53:33 karl Exp $ + $Id: html.h,v 1.2 2000/12/19 15:17:52 karl Exp $ - Copyright (C) 1999 Free Software Foundation, Inc. + Copyright (C) 1999, 2000 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 @@ -40,5 +40,8 @@ extern void add_escaped_anchor_name (/* char *name */); /* 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 */ ); #endif /* !HTML_H */ diff --git a/contrib/texinfo/makeinfo/index.c b/contrib/texinfo/makeinfo/index.c index 05466ce9a4f0..edaf4e1b213e 100644 --- a/contrib/texinfo/makeinfo/index.c +++ b/contrib/texinfo/makeinfo/index.c @@ -1,7 +1,7 @@ /* index.c -- indexing for Texinfo. - $Id: index.c,v 1.21 1999/07/18 18:50:02 karl Exp $ + $Id: index.c,v 1.24 2002/01/22 14:28:07 karl Exp $ - Copyright (C) 1998, 99 Free Software Foundation, Inc. + Copyright (C) 1998, 99, 2002 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,7 @@ #include "lang.h" #include "macro.h" #include "toc.h" +#include "xml.h" /* An index element... */ typedef struct index_elt @@ -226,7 +227,13 @@ index_add_arg (name) (see the findexerr test). */ new->defining_file = xstrdup (input_filename); the_indices[which] = new; + /* The index breaks if there are colons in the entry. */ + if (strchr (new->entry_text, ':')) + warning (_("Info cannot handle `:' in index entry `%s'"), + new->entry_text); } + if (xml) + xml_insert_indexterm (index_entry, name); } /* The function which user defined index commands call. */ @@ -583,7 +590,7 @@ sort_index (index) /* If this particular entry should be printed as a "code" index, then expand it as @code{entry}, i.e. as in fixed-width font. */ array[count-1]->entry = expansion (temp->entry_text, - array[count-1]->code); + array[count-1]->code); temp = temp->next; } @@ -621,203 +628,225 @@ int printing_index = 0; void cm_printindex () { - 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); - - index = index_list (index_name); - if (index == (INDEX_ELT *)-1) + if (xml && !docbook) { - line_error (_("Unknown index `%s' in @printindex"), index_name); - free (index_name); - return; + char *index_name; + get_rest_of_line (0, &index_name); + xml_insert_element (PRINTINDEX, START); + insert_string (index_name); + xml_insert_element (PRINTINDEX, END); } - - /* Do this before sorting, so execute_string in index_element_compare - will give the same results as when we actually print. */ - printing_index = 1; - filling_enabled = 0; - inhibit_paragraph_indentation = 1; - array = sort_index (index); - - close_paragraph (); - if (html) - add_word ("<ul compact>"); - else if (!no_headers) - add_word ("* Menu:\n\n"); - - me_inhibit_expansion++; - - /* This will probably be enough. */ - line_length = 100; - line = xmalloc (line_length); - - for (item = 0; (index = array[item]); item++) + else { - /* A pathological document might have an index entry outside of any - node. Don't crash; try using the section name instead. */ - char *index_node = index->node; - - line_number = index->defining_line; - input_filename = index->defining_file; - - if ((!index_node || !*index_node) && html) - index_node = toc_find_section_of_node (index_node); - - if (!index_node || !*index_node) + 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); + + index = index_list (index_name); + if (index == (INDEX_ELT *)-1) { - line_error (_("Entry for index `%s' outside of any node"), - index_name); - if (html || !no_headers) - index_node = _("(outside of any node)"); + line_error (_("Unknown index `%s' in @printindex"), index_name); + free (index_name); + return; } - + + /* Do this before sorting, so execute_string is in the good environment */ + if (xml && docbook) + xml_begin_index (); + + /* Do this before sorting, so execute_string in index_element_compare + will give the same results as when we actually print. */ + printing_index = 1; + filling_enabled = 0; + inhibit_paragraph_indentation = 1; + xml_sort_index = 1; + array = sort_index (index); + xml_sort_index = 0; + close_paragraph (); if (html) - /* fixme: html: we should use specific index anchors pointing + add_word ("<ul compact>"); + else if (!no_headers && !docbook) + add_word ("* Menu:\n\n"); + + me_inhibit_expansion++; + + /* This will probably be enough. */ + line_length = 100; + line = xmalloc (line_length); + + 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. */ + char *index_node = index->node; + + line_number = index->defining_line; + input_filename = index->defining_file; + + if ((!index_node || !*index_node) && html) + index_node = toc_find_section_of_node (index_node); + + if (!index_node || !*index_node) + { + line_error (_("Entry for index `%s' outside of any node"), + index_name); + if (html || !no_headers) + index_node = _("(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); - } - add_word ("<a href=\""); - if (index->node && *index->node) { - /* Make sure any non-macros in the node name are expanded. */ - in_fixed_width_font++; - index_node = expansion (index_node, 0); - in_fixed_width_font--; - add_anchor_name (index_node, 1); - add_word_args ("\">%s</a>", index_node); - free (index_node); + 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); + } + add_word ("<a href=\""); + if (index->node && *index->node) + { + /* Make sure any non-macros in the node name are expanded. */ + in_fixed_width_font++; + index_node = expansion (index_node, 0); + in_fixed_width_font--; + add_anchor_name (index_node, 1); + add_word_args ("\">%s</a>", index_node); + free (index_node); + } + else if (STREQ (index_node, _("(outside of any node)"))) + { + add_anchor_name (index_node, 1); + add_word_args ("\">%s</a>", index_node); + } + else + /* 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); } - else if (STREQ (index_node, _("(outside of any node)"))) + else if (xml && docbook) { - add_anchor_name (index_node, 1); - add_word_args ("\">%s</a>", index_node); + xml_insert_indexentry (index->entry, index_node); } else - /* 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); - } - else - { - unsigned new_length = strlen (index->entry); - - if (new_length < 50) /* minimum length used below */ - new_length = 50; - new_length += strlen (index_node) + 7; /* * : .\n\0 */ - - if (new_length > line_length) - { - line_length = new_length; - line = xrealloc (line, line_length); - } - /* Print the entry, nicely formatted. We've already - expanded any commands in index->entry, including any - implicit @code. Thus, can't call execute_string, since - @@ has turned into @. */ - if (!no_headers) - { - sprintf (line, "* %-37s ", index->entry); - line[2 + strlen (index->entry)] = ':'; - insert_string (line); - /* Make sure any non-macros in the node name are expanded. */ - in_fixed_width_font++; - execute_string ("%s.\n", index_node); - in_fixed_width_font--; - } - else - { - /* With --no-headers, the @node lines are gone, so - 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); - 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); + { + unsigned new_length = strlen (index->entry); + + if (new_length < 50) /* minimum length used below */ + new_length = 50; + new_length += strlen (index_node) + 7; /* * : .\n\0 */ + + if (new_length > line_length) + { + line_length = new_length; + line = xrealloc (line, line_length); + } + /* Print the entry, nicely formatted. We've already + expanded any commands in index->entry, including any + implicit @code. Thus, can't call execute_string, since + @@ has turned into @. */ + if (!no_headers) + { + sprintf (line, "* %-37s ", index->entry); + line[2 + strlen (index->entry)] = ':'; insert_string (line); - } - else + /* Make sure any non-macros in the node name are expanded. */ + in_fixed_width_font++; + execute_string ("%s.\n", index_node); + in_fixed_width_font--; + } + else { - insert_string (" "); /* force a blank */ - execute_string ("See node %s.\n", index_node); + /* With --no-headers, the @node lines are gone, so + 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); + 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); + } + else + { + insert_string (" "); /* force a blank */ + execute_string ("See node %s.\n", index_node); + } } - } - } + } + + /* Prevent `output_paragraph' from growing to the size of the + whole index. */ + flush_output (); + last_index = index; + } - /* Prevent `output_paragraph' from growing to the size of the - whole index. */ - flush_output (); - last_index = index; + free (line); + free (index_name); + + me_inhibit_expansion--; + + printing_index = 0; + free (array); + close_single_paragraph (); + filling_enabled = saved_filling_enabled; + inhibit_paragraph_indentation = saved_inhibit_paragraph_indentation; + input_filename = saved_input_filename; + line_number = saved_line_number; + + if (html) + add_word ("</ul>"); + else if (xml && docbook) + xml_end_index (); } - - free (line); - free (index_name); - - me_inhibit_expansion--; - - printing_index = 0; - free (array); - close_single_paragraph (); - filling_enabled = saved_filling_enabled; - inhibit_paragraph_indentation = saved_inhibit_paragraph_indentation; - input_filename = saved_input_filename; - line_number = saved_line_number; - - if (html) - add_word ("</ul>"); } diff --git a/contrib/texinfo/makeinfo/insertion.c b/contrib/texinfo/makeinfo/insertion.c index 11b908901db5..c7087f2c287c 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.27 1999/07/06 23:12:53 karl Exp $ + $Id: insertion.c,v 1.39 2002/03/02 15:05:21 karl Exp $ - Copyright (C) 1998, 99 Free Software Foundation, Inc. + Copyright (C) 1998, 99, 2000, 01, 02 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,20 +23,21 @@ #include "insertion.h" #include "macro.h" #include "makeinfo.h" +#include "xml.h" /* Must match list in insertion.h. */ static char *insertion_type_names[] = -{ +{ "cartouche", "defcv", "deffn", "defivar", "defmac", "defmethod", "defop", "defopt", "defspec", "deftp", "deftypefn", "deftypefun", "deftypeivar", "deftypemethod", "deftypeop", "deftypevar", "deftypevr", "defun", "defvar", "defvr", "detailmenu", "direntry", - "display", "enumerate", "example", "flushleft", "flushright", - "format", "ftable", "group", "ifclear", "ifhtml", "ifinfo", - "ifnothtml", "ifnotinfo", "ifnottex", "ifset", "iftex", "itemize", - "lisp", "menu", "multitable", "quotation", "rawhtml", "rawtex", - "smalldisplay", "smallexample", "smallformat", "smalllisp", "table", - "tex", "vtable", "bad_type" + "display", "documentdescription", "enumerate", "example", "flushleft", + "flushright", "format", "ftable", "group", "ifclear", "ifhtml", + "ifinfo", "ifnothtml", "ifnotinfo", "ifnottex", "ifset", "iftex", + "itemize", "lisp", "menu", "multitable", "quotation", "rawhtml", + "rawtex", "smalldisplay", "smallexample", "smallformat", "smalllisp", + "verbatim", "table", "tex", "vtable", "bad_type" }; /* All nested environments. */ @@ -359,7 +360,9 @@ begin_insertion (type) no_discard++; } else - push_insertion (type, get_item_function ()); + { + push_insertion (type, get_item_function ()); + } switch (type) { @@ -374,9 +377,12 @@ begin_insertion (type) { had_menu_commentary = 1; } - else if (!no_headers) + else if (!no_headers && !xml) add_word ("* Menu:\n"); + if (xml) + xml_insert_element (MENU, START); + in_menu++; in_fixed_width_font++; no_discard++; @@ -399,15 +405,29 @@ begin_insertion (type) break; case direntry: - if (html) - command_name_condition (); - else - { - close_single_paragraph (); - filling_enabled = no_indent = 0; - inhibit_paragraph_indentation = 1; - insert_string ("START-INFO-DIR-ENTRY\n"); - } + close_single_paragraph (); + filling_enabled = no_indent = 0; + inhibit_paragraph_indentation = 1; + insert_string ("START-INFO-DIR-ENTRY\n"); + break; + + case documentdescription: + { + char *desc; + int start_of_end; + int save_fixed_width; + + discard_until ("\n"); /* ignore the @documentdescription line */ + start_of_end = get_until ("\n@end documentdescription", &desc); + save_fixed_width = in_fixed_width_font; + + in_fixed_width_font = 0; + document_description = expansion (desc, 0); + free (desc); + + in_fixed_width_font = save_fixed_width; + input_text_offset = start_of_end; /* go back to the @end to match */ + } break; case quotation: @@ -443,7 +463,7 @@ begin_insertion (type) /* 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 ("<pre>"); + add_word ("<br><pre>"); if (type != format && type != smallformat) current_indent += default_indentation_increment; @@ -492,6 +512,8 @@ begin_insertion (type) else add_word (dl_tag); } + if (xml) + xml_begin_table (type, insertion_stack->item_function); break; case enumerate: @@ -509,6 +531,9 @@ begin_insertion (type) if (html) enum_html (); + if (xml) + xml_begin_enumerate (enumeration_arg); + if (isdigit (*enumeration_arg)) start_enumerating (atoi (enumeration_arg), ENUM_DIGITS); else @@ -519,7 +544,9 @@ begin_insertion (type) case group: /* Only close the paragraph if we are not inside of an @example-like environment. */ - if (!insertion_stack->next + if (xml) + xml_insert_element (GROUP, START); + else if (!insertion_stack->next || (insertion_stack->next->insertion != display && insertion_stack->next->insertion != smalldisplay && insertion_stack->next->insertion != example @@ -581,6 +608,8 @@ begin_insertion (type) close_single_paragraph (); inhibit_paragraph_indentation = 1; filling_enabled = indented_fill = no_indent = 0; + if (html) + add_word ("<div align=\"left\">"); break; case flushright: @@ -588,6 +617,8 @@ begin_insertion (type) filling_enabled = indented_fill = no_indent = 0; inhibit_paragraph_indentation = 1; force_flush_right++; + if (html) + add_word ("<div align=\"right\">"); break; default: @@ -627,12 +658,64 @@ end_insertion (type) pop_insertion (); + if (xml) + { + switch (type) + { + case ifinfo: + case documentdescription: + break; + case quotation: + xml_insert_element (QUOTATION, END); + break; + case example: + xml_insert_element (EXAMPLE, END); + break; + case smallexample: + xml_insert_element (SMALLEXAMPLE, END); + break; + case lisp: + xml_insert_element (LISP, END); + break; + case smalllisp: + xml_insert_element (SMALLLISP, END); + break; + case cartouche: + xml_insert_element (CARTOUCHE, END); + break; + case format: + xml_insert_element (FORMAT, END); + break; + case smallformat: + xml_insert_element (SMALLFORMAT, END); + break; + case display: + xml_insert_element (DISPLAY, END); + break; + case smalldisplay: + xml_insert_element (SMALLDISPLAY, END); + break; + case table: + case ftable: + case vtable: + case itemize: + xml_end_table (type); + break; + case enumerate: + xml_end_enumerate (type); + break; + case group: + xml_insert_element (GROUP, END); + break; + } + } switch (type) { /* Insertions which have no effect on paragraph formatting. */ + case documentdescription: case ifclear: - case ifhtml: case ifinfo: + case ifhtml: case ifnothtml: case ifnotinfo: case ifnottex: @@ -680,6 +763,11 @@ end_insertion (type) break; case flushleft: + if (html) + add_word ("</div>\n"); + close_insertion_paragraph (); + break; + case group: case cartouche: close_insertion_paragraph (); @@ -724,6 +812,8 @@ end_insertion (type) case flushright: force_flush_right--; + if (html) + add_word ("</div>\n"); close_insertion_paragraph (); break; @@ -750,7 +840,7 @@ end_insertion (type) case deftypeivar: if (html) /* close the tables which has been opened in defun.c */ - add_word ("</TD></TR>\n</TABLE>\n"); + add_word ("</td></tr>\n</table>\n"); break; } /* switch (base_type)... */ @@ -790,12 +880,11 @@ discard_insertions (specials_ok) else { char *offender = insertion_type_pname (insertion_stack->insertion); - char *current_filename = input_filename; - input_filename = insertion_stack->filename; - line_number = insertion_stack->line_number; - line_error (_("No matching `%cend %s'"), COMMAND_PREFIX, offender); - input_filename = current_filename; + file_line_error (insertion_stack->filename, + insertion_stack->line_number, + _("No matching `%cend %s'"), COMMAND_PREFIX, + offender); pop_insertion (); } } @@ -807,75 +896,103 @@ discard_insertions (specials_ok) void cm_quotation () { + if (xml) + xml_insert_element (QUOTATION, START); begin_insertion (quotation); } void cm_example () { + if (xml) + xml_insert_element (EXAMPLE, START); begin_insertion (example); } void cm_smallexample () { + if (xml) + xml_insert_element (SMALLEXAMPLE, START); begin_insertion (smallexample); } void cm_lisp () { + if (xml) + xml_insert_element (LISP, START); begin_insertion (lisp); } void cm_smalllisp () { + if (xml) + xml_insert_element (SMALLLISP, START); begin_insertion (smalllisp); } -/* @cartouche/@end cartouche draws box with rounded corners in - TeX output. Right now, just a no-op insertion. */ void cm_cartouche () { + if (xml) + xml_insert_element (CARTOUCHE, START); begin_insertion (cartouche); } void cm_format () { + if (xml) + xml_insert_element (FORMAT, START); begin_insertion (format); } void cm_smallformat () { + if (xml) + xml_insert_element (SMALLFORMAT, START); begin_insertion (smallformat); } void cm_display () { + if (xml) + xml_insert_element (DISPLAY, START); begin_insertion (display); } void cm_smalldisplay () { + if (xml) + xml_insert_element (SMALLDISPLAY, START); begin_insertion (smalldisplay); } void cm_direntry () { - if (no_headers || html) + if (html || xml) command_name_condition (); else begin_insertion (direntry); } void +cm_documentdescription () +{ + if (html || xml) + begin_insertion (documentdescription); + else + command_name_condition (); +} + + +void cm_itemize () { begin_insertion (itemize); @@ -918,6 +1035,77 @@ cm_enumerate () do_enumeration (enumerate, "1"); } +/* Handle verbatim environment: + find_end_verbatim == 0: process until end of file + find_end_verbatim != 0: process until 'COMMAND_PREFIXend verbatim' + or end of file + + We cannot simply copy input stream onto output stream; as the + verbatim environment may be encapsulated in an @example environment, + for example. */ +void +handle_verbatim_environment (find_end_verbatim) + int find_end_verbatim; +{ + int character; + int seen_end = 0; + int save_filling_enabled = filling_enabled; + int save_inhibit_paragraph_indentation = inhibit_paragraph_indentation; + + close_single_paragraph (); + inhibit_paragraph_indentation = 1; + filling_enabled = 0; + in_fixed_width_font++; + last_char_was_newline = 0; + + /* No indentation: this is verbatim after all + If you want indent, enclose @verbatim in @example + current_indent += default_indentation_increment; + */ + + if (html) + add_word ("<pre>"); + + while (input_text_offset < input_text_length) + { + character = curchar (); + + if (character == '\n') + line_number++; + /* + 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, + sizeof (END_VERBATIM)-1)) + { + input_text_offset += sizeof (END_VERBATIM); + seen_end = 1; + break; + } + + add_char (character); + input_text_offset++; + } + + if (find_end_verbatim && !seen_end) + warning (_("end of file inside verbatim block")); + + if (html) + add_word ("</pre>"); + + in_fixed_width_font--; + filling_enabled = save_filling_enabled; + inhibit_paragraph_indentation = save_inhibit_paragraph_indentation; +} + +void +cm_verbatim () +{ + handle_verbatim_environment (1); +} + void cm_table () { @@ -1087,6 +1275,10 @@ cm_end () line_error (_("Bad argument to `%s', `%s', using `%s'"), command, temp, insertion_type_pname (current_insertion_type ())); } + if (xml && type == menu) /* fixme */ + { + xml_end_menu (); + } end_insertion (type); free (temp); } @@ -1096,7 +1288,7 @@ cm_end () static int itemx_flag = 0; /* Return whether CMD takes a brace-delimited {arg}. */ -static int +/*static */int command_needs_braces (cmd) char *cmd; { @@ -1195,6 +1387,8 @@ cm_item () } add_word ("<li>"); } + else if (xml) + xml_begin_item (); else { start_paragraph (); @@ -1289,6 +1483,15 @@ cm_item () last_html_output_position = output_position; add_word ("<dd>"); } + else if (xml) /* && docbook)*/ /* 05-08 */ + { + xml_begin_table_item (); + if (item_func && *item_func) + execute_string ("%s{%s}", item_func, rest_of_line); + else + execute_string ("%s", rest_of_line); + xml_continue_table_item (); + } else { /* We need this to determine if we have two @item's in a row diff --git a/contrib/texinfo/makeinfo/insertion.h b/contrib/texinfo/makeinfo/insertion.h index 6f4a24b79267..51540b223565 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.6 1999/07/06 23:12:58 karl Exp $ + $Id: insertion.h,v 1.8 2001/06/30 00:29:41 karl Exp $ - Copyright (C) 1998, 99 Free Software Foundation, Inc. + Copyright (C) 1998, 99, 2001 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,15 +22,15 @@ /* Must match list in insertion.c. */ enum insertion_type -{ +{ cartouche, defcv, deffn, defivar, defmac, defmethod, defop, defopt, defspec, deftp, deftypefn, deftypefun, deftypeivar, deftypemethod, deftypeop, deftypevar, deftypevr, defun, defvar, defvr, detailmenu, - direntry, display, enumerate, example, flushleft, flushright, format, - ftable, group, ifclear, ifhtml, ifinfo, ifnothtml, ifnotinfo, - ifnottex, ifset, iftex, itemize, lisp, menu, multitable, quotation, - rawhtml, rawtex, smalldisplay, smallexample, smallformat, smalllisp, - table, tex, vtable, bad_type + direntry, display, documentdescription, enumerate, example, flushleft, + flushright, format, ftable, group, ifclear, ifhtml, ifinfo, ifnothtml, + ifnotinfo, ifnottex, ifset, iftex, itemize, lisp, menu, multitable, + quotation, rawhtml, rawtex, smalldisplay, smallexample, smallformat, + smalllisp, verbatim, table, tex, vtable, bad_type }; typedef struct istack_elt diff --git a/contrib/texinfo/makeinfo/lang.c b/contrib/texinfo/makeinfo/lang.c index eeb9ef582a4f..468bed80b1f0 100644 --- a/contrib/texinfo/makeinfo/lang.c +++ b/contrib/texinfo/makeinfo/lang.c @@ -1,7 +1,7 @@ -/* lang.c -- language depend behaviour (startpoint) - $Id: lang.c,v 1.11 1999/07/13 21:16:29 karl Exp $ +/* lang.c -- language-dependent support. + $Id: lang.c,v 1.14 2001/09/11 18:04:35 karl Exp $ - Copyright (C) 1999 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 01 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,20 +17,150 @@ 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 Karl Heinz Marbaise <kama@hippo.fido.de>. */ + Originally written by Karl Heinz Marbaise <kama@hippo.fido.de>. */ #include "system.h" #include "cmds.h" #include "lang.h" #include "makeinfo.h" +#include "xml.h" /* Current document encoding. */ -char *document_encoding = NULL; +encoding_code_type document_encoding_code = no_encoding; /* Current language code; default is English. */ language_code_type language_code = en; -language_struct language_table[] = { +/* Translation table between HTML and ISO Codes. The last item is + hopefully the Unicode. It might be possible that those Unicodes are + not correct, cause I didn't check them. kama */ +iso_map_type iso8859_1_map [] = { + { "nbsp", 0xA0, 0x00A0 }, + { "iexcl", 0xA1, 0x00A1 }, + { "cent", 0xA2, 0x00A2 }, + { "pound", 0xA3, 0x00A3 }, + { "curren", 0xA4, 0x00A4 }, + { "yen", 0xA5, 0x00A5 }, + { "brkbar", 0xA6, 0x00A6 }, + { "sect", 0xA7, 0x00A7 }, + { "uml", 0xA8, 0x00A8 }, + { "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 }, + { "acute", 0xB4, 0x00B4 }, + { "micro", 0xB5, 0x00B5 }, + { "para", 0xB6, 0x00B6 }, + { "middot", 0xB7, 0x00B7 }, + { "cedil", 0xB8, 0x00B8 }, + { "sup1", 0xB9, 0x00B9 }, + { "ordm", 0xBA, 0x00BA }, + { "raquo", 0xBB, 0x00BB }, + { "frac14", 0xBC, 0x00BC }, + { "frac12", 0xBD, 0x00BD }, + { "frac34", 0xBE, 0x00BE }, + { "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 }, /* I don't know ;-( */ + { "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 } +}; + +/* This might be put into structure below and NOT coded via define, + because some translation tables could contain different numbers of + characters, but for now it suffices. */ +#define ISO_MAP_SIZE (sizeof (iso8859_1_map) / sizeof (iso8859_1_map[0])) + +encoding_type encoding_table[] = { + { no_encoding, "(no encoding)", NULL }, + { ISO_8859_1, "ISO-8859-1", (iso_map_type *) iso8859_1_map }, + { ISO_8859_2, "ISO-8859-2", NULL }, + { 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 }, + { last_encoding_code, NULL, NULL } +}; + + +language_type language_table[] = { { aa, "aa", "Afar" }, { ab, "ab", "Abkhazian" }, { af, "af", "Afrikaans" }, @@ -173,16 +303,18 @@ language_struct language_table[] = { { last_language_code, NULL, NULL } }; + + /* @documentlanguage. Maybe we'll do something useful with this in the future. For now, we just recognize it. */ void cm_documentlanguage () { language_code_type c; - char *lang_arg; + char *lang_arg; /* Read the line with the language code on it. */ - get_rest_of_line (1, &lang_arg); + get_rest_of_line (0, &lang_arg); /* Linear search is fine these days. */ for (c = aa; c != last_language_code; c++) @@ -203,11 +335,178 @@ cm_documentlanguage () -/* @documentencoding. Set global. */ +/* Search through the encoding table for the given character, returning + its equivalent. */ + +static int +cm_search_iso_map (html) + char *html; +{ + int i; + iso_map_type *iso = encoding_table[document_encoding_code].isotab; + + /* If no conversion table for this encoding, quit. */ + if (!iso) + return -1; + + for (i = 0; i < ISO_MAP_SIZE; i++) + { + if (strcmp (html, iso[i].html) == 0) + return i; + } + + return -1; +} + + +/* @documentencoding. Set the translation table. */ + void cm_documentencoding () { - get_rest_of_line (1, &document_encoding); + encoding_code_type enc; + char *enc_arg; + + get_rest_of_line (1, &enc_arg); + + /* See if we have this encoding. */ + for (enc = ISO_8859_1; enc != last_encoding_code; enc++) + { + if (strcasecmp (enc_arg, encoding_table[enc].ecname) == 0) + { + document_encoding_code = enc; + break; + } + } + + /* If we didn't find this code, complain. */ + if (enc == last_encoding_code) + warning (_("unrecogized encoding name `%s'"), enc_arg); + + else if (encoding_table[document_encoding_code].isotab == NULL) + warning (_("sorry, encoding `%s' not supported"), enc_arg); + + free (enc_arg); +} + + +/* 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; +{ + if (html || xml) + add_word_args ("&%s;", html_str); + else if (enable_encoding) + { + /* Look for HTML_STR in the current translation table. */ + int rc = cm_search_iso_map (html_str); + if (rc >= 0) + /* We found it, add the real character. */ + add_char (encoding_table[document_encoding_code].isotab[rc].bytecode); + else + { /* We didn't find it, that seems bad. */ + warning (_("invalid encoded character `%s'"), html_str); + add_word (info_str); + } + } + else + add_word (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; +{ + static int valid_html_accent; /* yikes */ + + if (arg == START) + { /* If HTML has good support for this character, use it. */ + if (strchr (html_supported, curchar ())) + { /* Yes; start with an ampersand. The character itself + will be added later in read_command (makeinfo.c). */ + valid_html_accent = 1; + add_char ('&'); + } + else + { + valid_html_accent = 0; + if (html_solo_standalone) + { /* No special HTML support, so produce standalone char. */ + add_word_args ("&%s;", html_solo); + } + else + /* If the html_solo does not exist as standalone character + (namely ˆ ` ˜), then we use + the single character version instead. */ + add_char (single); + } + } + else if (arg == END) + { /* Only if we saw a valid_html_accent can we use the full + HTML accent (umlaut, grave ...). */ + if (valid_html_accent) + { + add_word (html_solo); + add_char (';'); + } + } +} + + +static void +cm_accent_generic_no_headers (arg, start, end, single, html_solo) + int arg, start, end; + int single; + char *html_solo; +{ + if (arg == END) + { + if (no_encoding) + add_char (single); + else + { + int rc; + char *buffer = xmalloc (1 + strlen (html_solo) + 1); + buffer[0] = output_paragraph[end - 1]; + buffer[1] = 0; + strcat (buffer, html_solo); + + rc = cm_search_iso_map (buffer); + if (rc >= 0) + /* A little bit tricky ;-) + Here we replace the character which has + been inserted in read_command with + the value we have found in converting table + Does there exist a better way to do this? kama. */ + output_paragraph[end - 1] + = encoding_table[document_encoding_code].isotab[rc].bytecode; + else + { /* If we didn't find a translation for this character, + put the single instead. E.g., &Xuml; does not exist so X¨ + should be produced. */ + warning (_("%s is an invalid ISO code, using %c"), + buffer, single); + add_char (single); + } + + free (buffer); + } + } } @@ -219,6 +518,8 @@ void cm_accent (arg) int arg; { + int old_escape_html = escape_html; + escape_html = 0; if (arg == START) { /* Must come first to avoid ambiguity with overdot. */ @@ -228,7 +529,7 @@ cm_accent (arg) else if (arg == END) { if (strcmp (command, "=") == 0) /* macron */ - add_word (html ? "¯" : "="); + add_word ((html || xml) ? "¯" : "="); else if (strcmp (command, "H") == 0) /* Hungarian umlaut */ add_word ("''"); else if (strcmp (command, "dotaccent") == 0) /* overdot */ @@ -242,18 +543,19 @@ cm_accent (arg) else if (strcmp (command, "ubaraccent") == 0) /* underbar */ add_char ('_'); else if (strcmp (command, "v") == 0) /* hacek/check */ - add_word (html ? "<" : "<"); + add_word ((html || xml) ? "<" : "<"); } + escape_html = old_escape_html; } /* Common routine for the accent characters that have support in HTML. If the character being accented is in the HTML_SUPPORTED set, then produce &CHTML_SOLO;, for example, Ä for an A-umlaut. If not in HTML_SUPPORTED, just produce &HTML_SOLO;X for the best we can do with - at an X-umlaut. Finally, if not producing HTML, just use SINGLE, a + at an X-umlaut. If not producing HTML, just use SINGLE, a character such as " which is the best plain text representation we - can manage. If HTML_SOLO_STANDALONE is zero the given HTML_SOLO - does not exist as valid standalone character in HTML. */ + can manage. If HTML_SOLO_STANDALONE is nonzero the given HTML_SOLO + exists as valid standalone character in HTML, e.g., ¨. */ static void cm_accent_generic (arg, start, end, html_supported, single, @@ -264,47 +566,19 @@ cm_accent_generic (arg, start, end, html_supported, single, int html_solo_standalone; char *html_solo; { - if (html) - { - static int valid_html_accent; - - if (arg == START) - { /* If HTML has good support for this character, use it. */ - if (strchr (html_supported, curchar ())) - { /* Yes; start with an ampersand. The character itself - will be added later in read_command (makeinfo.c). */ - add_char ('&'); - valid_html_accent = 1; - } - else - { /* No special HTML support, so produce standalone char. */ - valid_html_accent = 0; - if (html_solo_standalone) - { - add_char ('&'); - add_word (html_solo); - add_char (';'); - } - else - /* If the html_solo does not exist as standalone character - (namely ˆ ` ˜), then we use - the single character version instead. */ - add_char (single); - } - } - else if (arg == END) - { /* Only if we saw a valid_html_accent can we use the full - HTML accent (umlaut, grave ...). */ - if (valid_html_accent) - { - add_word (html_solo); - add_char (';'); - } - } - } + if (html || xml) + cm_accent_generic_html (arg, start, end, html_supported, + single, html_solo_standalone, html_solo); + else if (no_headers) + cm_accent_generic_no_headers (arg, start, end, single, html_solo); else if (arg == END) - { /* Not producing HTML, so just use the normal character. */ - add_char (single); + { + if (enable_encoding) + /* use 8-bit if available */ + cm_accent_generic_no_headers (arg, start, end, single, html_solo); + else + /* use regular character */ + add_char (single); } } @@ -347,7 +621,7 @@ void cm_accent_tilde (arg, start, end) int arg, start, end; { - cm_accent_generic (arg, start, end, "AOano", '~', 0, "tilde"); + cm_accent_generic (arg, start, end, "ANOano", '~', 0, "tilde"); } @@ -356,6 +630,9 @@ cm_accent_tilde (arg, start, end) void cm_special_char (arg) { + int old_escape_html = escape_html; + escape_html = 0; + if (arg == START) { if ((*command == 'L' || *command == 'l' @@ -363,34 +640,37 @@ cm_special_char (arg) && command[1] == 0) { /* Lslash lslash Oslash oslash. Lslash and lslash aren't supported in HTML. */ - if (html && (command[0] == 'O' || command[0] == 'o')) - add_word_args ("&%cslash;", command[0]); + if ((html || xml) && command[0] == 'O') + add_encoded_char ("Oslash", "/O"); + else if ((html || xml) && command[0] == 'o') + add_encoded_char ("oslash", "/o"); else add_word_args ("/%c", command[0]); } else if (strcmp (command, "exclamdown") == 0) - add_word (html ? "¡" : "!"); + add_encoded_char ("iexcl", "!"); else if (strcmp (command, "pounds") == 0) - add_word (html ? "£" : "#"); + add_encoded_char ("pound" , "#"); else if (strcmp (command, "questiondown") == 0) - add_word (html ? "¿" : "?"); + add_encoded_char ("iquest", "?"); else if (strcmp (command, "AE") == 0) - add_word (html ? "Æ" : command); + add_encoded_char ("AElig", command); else if (strcmp (command, "ae") == 0) - add_word (html ? "æ" : command); + add_encoded_char ("aelig", command); else if (strcmp (command, "OE") == 0) - add_word (html ? "Œ" : command); + add_word ("Œ", command); else if (strcmp (command, "oe") == 0) - add_word (html ? "œ" : command); + add_word ("œ", command); else if (strcmp (command, "AA") == 0) - add_word (html ? "Å" : command); + add_encoded_char ("Aring", command); else if (strcmp (command, "aa") == 0) - add_word (html ? "å" : command); + add_encoded_char ("aring", command); else if (strcmp (command, "ss") == 0) - add_word (html ? "ß" : command); + add_encoded_char ("szlig", command); else line_error ("cm_special_char internal error: command=@%s", command); } + escape_html = old_escape_html; } /* Dotless i or j. */ @@ -400,6 +680,7 @@ cm_dotless (arg, start, end) { if (arg == END) { + xml_no_para --; if (output_paragraph[start] != 'i' && output_paragraph[start] != 'j') /* This error message isn't perfect if the argument is multiple characters, but it doesn't seem worth getting right. */ @@ -412,4 +693,6 @@ cm_dotless (arg, start, end) /* We've already inserted the `i' or `j', so nothing to do. */ } + else + xml_no_para ++; } diff --git a/contrib/texinfo/makeinfo/lang.h b/contrib/texinfo/makeinfo/lang.h index 25bf0bd9c4bd..57d4946080fc 100644 --- a/contrib/texinfo/makeinfo/lang.h +++ b/contrib/texinfo/makeinfo/lang.h @@ -1,7 +1,7 @@ /* lang.h -- declarations for language codes etc. - $Id: lang.h,v 1.6 1999/03/22 20:07:34 karl Exp $ + $Id: lang.h,v 1.7 2001/09/11 18:04:29 karl Exp $ - Copyright (C) 1999 Free Software Foundation, Inc. + Copyright (C) 1999, 2001 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,15 +17,14 @@ 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 Karl Heinz Marbaise <kama@hippo.fido.de>. */ + Originally written by Karl Heinz Marbaise <kama@hippo.fido.de>. */ #ifndef LANG_H #define LANG_H -/* The langauge code which can be changed through @documentlanguage - * Actualy Info does not support this (may be in the future) ;-) - * Default for language code is en (english!) kama - * These code should ISO 639 two letter codes. +/* The language code which can be changed through @documentlanguage + * Actually we don't currently support this (may be in the future) ;-) + * These code are the ISO-639 two letter codes. */ typedef enum { @@ -61,19 +60,71 @@ typedef enum /* The current language code. */ extern language_code_type language_code; -/* Information about all valid languages. */ + +/* Information for each language. */ typedef struct { language_code_type lc; /* language code as enum type */ char *abbrev; /* two letter language code */ char *desc; /* full name for language code */ -} language_struct; -extern language_struct language_table[]; +} language_type; + +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). + */ +typedef enum { + no_encoding, + ISO_8859_1, /* default for en, de, */ + ISO_8859_2, /* actualy not supported like the rest below */ + ISO_8859_3, + 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; + -/* The encoding, or null if not set. */ -extern char *document_encoding; +/* Maps an HTML abbreviation to ISO and Unicode codes for a given code. */ + +typedef unsigned short int unicode_t; /* should be 16 bits */ +typedef unsigned char byte_t; + +typedef struct +{ + char *html; /* HTML equivalent like umlaut auml => ä */ + byte_t bytecode; /* 8-Bit Code (ISO 8859-1,...) */ + unicode_t unicode; /* Unicode in U+ convention */ +} iso_map_type; + +/* Information about the document encoding. */ +typedef struct +{ + encoding_code_type ec; /* document encoding type (see above enum) */ + char *ecname; /* encoding name like ISO-8859-1 */ + iso_map_type *isotab; /* address of ISO translation table */ +} encoding_type; +/* Table with all the encoding codes that we recognize. */ +extern encoding_type encoding_table[]; + /* The commands. */ extern void cm_documentlanguage (), cm_documentencoding (); diff --git a/contrib/texinfo/makeinfo/macro.c b/contrib/texinfo/makeinfo/macro.c index 8c89da257106..2bba3782efa2 100644 --- a/contrib/texinfo/makeinfo/macro.c +++ b/contrib/texinfo/makeinfo/macro.c @@ -1,7 +1,7 @@ /* macro.c -- user-defined macros for Texinfo. - $Id: macro.c,v 1.10 1999/08/17 21:06:35 karl Exp $ + $Id: macro.c,v 1.12 2002/03/02 15:05:21 karl Exp $ - Copyright (C) 1998, 99 Free Software Foundation, Inc. + Copyright (C) 1998, 99, 2002 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 @@ -590,10 +590,8 @@ define_macro (mactype, recursive) { if ((input_text_offset + 9) > input_text_length) { - int temp_line = line_number; - line_number = defining_line; - line_error (_("%cend macro not found"), COMMAND_PREFIX); - line_number = temp_line; + file_line_error (input_filename, defining_line, + _("%cend macro not found"), COMMAND_PREFIX); return; } @@ -1002,6 +1000,8 @@ cm_alias () skip_whitespace (); get_until_in_line (1, "=", &(a->alias)); + canon_white (a->alias); + discard_until ("="); skip_whitespace (); get_until_in_line (0, " ", &(a->mapto)); diff --git a/contrib/texinfo/makeinfo/makeinfo.h b/contrib/texinfo/makeinfo/makeinfo.h index caff188ebe42..21aae89b4c80 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.25 1999/09/18 18:09:22 karl Exp $ + $Id: makeinfo.h,v 1.31 2001/09/11 16:37:51 karl Exp $ - Copyright (C) 1996, 97, 98, 99 Free Software Foundation, Inc. + Copyright (C) 1996, 97, 98, 99, 2000, 01 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 @@ -116,6 +116,15 @@ DECLARE (int, multitable_active, 0); /* Nonzero means that we're generating HTML. */ DECLARE (int, html, 0); +/* Nonzero means that we're generating XML. */ +DECLARE (int, xml, 0); + +/* Nonzero means that we're generating DocBook. */ +DECLARE (int, docbook, 0); + +/* Nonzero means true 8-bit output for Info and plain text. */ +DECLARE (int, enable_encoding, 0); + /* Nonzero means escape characters in HTML output. */ DECLARE (int, escape_html, 1); extern char *escape_string (); /* do HTML escapes */ @@ -135,6 +144,9 @@ DECLARE (char *, current_node, NULL); /* Command name in the process of being hacked. */ DECLARE (char *, command, NULL); +/* @documentdescription ... @end documentdescription. */ +DECLARE (char *, document_description, NULL); + /* Nonzero if the last character inserted has the syntax class of NEWLINE. */ DECLARE (int, last_char_was_newline, 1); @@ -144,6 +156,7 @@ DECLARE (char *, input_text, (char *)NULL); DECLARE (int, input_text_length, 0); DECLARE (int, input_text_offset, 0); DECLARE (int, line_number, 0); +DECLARE (char *, toplevel_output_filename, NULL); #define curchar() input_text[input_text_offset] /* A colon separated list of directories to search for files included @@ -181,6 +194,9 @@ DECLARE (int, verbose_mode, 0); /* Nonzero means prefix each @chapter, ... with a number like 1. (--number-sections) */ DECLARE (int, number_sections, 0); +/* Nonzero means split size. When zero, DEFAULT_SPLIT_SIZE is used. */ +DECLARE (int, split_size, 0); + /* Nonzero means expand node names and references while validating. This will avoid errors when the Texinfo document uses features like @@ and @value inconsistently in node names, but will slow @@ -225,6 +241,8 @@ DECLARE (int, expensive_validation, 0); #define COMMAND_PREFIX '@' +#define END_VERBATIM "end verbatim" + /* Stuff for splitting large files. */ #define SPLIT_SIZE_THRESHOLD 70000 /* What's good enough for Stallman... */ #define DEFAULT_SPLIT_SIZE 50000 /* Is probably good enough for me. */ @@ -256,5 +274,4 @@ DECLARE (int, splitting, 1); /* Defaults to true for now. */ #define looking_at(string) \ (strncmp (input_text + input_text_offset, string, strlen (string)) == 0) - #endif /* not MAKEINFO_H */ diff --git a/contrib/texinfo/makeinfo/multi.c b/contrib/texinfo/makeinfo/multi.c index b41bb4709977..6b6ec3dafdf4 100644 --- a/contrib/texinfo/makeinfo/multi.c +++ b/contrib/texinfo/makeinfo/multi.c @@ -1,7 +1,7 @@ /* multi.c -- multitable stuff for makeinfo. - $Id: multi.c,v 1.18 1999/08/17 21:06:56 karl Exp $ + $Id: multi.c,v 1.23 2002/01/19 01:09:08 karl Exp $ - Copyright (C) 1996, 97, 98, 99 Free Software Foundation, Inc. + Copyright (C) 1996, 97, 98, 99, 2000, 01, 02 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 @@ -15,11 +15,14 @@ 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. */ + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Written by phr@gnu.org (Paul Rubin). */ #include "system.h" #include "insertion.h" #include "makeinfo.h" +#include "xml.h" #define MAXCOLS 100 /* remove this limit later @@ */ @@ -108,6 +111,8 @@ draw_horizontal_separator () add_word ("<hr>"); return; } + if (xml) + return; for (s = 0; s < envs[0].current_indent; s++) out_char (' '); @@ -156,6 +161,9 @@ do_multitable () /* 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; @@ -163,6 +171,16 @@ do_multitable () 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 (); @@ -199,7 +217,7 @@ find_template_width (params) do { - if (**params == '{' && (*params)[-1] != '@') + if (**params == '{' && (*params == start || (*params)[-1] != '@')) brace_level++; else if (**params == '}' && (*params)[-1] != '@') brace_level--; @@ -385,10 +403,17 @@ multitable_item () if (html) { if (!first_row) - add_word ("<br></tr>"); /* <br> for non-tables browsers. */ - add_word ("<tr align=\"left\"><td>"); + add_word ("<br></td></tr>"); /* <br> for non-tables browsers. */ + add_word ("<tr align=\"left\"><td valign=\"top\">"); first_row = 0; - return; + return 0; + } + /* else if (docbook)*/ /* 05-08 */ + else if (xml) + { + xml_end_multitable_row (first_row); + first_row = 0; + return 0; } first_row = 0; @@ -504,7 +529,10 @@ cm_tab () error (_("ignoring @tab outside of multitable")); if (html) - add_word ("<td>"); + add_word ("</td><td valign=\"top\">"); + /* else if (docbook)*/ /* 05-08 */ + else if (xml) + xml_end_multitable_column (); else nselect_next_environment (); @@ -516,7 +544,7 @@ cm_tab () void end_multitable () { - if (!html) + if (!html && !docbook) output_multitable_row (); /* Multitables cannot be nested. Otherwise, we'd have to save the @@ -528,7 +556,10 @@ end_multitable () close_insertion_paragraph (); if (html) - add_word ("<br></tr></table>\n"); + add_word ("<br></td></tr></table>\n"); + /* else if (docbook)*/ /* 05-08 */ + else if (xml) + xml_end_multitable (); #if 0 printf (_("** Multicolumn output from last row:\n")); diff --git a/contrib/texinfo/makeinfo/node.c b/contrib/texinfo/makeinfo/node.c index 8dbbd422846b..3c7a27d5d4cd 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.23 1999/09/20 12:31:21 karl Exp $ + $Id: node.c,v 1.31 2002/02/23 19:12:15 karl Exp $ - Copyright (C) 1998, 99 Free Software Foundation, Inc. + Copyright (C) 1998, 99, 2000, 01, 02 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,8 +24,10 @@ #include "macro.h" #include "makeinfo.h" #include "node.h" +#include "html.h" #include "sectioning.h" #include "insertion.h" +#include "xml.h" /* See comments in node.h. */ @@ -64,6 +66,12 @@ write_tag_table_internal (indirect_p) TAG_ENTRY *node; int old_indent = no_indent; + if (xml) + { + flush_output (); + return; + } + no_indent = 1; filling_enabled = 0; must_start_paragraph = 0; @@ -211,7 +219,25 @@ find_node (name) return tag; } -/* Similarly for next etc. references in a @node command, where we +/* 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; +{ + TAG_ENTRY *tag = tag_table; + while (tag) + { + if (tag->html_fname && FILENAME_CMP (tag->html_fname, fname) == 0) + return tag; + tag = tag->next_ent; + } + + return tag; +} + +/* 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) @@ -237,8 +263,8 @@ remember_node_node_reference (node) /* Remember NODE and associates. */ void -remember_node (node, prev, next, up, position, line_no, flags) - char *node, *prev, *next, *up; +remember_node (node, prev, next, up, position, line_no, fname, flags) + char *node, *prev, *next, *up, *fname; int position, line_no, flags; { /* Check for existence of this tag already. */ @@ -280,6 +306,7 @@ remember_node (node, prev, next, up, position, line_no, flags) node_number++; new->number = node_number; } + new->html_fname = fname; new->next_ent = tag_table; tag_table = new; } @@ -392,7 +419,7 @@ glean_node_from_menu (remember_ref, ref_type) char *nodename; char *line, *expanded_line; char *old_input = input_text; - size_t old_size = input_text_length; + int old_size = input_text_length; if (strncmp (&input_text[input_text_offset + 1], MENU_STARTER, @@ -457,9 +484,13 @@ set_current_output_filename (fname) void cm_node () { + static long epilogue_len = 0L; char *node, *prev, *next, *up; int new_node_pos, defaulting, this_section; int no_warn = 0; + char *fname_for_this_node = NULL; + char *tem; + TAG_ENTRY *tag = NULL; if (strcmp (command, "nwnode") == 0) no_warn = TAG_FLAG_NO_WARN; @@ -473,27 +504,12 @@ cm_node () if (!html && !already_outputting_pending_notes) { + if (!xml) close_paragraph (); output_pending_notes (); } - if (html && splitting && top_node_seen) - { - /* End the current split output file. */ - close_paragraph (); - output_pending_notes (); - start_paragraph (); - /* Fixme: html: need a navigation bar here. */ - add_word ("</body></html>\n"); - close_paragraph (); - fclose (output_stream); - output_stream = NULL; - } - - filling_enabled = indented_fill = 0; new_node_pos = output_position; - if (!html || (html && splitting)) - current_footnote_number = 1; if (macro_expansion_output_stream && !executing_string) append_to_expansion_output (input_text_offset + 1); @@ -510,6 +526,70 @@ cm_node () prev = get_node_token (0); up = get_node_token (0); + if (html && splitting + /* If there is a Top node, it always goes into index.html. So + don't start a new HTML file for Top. */ + && (top_node_seen || strcasecmp (node, "Top") != 0)) + { + /* We test *node here so that @node without a valid name won't + start a new file name with a bogus name such as ".html". + This could happen if we run under "--force", where we cannot + simply bail out. Continuing to use the same file sounds like + the best we can do in such cases. */ + if (current_output_filename && output_stream && *node) + { + char *fname_for_prev_node; + + if (current_node) + { + /* NOTE: current_node at this point still holds the name + of the previous node. */ + tem = expand_node_name (current_node); + fname_for_prev_node = nodename_to_filename (tem); + free (tem); + } + else /* could happen if their top node isn't named "Top" */ + fname_for_prev_node = filename_part (current_output_filename); + tem = expand_node_name (node); + fname_for_this_node = nodename_to_filename (tem); + free (tem); + /* Don't close current output file, if next output file is + to have the same name. This may happen at top level, or + if two nodes produce the same file name under --split. */ + if (FILENAME_CMP (fname_for_this_node, fname_for_prev_node) != 0) + { + long pos1 = 0; + + /* End the current split output file. */ + close_paragraph (); + output_pending_notes (); + start_paragraph (); + /* Compute the length of the HTML file's epilogue. We + cannot know the value until run time, due to the + text/binary nuisance on DOS/Windows platforms, where + 2 `\r' characters could be added to the epilogue when + it is written in text mode. */ + if (epilogue_len == 0) + { + flush_output (); + pos1 = ftell (output_stream); + } + add_word ("</body></html>\n"); + close_paragraph (); + if (epilogue_len == 0) + epilogue_len = ftell (output_stream) - pos1; + fclose (output_stream); + output_stream = NULL; + tag = find_node_by_fname (fname_for_this_node); + } + free (fname_for_prev_node); + } + } + + filling_enabled = indented_fill = 0; + if (!html || (html && splitting)) + current_footnote_number = 1; + if (verbose_mode) printf (_("Formatting node %s...\n"), node); @@ -517,7 +597,23 @@ cm_node () remember_itext (input_text, input_text_offset); no_indent = 1; - if (!no_headers && !html) + if (xml) + { + xml_begin_document (); + xml_begin_node (); + if (!docbook) + { + xml_insert_element (NODENAME, START); + if (macro_expansion_output_stream && !executing_string) + me_execute_string (node); + else + execute_string ("%s", node); + xml_insert_element (NODENAME, END); + } + else + xml_node_id = xml_id (node); + } + else if (!no_headers && !html) { add_word_args ("\037\nFile: %s, Node: ", pretty_output_filename); @@ -729,33 +825,83 @@ cm_node () if (!*next) { free (next); next = NULL; } if (!*prev) { free (prev); prev = NULL; } if (!*up) { free (up); up = NULL; } - remember_node (node, prev, next, up, new_node_pos, line_number, no_warn); + remember_node (node, prev, next, up, new_node_pos, line_number, + fname_for_this_node, no_warn); outstanding_node = 1; } if (html) { - char *tem; - - if (splitting) - { /* this code not operational, we do not currently split html */ - char filename[20]; - - sprintf (filename, "node%d.html", number_of_node (node)); - output_stream = fopen (filename, "w"); + if (splitting && *node && output_stream == NULL) + { + char *dirname; + char filename[PATH_MAX]; + + dirname = pathname_part (current_output_filename); + strcpy (filename, dirname); + strcat (filename, fname_for_this_node); + free (dirname); + + /* See if the node name converted to a file name clashes + with other nodes or anchors. If it clashes with an + anchor, we complain and nuke that anchor's file. */ + if (!tag) + { + output_stream = fopen (filename, "w"); + html_output_head_p = 0; /* so that we generate HTML preamble */ + html_output_head (); + } + else if ((tag->flags & TAG_FLAG_ANCHOR) != 0) + { + line_error (_("Anchor `%s' and node `%s' map to the same file name"), + tag->node, node); + file_line_error (tag->filename, tag->line_no, + _("This @anchor command ignored; references to it will not work")); + file_line_error (tag->filename, tag->line_no, + _("Rename this anchor or use the `--no-split' option")); + /* Nuke the file name recorded in anchor's tag. + Since we are about to nuke the file itself, we + don't want find_node_by_fname to consider this + anchor anymore. */ + free (tag->html_fname); + tag->html_fname = NULL; + output_stream = fopen (filename, "w"); + html_output_head_p = 0; /* so that we generate HTML preamble */ + html_output_head (); + } + else + { + /* This node's file name clashes with another node. + We put them both on the same file. */ + output_stream = fopen (filename, "r+"); + if (output_stream) + { + static char html_end[] = "</body></html>\n"; + char end_line[sizeof(html_end)]; + int fpos = fseek (output_stream, -epilogue_len, + SEEK_END); + + if (fpos < 0 + || fgets (end_line, sizeof (html_end), + output_stream) == NULL + /* Paranoia: did someone change the way HTML + files are finished up? */ + || strcasecmp (end_line, html_end) != 0) + { + line_error (_("Unexpected string at end of split-HTML file `%s'"), + fname_for_this_node); + fclose (output_stream); + xexit (1); + } + fseek (output_stream, -epilogue_len, SEEK_END); + } + } if (output_stream == NULL) { fs_error (filename); xexit (1); } set_current_output_filename (filename); - /* FIXME: when this code is operational, we will need to - expand node, next, prev, and up before output. */ - add_word_args ("<html><head><title>%s</title>", node); - if (next) add_link (next, "rel=next"); - if (prev) add_link (prev, "rel=previous"); - if (up) add_link (up, "rel=up"); - add_word ("</head>\n<body>\n"); } if (!splitting && no_headers) @@ -779,32 +925,32 @@ cm_node () if (next) { - add_word (",\n"); - add_word (_("Next:")); - add_word ("<a rel=next href=\""); tem = expansion (next, 0); - add_anchor_name (tem, 1); - add_word_args ("\">%s</a>", tem); + add_word (",\n"); + add_word (_("Next:")); + add_word ("<a rel=next href=\""); + add_anchor_name (tem, 1); + add_word_args ("\">%s</a>", tem); free (tem); } if (prev) { - add_word (",\n"); - add_word (_("Previous:")); - add_word ("<a rel=previous href=\""); tem = expansion (prev, 0); - add_anchor_name (tem, 1); - add_word_args ("\">%s</a>", tem); + add_word (",\n"); + add_word (_("Previous:")); + add_word ("<a rel=previous href=\""); + add_anchor_name (tem, 1); + add_word_args ("\">%s</a>", tem); free (tem); } if (up) { - add_word (",\n"); - add_word (_("Up:")); - add_word ("<a rel=up href=\""); tem = expansion (up, 0); - add_anchor_name (tem, 1); - add_word_args ("\">%s</a>", tem); + add_word (",\n"); + add_word (_("Up:")); + add_word ("<a rel=up href=\""); + add_anchor_name (tem, 1); + add_word_args ("\">%s</a>", tem); free (tem); } /* html fixxme: we want a `top' or `contents' link here. */ @@ -812,7 +958,29 @@ cm_node () add_word_args ("\n%s<br>\n", splitting ? "<hr>" : ""); } } - + else if (docbook) + ; + else if (xml) + { + if (next) + { + xml_insert_element (NODENEXT, START); + execute_string ("%s", next); + xml_insert_element (NODENEXT, END); + } + if (prev) + { + xml_insert_element (NODEPREV, START); + execute_string ("%s", prev); + xml_insert_element (NODEPREV, END); + } + if (up) + { + xml_insert_element (NODEUP, START); + execute_string ("%s", up); + xml_insert_element (NODEUP, END); + } + } else if (!no_headers) { if (macro_expansion_output_stream) @@ -858,6 +1026,7 @@ cm_anchor (arg) int arg; { char *anchor; + char *fname_for_anchor = NULL; if (arg == END) return; @@ -872,6 +1041,8 @@ cm_anchor (arg) sure a new paragraph is indeed started. */ if (!paragraph_is_open) { + if (!executing_string && html) + html_output_head (); start_paragraph (); if (!in_fixed_width_font || in_menu || in_detailmenu) { @@ -882,11 +1053,104 @@ cm_anchor (arg) add_word ("<a name=\""); add_anchor_name (anchor, 0); add_word ("\"></a>"); + if (splitting) + { + /* If we are splitting, cm_xref will produce a reference to + a file whose name is derived from the anchor name. So we + must create a file when we see an @anchor, otherwise + xref's to anchors won't work. The file we create simply + redirects to the file of this anchor's node. */ + TAG_ENTRY *tag; + + fname_for_anchor = nodename_to_filename (anchor); + /* See if the anchor name converted to a file name clashes + with other anchors or nodes. */ + tag = find_node_by_fname (fname_for_anchor); + if (tag) + { + if ((tag->flags & TAG_FLAG_ANCHOR) != 0) + line_error (_("Anchors `%s' and `%s' map to the same file name"), + anchor, tag->node); + else + line_error (_("Anchor `%s' and node `%s' map to the same file name"), + anchor, tag->node); + line_error (_("@anchor command ignored; references to it will not work")); + line_error (_("Rename this anchor or use the `--no-split' option")); + free (fname_for_anchor); + /* We will not be creating a file for this anchor, so + set its name to NULL, so that remember_node stores a + NULL and find_node_by_fname won't consider this + anchor for clashes. */ + fname_for_anchor = NULL; + } + else + { + char *dirname, *p; + char filename[PATH_MAX]; + FILE *anchor_stream; + + dirname = pathname_part (current_output_filename); + strcpy (filename, dirname); + strcat (filename, fname_for_anchor); + free (dirname); + + anchor_stream = fopen (filename, "w"); + if (anchor_stream == NULL) + { + fs_error (filename); + xexit (1); + } + /* The HTML magic below will cause the browser to + immediately go to the anchor's node's file. Lynx + seems not to support this redirection, but it looks + like a bug in Lynx, and they can work around it by + clicking on the link once more. */ + fputs ("<meta http-equiv=\"refresh\" content=\"0; url=", + anchor_stream); + /* Make the indirect link point to the current node's + file and anchor's "<a name" label. If we don't have + a valid node name, refer to the current output file + instead. */ + if (current_node && *current_node) + { + char *fn, *tem; + + tem = expand_node_name (current_node); + fn = nodename_to_filename (tem); + free (tem); + fputs (fn, anchor_stream); + free (fn); + } + else + { + char *base = filename_part (current_output_filename); + + fputs (base, anchor_stream); + free (base); + } + fputs ("#", anchor_stream); + for (p = anchor; *p; p++) + { + if (*p == '&') + fputs ("&", anchor_stream); + else if (!URL_SAFE_CHAR (*p)) + fprintf (anchor_stream, "%%%x", (unsigned char) *p); + else + fputc (*p, anchor_stream); + } + fputs ("\">\n", anchor_stream); + fclose (anchor_stream); + } + } + } + else if (xml) + { + xml_insert_element_with_attribute (ANCHOR, START, "name=\"%s\"", anchor); + xml_insert_element (ANCHOR, END); } - /* Save it in the tag table. */ remember_node (anchor, NULL, NULL, NULL, output_position + output_column, - line_number, TAG_FLAG_ANCHOR); + line_number, fname_for_anchor, TAG_FLAG_ANCHOR); } /* Find NODE in REF_LIST. */ @@ -1114,12 +1378,9 @@ validate_file (tag_table) { line_error (_("Next field of node `%s' not pointed to"), tags->node); - line_number = temp_tag->line_no; - input_filename = temp_tag->filename; - line_error (_("This node (%s) has the bad Prev"), - temp_tag->node); - input_filename = tags->filename; - line_number = tags->line_no; + file_line_error (temp_tag->filename, temp_tag->line_no, + _("This node (%s) has the bad Prev"), + temp_tag->node); temp_tag->flags |= TAG_FLAG_PREV_ERROR; } } @@ -1175,12 +1436,10 @@ validate_file (tag_table) line_error (_("Prev field of node `%s' not pointed to"), tags->node); - line_number = temp_tag->line_no; - input_filename = temp_tag->filename; - line_error (_("This node (%s) has the bad Next"), - temp_tag->node); - input_filename = tags->filename; - line_number = tags->line_no; + file_line_error (temp_tag->filename, + temp_tag->line_no, + _("This node (%s) has the bad Next"), + temp_tag->node); temp_tag->flags |= TAG_FLAG_NEXT_ERROR; } } @@ -1259,13 +1518,9 @@ validate_file (tag_table) if (!nref && !tref) { temp_tag = find_node (tags->up); - line_number = temp_tag->line_no; - input_filename = temp_tag->filename; - line_error ( + file_line_error (temp_tag->filename, temp_tag->line_no, _("Node `%s' lacks menu item for `%s' despite being its Up target"), tags->up, tags->node); - line_number = tags->line_no; - input_filename = tags->filename; } } } diff --git a/contrib/texinfo/makeinfo/node.h b/contrib/texinfo/makeinfo/node.h index e2fc883d73aa..735a23131628 100644 --- a/contrib/texinfo/makeinfo/node.h +++ b/contrib/texinfo/makeinfo/node.h @@ -1,7 +1,7 @@ /* node.h -- declarations for Node. - $Id: node.h,v 1.5 1999/07/11 16:50:19 karl Exp $ + $Id: node.h,v 1.6 2002/01/16 15:52:45 karl Exp $ - Copyright (C) 1996, 97, 98, 99 Free Software Foundation, Inc. + Copyright (C) 1996, 97, 98, 99, 2002 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 @@ -39,6 +39,8 @@ typedef struct tentry int number; /* Number for this node, relevant for HTML splitting -- from use+define order, not just define. */ + char *html_fname; /* The HTML file to which this node is written + (non-NULL only for HTML splitting). */ } TAG_ENTRY; /* If node-a has a "Next" for node-b, but node-b has no "Prev" for node-a, diff --git a/contrib/texinfo/makeinfo/sectioning.c b/contrib/texinfo/makeinfo/sectioning.c index b06785b94b62..850fc4654ba9 100644 --- a/contrib/texinfo/makeinfo/sectioning.c +++ b/contrib/texinfo/makeinfo/sectioning.c @@ -1,7 +1,7 @@ /* sectioning.c -- all related stuff @chapter, @section... @contents - $Id: sectioning.c,v 1.12 1999/08/17 21:06:50 karl Exp $ + $Id: sectioning.c,v 1.17 2002/02/09 00:54:51 karl Exp $ - Copyright (C) 1999 Free Software Foundation, Inc. + Copyright (C) 1999, 2001, 02 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 @@ -26,6 +26,7 @@ #include "node.h" #include "toc.h" #include "sectioning.h" +#include "xml.h" /* See comment in sectioning.h. */ section_alist_type section_alist[] = { @@ -210,11 +211,37 @@ what_section (text) return -1; } - void sectioning_underscore (cmd) char *cmd; { + if (xml) + { + 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); + } + else + { char character; char *temp; int level; @@ -235,6 +262,7 @@ sectioning_underscore (cmd) { character = scoring_characters[level]; insert_and_underscore (level, character, cmd); + } } } @@ -385,16 +413,22 @@ sectioning_html (level, cmd) old_no_indent = no_indent; no_indent = 1; - add_word_args ("<h%d>", level + 1); /* level 0 is <h1> */ + add_word_args ("<h%d>", level + 2); /* level 0 (chapter) is <h2> */ /* If we are outside of any node, produce an anchor that the TOC could refer to. */ if (!current_node || !*current_node) { + static const char a_name[] = "<a name=\""; + starting_pos = output_paragraph + output_paragraph_offset; - add_word_args ("<a name=\"TOC%d\">", toc_ref_count++); - toc_anchor = substring (starting_pos + 9, + add_word_args ("%sTOC%d\">", a_name, toc_ref_count++); + toc_anchor = substring (starting_pos + sizeof (a_name) - 1, output_paragraph + output_paragraph_offset); + /* This must be added after toc_anchor is extracted, since + toc_anchor cannot include the closing </a>. For details, + see toc.c:toc_add_entry and toc.c:contents_update_html. */ + add_word ("</a>"); } starting_pos = output_paragraph + output_paragraph_offset; @@ -431,13 +465,13 @@ sectioning_html (level, cmd) if (section_alist[index].toc == TOC_YES) toc_add_entry (substring (starting_pos, ending_pos), level, current_node, toc_anchor); - + free (temp); if (outstanding_node) outstanding_node = 0; - add_word_args ("</h%d>", level+1); + add_word_args ("</h%d>", level + 2); close_paragraph(); filling_enabled = 1; no_indent = old_no_indent; @@ -488,14 +522,8 @@ cm_top () { if (tag->flags & TAG_FLAG_IS_TOP) { - int old_line_number = line_number; - char *old_input_filename = input_filename; - - line_number = tag->line_no; - input_filename = tag->filename; - line_error (_("Here is the %ctop node"), COMMAND_PREFIX); - input_filename = old_input_filename; - line_number = old_line_number; + file_line_error (tag->filename, tag->line_no, + _("Here is the %ctop node"), COMMAND_PREFIX); return; } tag = tag->next_ent; @@ -506,7 +534,7 @@ cm_top () TAG_ENTRY *top_node = find_node ("Top"); top_node_seen = 1; - /* It is an error to use @top before you have used @node. */ + /* It is an error to use @top before using @node. */ if (!tag_table) { char *top_name; @@ -518,21 +546,6 @@ cm_top () free (top_name); return; } - else if (html && splitting) - { - char *next = top_node ? top_node->next : NULL; - - add_word ("<p>"); - if (next) - { - add_word (_("Next:")); - add_word ("<a rel=next href=\""); - add_anchor_name (next, 1); - add_word ("\">"); - execute_string (next); - add_word ("</a>\n"); - } - } cm_unnumbered (); diff --git a/contrib/texinfo/makeinfo/texinfo.dtd b/contrib/texinfo/makeinfo/texinfo.dtd new file mode 100644 index 000000000000..ead278a065e1 --- /dev/null +++ b/contrib/texinfo/makeinfo/texinfo.dtd @@ -0,0 +1,345 @@ +<!-- $Id: texinfo.dtd,v 1.1 2001/05/21 17:36:22 karl Exp $ + Document Type Definition for Texinfo + ************************************ + For texinfo-4.0b + ******************* + + Author: Philippe Martin (feloy@free.fr) + Contributors: + Karl Eichwalder (keichwa@gmx.net) + + HISTORY + ******* + Version 0.2 - 2001-05-08 + Version 0.1 - 2001-05-07 + + + + Copyright (C) 2001 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. */ +--> + +<!-- ENTITIES --> + +<!-- Meta-information --> +<!ENTITY % metainformation "setfilename | settitle | titlefont | dircategory"> + +<!-- block --> +<!-- ***** --> +<!ENTITY % block "menu | para | quotation | example | smallexample | lisp + | smalllisp | cartouche | format | smallformat | display + | smalldisplay | itemize | enumerate | sp | center | group + | table | multitable"> + +<!-- Sectioning --> +<!-- ********** --> +<!ENTITY % section.level1 "top | chapter | unnumbered | appendix + | majorheading | chapheading"> + +<!ENTITY % section.level2 "section | unnumberedsec | appendixsec | heading"> + +<!ENTITY % section.level3 "subsection | unnumberedsubsec | appendixsubsec + | subheading"> + +<!ENTITY % section.level4 "subsubsection | unnumberedsubsubsec + | appendixsubsubsec | subsubheading"> + +<!ENTITY % section.all "%section.level1; | %section.level2; | %section.level3; + | %section.level4;"> + + +<!ENTITY % section.level1.content "(%block; + | %section.level2; + | %section.level3; + | %section.level4; + | printindex)*"> + +<!ENTITY % section.level2.content "(%block; + | %section.level3; + | %section.level4;)*"> + +<!ENTITY % section.level3.content "(%block; + | %section.level4;)*"> + +<!ENTITY % section.level4.content "(%block;)*"> + + +<!-- Inline --> +<!-- ****** --> +<!ENTITY % Inline.emphasize "strong | emph"> +<!ENTITY % Inline.smallcaps "sc"> +<!ENTITY % Inline.fonts "i | b | tt | r"> +<!ENTITY % Inline.markup "code | dfn | cite | key | kbd | var | acronym | url"> +<!ENTITY % Inline.reference "xref | inforef | indexterm | email | uref"> + +<!ENTITY % Inline.phrase + "%Inline.emphasize; | %Inline.smallcaps; | %Inline.fonts; + | %Inline.markup; | %Inline.reference; "> + + +<!-- ************ --> +<!-- * ELEMENTS * --> +<!-- ************ --> + +<!-- TOP Level Element --> +<!-- ***************** --> +<!ELEMENT texinfo ((%metainformation; | node | %block;)* )> + +<!-- meta-information --> +<!ELEMENT setfilename (#PCDATA)> +<!ELEMENT settitle (#PCDATA)> +<!ELEMENT titlefont (#PCDATA)> +<!ELEMENT dircategory (#PCDATA)> + +<!-- NODES --> +<!-- ***** --> +<!ELEMENT node (nodename, nodenext?, nodeprev?, nodeup?, + (para | menu | %section.all;)*) > + +<!ELEMENT nodename (#PCDATA)> +<!ELEMENT nodenext (#PCDATA)> +<!ELEMENT nodeprev (#PCDATA)> +<!ELEMENT nodeup (#PCDATA)> + +<!-- SECTIONING --> +<!-- ********** --> + +<!ELEMENT top (title?, %section.level1.content;)> + +<!ELEMENT chapter (title?, %section.level1.content;)> +<!ELEMENT section (title?, %section.level2.content;)> +<!ELEMENT subsection (title?, %section.level3.content;)> +<!ELEMENT subsubsection (title?, %section.level4.content;)> + +<!ELEMENT unnumbered (title?, %section.level1.content;)> +<!ELEMENT unnumberedsec (title?, %section.level2.content;)> +<!ELEMENT unnumberedsubsec (title?, %section.level3.content;)> +<!ELEMENT unnumberedsubsubsec (title?, %section.level4.content;)> + +<!ELEMENT appendix (title?, %section.level1.content;)> +<!ELEMENT appendixsec (title?, %section.level2.content;)> +<!ELEMENT appendixsubsec (title?, %section.level3.content;)> +<!ELEMENT appendixsubsubsec (title?, %section.level4.content;)> + +<!ELEMENT majorheading (title?, %section.level1.content;)> +<!ELEMENT chapheading (title?, %section.level1.content;)> +<!ELEMENT heading (title?, %section.level2.content;)> +<!ELEMENT subheading (title?, %section.level3.content;)> +<!ELEMENT subsubheading (title?, %section.level4.content;)> + +<!ELEMENT title (#PCDATA | %Inline.phrase; | footnote)*> + +<!-- BLOCK Elements --> +<!-- ************** --> + +<!ELEMENT quotation (#PCDATA | %block; | %Inline.phrase;)*> +<!ELEMENT example (#PCDATA | %block; | %Inline.phrase;)*> +<!ELEMENT smallexample (#PCDATA | %block; | %Inline.phrase;)*> +<!ELEMENT lisp (#PCDATA | %block; | %Inline.phrase;)*> +<!ELEMENT smalllisp (#PCDATA | %block; | %Inline.phrase;)*> +<!ELEMENT cartouche (#PCDATA | %block; | %Inline.phrase;)*> +<!ELEMENT format (#PCDATA | %block; | %Inline.phrase;)*> +<!ELEMENT smallformat (#PCDATA | %block; | %Inline.phrase;)*> +<!ELEMENT display (#PCDATA | %block; | %Inline.phrase;)*> +<!ELEMENT smalldisplay (#PCDATA | %block; | %Inline.phrase;)*> +<!ELEMENT center (#PCDATA | %block; | %Inline.phrase;)*> +<!ELEMENT group (#PCDATA | %block; | %Inline.phrase;)*> +<!ELEMENT image (#PCDATA)> + +<!ELEMENT para (#PCDATA | %Inline.phrase; | footnote)*> + +<!ELEMENT menu ((menuentry | para)*)> +<!ELEMENT menuentry (menunode?, menutitle?, menucomment?)> +<!ELEMENT menunode (#PCDATA)> +<!ELEMENT menutitle (#PCDATA)> +<!ELEMENT menucomment (#PCDATA | para)*> + +<!-- Lists --> +<!ELEMENT itemize (itemfunction, (item | itemize | enumerate | indexterm)*)> +<!ELEMENT enumerate (enumarg?, (item | itemize | enumerate)*)> +<!ATTLIST enumerate + first CDATA #IMPLIED> + +<!ELEMENT item (%block;)*> +<!ELEMENT enumarg (#PCDATA)> + +<!ELEMENT itemfunction (#PCDATA | %Inline.phrase;)*> + +<!-- Tables --> +<!ELEMENT table (tableitem | indexterm)+> +<!ELEMENT tableitem (tableterm+, item)> +<!ELEMENT tableterm (#PCDATA | %Inline.phrase;)*> + +<!ELEMENT multitable (columnfraction*, row*)> +<!ELEMENT columnfraction (#PCDATA)> +<!ELEMENT row (entry*)> +<!ELEMENT entry (#PCDATA | %Inline.phrase;)*> + +<!-- INLINE Elements --> +<!-- *************** --> + +<!-- Emphasize --> +<!ELEMENT strong (#PCDATA | %Inline.phrase;)*> +<!ELEMENT emph (#PCDATA | %Inline.phrase;)*> + +<!-- small caps --> +<!ELEMENT sc (#PCDATA | %Inline.phrase;)*> + +<!-- fonts --> +<!ELEMENT i (#PCDATA | %Inline.phrase;)*> +<!ELEMENT b (#PCDATA | %Inline.phrase;)*> +<!ELEMENT tt (#PCDATA | %Inline.phrase;)*> +<!ELEMENT r (#PCDATA | %Inline.phrase;)*> +<!ELEMENT notfixedwidth (#PCDATA | %Inline.phrase;)*> + +<!-- markup --> +<!ELEMENT code (#PCDATA | %Inline.phrase;)*> +<!ELEMENT dfn (#PCDATA | %Inline.phrase;)*> +<!ELEMENT cite (#PCDATA | %Inline.phrase;)*> +<!ELEMENT key (#PCDATA | %Inline.phrase;)*> +<!ELEMENT kbd (#PCDATA | %Inline.phrase;)*> +<!ELEMENT var (#PCDATA | %Inline.phrase;)*> +<!ELEMENT acronym (#PCDATA | %Inline.phrase;)*> +<!ELEMENT url (#PCDATA | %Inline.phrase;)*> + +<!-- reference --> +<!ELEMENT anchor EMPTY> +<!ATTLIST anchor + name CDATA #IMPLIED> + +<!ELEMENT xref (xrefnodename | xrefinfoname | xrefinfofile + | xrefprintedname | xrefprinteddesc)*> +<!ELEMENT xrefnodename (#PCDATA | %Inline.phrase;)*> +<!ELEMENT xrefinfoname (#PCDATA | %Inline.phrase;)*> +<!ELEMENT xrefinfofile (#PCDATA | %Inline.phrase;)*> +<!ELEMENT xrefprintedname (#PCDATA | %Inline.phrase;)*> +<!ELEMENT xrefprinteddesc (#PCDATA | %Inline.phrase;)*> + +<!ELEMENT inforef (inforefnodename | inforefrefname | inforefinfoname)*> +<!ELEMENT inforefnodename (#PCDATA | %Inline.phrase;)*> +<!ELEMENT inforefrefname (#PCDATA | %Inline.phrase;)*> +<!ELEMENT inforefinfoname (#PCDATA | %Inline.phrase;)*> + +<!ELEMENT indexterm (#PCDATA | %Inline.phrase;)*> +<!ATTLIST indexterm + INDEX CDATA #IMPLIED> + +<!ELEMENT email (emailaddress, emailname?)> +<!ELEMENT emailaddress (#PCDATA | %Inline.phrase;)*> +<!ELEMENT emailname (#PCDATA | %Inline.phrase;)*> + +<!ELEMENT uref (urefurl, urefdesc?, urefreplacement?)> +<!ELEMENT urefurl (#PCDATA | %Inline.phrase;)*> +<!ELEMENT urefdesc (#PCDATA | %Inline.phrase;)*> +<!ELEMENT urefreplacement (#PCDATA | %Inline.phrase;)*> + +<!ELEMENT footnote (para)> + + + +<!ENTITY tex "TeX"> +<!ENTITY ellipsis ""> +<!ENTITY lt ""> +<!ENTITY gt ""> +<!ENTITY bullet ""> +<!ENTITY copyright ""> +<!ENTITY minus ""> +<!ENTITY linebreak ""> +<!ENTITY space ""> +<!ENTITY dots ""> +<!ENTITY enddots ""> +<!ENTITY amp ""> + +<!ENTITY auml ""> +<!ENTITY ouml ""> +<!ENTITY uuml ""> +<!ENTITY Auml ""> +<!ENTITY Ouml ""> +<!ENTITY Uuml ""> +<!ENTITY Euml ""> +<!ENTITY euml ""> +<!ENTITY Iuml ""> +<!ENTITY iuml ""> +<!ENTITY yuml ""> +<!ENTITY uml ""> + +<!ENTITY Aacute ""> +<!ENTITY Eacute ""> +<!ENTITY Iacute ""> +<!ENTITY Oacute ""> +<!ENTITY Uacute ""> +<!ENTITY Yacute ""> +<!ENTITY aacute ""> +<!ENTITY eacute ""> +<!ENTITY iacute ""> +<!ENTITY oacute ""> +<!ENTITY uacute ""> +<!ENTITY yacute ""> + +<!ENTITY ccedil ""> +<!ENTITY Ccedil ""> + +<!ENTITY Acirc ""> +<!ENTITY Ecirc ""> +<!ENTITY Icirc ""> +<!ENTITY Ocirc ""> +<!ENTITY Ucirc ""> +<!ENTITY acirc ""> +<!ENTITY ecirc ""> +<!ENTITY icirc ""> +<!ENTITY ocirc ""> +<!ENTITY ucirc ""> + +<!ENTITY Agrave ""> +<!ENTITY Egrave ""> +<!ENTITY Igrave ""> +<!ENTITY Ograve ""> +<!ENTITY Ugrave ""> +<!ENTITY agrave ""> +<!ENTITY egrave ""> +<!ENTITY igrave ""> +<!ENTITY ograve ""> +<!ENTITY ugrave ""> + +<!ENTITY Atilde ""> +<!ENTITY Ntilde ""> +<!ENTITY Otilde ""> +<!ENTITY atilde ""> +<!ENTITY ntilde ""> +<!ENTITY otilde ""> + +<!ENTITY oslash ""> +<!ENTITY Oslash ""> + +<!ENTITY iexcl ""> +<!ENTITY pound ""> +<!ENTITY iquest ""> +<!ENTITY AElig ""> +<!ENTITY aelig ""> +<!ENTITY Aring ""> +<!ENTITY aring ""> +<!ENTITY szlig ""> + +<!ENTITY macr ""> + + +<!-- fixxme: not yet classified --> + +<!ELEMENT sp (#PCDATA)> +<!ATTLIST sp + lines CDATA #IMPLIED> +<!ELEMENT printindex (#PCDATA)> + diff --git a/contrib/texinfo/makeinfo/texinfo.xsl b/contrib/texinfo/makeinfo/texinfo.xsl new file mode 100644 index 000000000000..401e9be06a89 --- /dev/null +++ b/contrib/texinfo/makeinfo/texinfo.xsl @@ -0,0 +1,242 @@ +<?xml version='1.0'?> +<!-- $Id: texinfo.xsl,v 1.1 2001/06/07 18:35:23 karl Exp $ --> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + version="1.0"> + +<xsl:output method="html" indent="yes"/> + +<!-- root rule --> +<xsl:template match="/"> + <HTML> + <HEAD><TITLE> + <xsl:apply-templates select="TEXINFO/SETTITLE" mode="head"/> + </TITLE></HEAD> + <BODY BGCOLOR="#FFFFFF"><xsl:apply-templates/> +</BODY></HTML> +</xsl:template> + + +<xsl:template match="TEXINFO"> + <xsl:apply-templates/> +</xsl:template> + + +<xsl:template match="TEXINFO/SETFILENAME"> +</xsl:template> + +<xsl:template match="TEXINFO/SETTITLE" mode="head"> + <xsl:apply-templates/> +</xsl:template> + +<xsl:template match="TEXINFO/SETTITLE"> + <h1><xsl:apply-templates/></h1> +</xsl:template> + + +<xsl:template match="TEXINFO/DIRCATEGORY"> +</xsl:template> + +<xsl:template match="//PARA"> + <p><xsl:apply-templates/></p> +</xsl:template> + +<xsl:template match="//EMPH"> + <i><xsl:apply-templates/></i> +</xsl:template> + +<!-- The node --> +<xsl:template match="TEXINFO/NODE"> + <hr><p> + <xsl:apply-templates select="NODENAME" mode="select"/> + <xsl:apply-templates select="NODEPREV" mode="select"/> + <xsl:apply-templates select="NODEUP" mode="select"/> + <xsl:apply-templates select="NODENEXT" mode="select"/> + <xsl:apply-templates/> + <h2>Footnotes</h2> + <ol> + <xsl:apply-templates select=".//FOOTNOTE" mode="footnote"/> + </ol> + </p></hr> +</xsl:template> + +<xsl:template match="TEXINFO/NODE/NODENAME" mode="select"> +<h2> + <a> + <xsl:attribute name="name"> + <xsl:apply-templates/> + </xsl:attribute> + <xsl:apply-templates/> + </a> +</h2> +</xsl:template> + +<xsl:template match="TEXINFO/NODE/NODENAME"/> + + +<xsl:template match="TEXINFO/NODE/NODEPREV" mode="select"> + [ <b>Previous: </b> + <a> + <xsl:attribute name="href"> + <xsl:text>#</xsl:text> + <xsl:apply-templates/> + </xsl:attribute> + <xsl:apply-templates/> + </a> ] +</xsl:template> + +<xsl:template match="TEXINFO/NODE/NODEPREV"/> + +<xsl:template match="TEXINFO/NODE/NODEUP" mode="select"> + [ <b>Up: </b> + <a> + <xsl:attribute name="href"> + <xsl:text>#</xsl:text> + <xsl:apply-templates/> + </xsl:attribute> + <xsl:apply-templates/> + </a> ] +</xsl:template> + +<xsl:template match="TEXINFO/NODE/NODEUP"/> + +<xsl:template match="TEXINFO/NODE/NODENEXT" mode="select"> + [ <b>Next: </b> + <a> + <xsl:attribute name="href"> + <xsl:text>#</xsl:text> + <xsl:apply-templates/> + </xsl:attribute> + <xsl:apply-templates/> + </a> ] +</xsl:template> + +<xsl:template match="TEXINFO/NODE/NODENEXT"/> + +<!-- Menu --> +<xsl:template match="//MENU"> + <h3>Menu</h3> + <xsl:apply-templates/> +</xsl:template> + +<xsl:template match="//MENU/MENUENTRY"> + <a> + <xsl:attribute name="href"> + <xsl:text>#</xsl:text> + <xsl:apply-templates select="MENUNODE"/> + </xsl:attribute> + <xsl:apply-templates select="MENUTITLE"/> + </a>: + <xsl:apply-templates select="MENUCOMMENT"/> +<br></br> +</xsl:template> + +<xsl:template match="//MENU/MENUENTRY/MENUNODE"> + <xsl:apply-templates/> +</xsl:template> + +<xsl:template match="//MENU/MENUENTRY/MENUTITLE"> + <xsl:apply-templates/> +</xsl:template> + +<xsl:template match="//MENU/MENUENTRY/MENUCOMMENT"> + <xsl:apply-templates mode="menucomment"/> +</xsl:template> + +<xsl:template match="PARA" mode="menucomment"> + <xsl:apply-templates/> +</xsl:template> + +<xsl:template match="//PARA"> + <p><xsl:apply-templates/></p> +</xsl:template> + +<!-- LISTS --> +<xsl:template match="//ITEMIZE"> + <ul> + <xsl:apply-templates/> + </ul> +</xsl:template> + +<xsl:template match="//ITEMIZE/ITEM"> + <li> + <xsl:apply-templates/> + </li> +</xsl:template> + +<xsl:template match="//ENUMERATE"> + <ol> + <xsl:apply-templates/> + </ol> +</xsl:template> + +<xsl:template match="//ENUMERATE/ITEM"> + <li> + <xsl:apply-templates/> + </li> +</xsl:template> + +<!-- INLINE --> +<xsl:template match="//CODE"> + <tt> + <xsl:apply-templates/> + </tt> +</xsl:template> + +<xsl:template match="//DFN"> + <i><b> + <xsl:apply-templates/> + </b></i> +</xsl:template> + +<xsl:template match="//STRONG"> + <b> + <xsl:apply-templates/> + </b> +</xsl:template> + +<xsl:template match="//CENTER"> + <center> + <xsl:apply-templates/> + </center> +</xsl:template> + +<xsl:template match="//VAR"> + <i> + <xsl:apply-templates/> + </i> +</xsl:template> + +<xsl:template match="//KBD"> + <tt> + <xsl:apply-templates/> + </tt> +</xsl:template> + +<xsl:template match="//KEY"> + <b> + <xsl:apply-templates/> + </b> +</xsl:template> + +<!-- BLOCKS --> +<xsl:template match="//DISPLAY"> + <pre> + <xsl:apply-templates/> + </pre> +</xsl:template> + + +<!-- INDEX --> +<xsl:template match="//INDEXTERM"> +</xsl:template> + +<!-- FOOTNOTE --> +<xsl:template match="//FOOTNOTE"> +</xsl:template> + +<xsl:template match="//FOOTNOTE" mode="footnote"> + <li><xsl:apply-templates/></li> +</xsl:template> + +</xsl:stylesheet> + diff --git a/contrib/texinfo/makeinfo/toc.c b/contrib/texinfo/makeinfo/toc.c index 41c5ffb8edcf..0340f4a9f69f 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.14 1999/08/09 20:28:18 karl Exp $ + $Id: toc.c,v 1.21 2002/02/23 19:12:15 karl Exp $ - Copyright (C) 1999 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 01, 02 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 @@ #include "files.h" #include "macro.h" #include "node.h" +#include "html.h" #include "lang.h" #include "makeinfo.h" #include "sectioning.h" @@ -32,7 +33,6 @@ - /* array of toc entries */ static TOC_ENTRY_ELT **toc_entry_alist = NULL; @@ -60,6 +60,7 @@ toc_add_entry (tocname, level, node_name, anchor) char *anchor; { char *tocname_and_node, *expanded_node, *s, *d; + char *filename = NULL; if (!node_name) node_name = ""; @@ -74,52 +75,59 @@ toc_add_entry (tocname, level, node_name, anchor) if (html) { /* We need to insert the expanded node name into the TOC, so - that when we eventually output the TOC, its <A REF= link will - point to the <A NAME= tag created by cm_node in the navigation - bar. We cannot expand the containing_node member, for the - reasons explained in the WARNING below. We also cannot wait - with the node name expansion until the TOC is actually output, - since by that time the macro definitions may have been changed. - So instead we store in the tocname member the expanded node - name and the TOC name concatenated together (with the necessary - HTML markup), since that's how they are output. */ + that when we eventually output the TOC, its <A REF= link will + point to the <A NAME= tag created by cm_node in the navigation + bar. We cannot expand the containing_node member, for the + reasons explained in the WARNING below. We also cannot wait + with the node name expansion until the TOC is actually output, + since by that time the macro definitions may have been changed. + So instead we store in the tocname member the expanded node + name and the TOC name concatenated together (with the necessary + HTML markup), since that's how they are output. */ if (!anchor) - s = expanded_node = expand_node_name (node_name); + s = expanded_node = expand_node_name (node_name); else - expanded_node = anchor; + expanded_node = anchor; + if (splitting) + { + if (!anchor) + filename = nodename_to_filename (expanded_node); + else + filename = filename_part (current_output_filename); + } /* Sigh... Need to HTML-escape the expanded node name like - add_anchor_name does, except that we are not writing this to - the output, so can't use add_anchor_name... */ + add_anchor_name does, except that we are not writing this to + the output, so can't use add_anchor_name... */ /* The factor 5 in the next allocation is because the maximum - expansion of HTML-escaping is for the & character, which is - output as "&". 2 is for "> that separates node from tocname. */ + expansion of HTML-escaping is for the & character, which is + output as "&". 2 is for "> that separates node from tocname. */ d = tocname_and_node = (char *)xmalloc (2 + 5 * strlen (expanded_node) - + strlen (tocname) + 1); + + strlen (tocname) + 1); if (!anchor) - { - for (; *s; s++) - { - if (*s == '&') - { - strcpy (d, "&"); - d += 5; - } - else if (! URL_SAFE_CHAR (*s)) - { - sprintf (d, "%%%x", (unsigned char) *s); - /* do this manually since sprintf returns char * on - SunOS 4 and other old systems. */ - while (*d) - d++; - } - else - *d++ = *s; - } - strcpy (d, "\">"); - } + { + for (; *s; s++) + { + if (*s == '&') + { + strcpy (d, "&"); + d += 5; + } + else if (! URL_SAFE_CHAR (*s)) + { + sprintf (d, "%%%x", (unsigned char) *s); + /* do this manually since sprintf returns char * on + SunOS 4 and other old systems. */ + while (*d) + d++; + } + else + *d++ = *s; + } + strcpy (d, "\">"); + } else - /* Section outside any node, they provided explicit anchor. */ - strcpy (d, anchor); + /* Section outside any node, they provided explicit anchor. */ + strcpy (d, anchor); strcat (d, tocname); free (tocname); /* it was malloc'ed by substring() */ free (expanded_node); @@ -137,6 +145,7 @@ toc_add_entry (tocname, level, node_name, anchor) toc_entry_alist[toc_counter]->containing_node = xstrdup (node_name); toc_entry_alist[toc_counter]->level = level; toc_entry_alist[toc_counter]->number = toc_counter; + toc_entry_alist[toc_counter]->html_file = filename; /* have to be done at least */ return toc_counter++; @@ -192,8 +201,8 @@ toc_free () } -/* print table of contents in HTML, may be we can produce a standalone - HTML file? */ +/* Print table of contents in HTML. */ + static void contents_update_html (fp) FILE *fp; @@ -209,10 +218,10 @@ contents_update_html (fp) flush_output (); /* in case we are writing stdout */ - fprintf (fp, "\n<h1>%s</h1>\n<ul>\n", _("Table of Contents")); + fprintf (fp, "\n<h2>%s</h2>\n<ul>\n", _("Table of Contents")); last_level = toc_entry_alist[0]->level; - + for (i = 0; i < toc_counter; i++) { if (toc_entry_alist[i]->level > last_level) @@ -231,7 +240,35 @@ contents_update_html (fp) fputs ("</ul>\n", fp); } - fprintf (fp, "<li><a href=\"#%s</a>\n", toc_entry_alist[i]->name); + /* No double entries in TOC. */ + if (!(i && strcmp (toc_entry_alist[i]->name, + toc_entry_alist[i-1]->name) == 0)) + { + /* each toc entry is a list item. */ + fputs ("<li>", fp); + + /* For chapters (only), insert an anchor that the short contents + will link to. */ + if (toc_entry_alist[i]->level == 0) + { + char *p = toc_entry_alist[i]->name; + + /* toc_entry_alist[i]->name has the form `foo">bar', + that is, it includes both the node name and anchor + text. We need to find where `foo', the node name, + ends, and use that in toc_FOO. */ + while (*p && *p != '"') + p++; + fprintf (fp, "<a name=\"toc_%.*s\"></a>\n ", + p - toc_entry_alist[i]->name, toc_entry_alist[i]->name); + } + + /* Insert link -- to an external file if splitting, or + within the current document if not splitting. */ + fprintf (fp, "<a href=\"%s#%s</a>\n", + splitting ? toc_entry_alist[i]->html_file : "", + toc_entry_alist[i]->name); + } last_level = toc_entry_alist[i]->level; } @@ -282,29 +319,39 @@ shortcontents_update_html (fp) FILE *fp; { int i; + char *toc_file; /* does exist any toc? */ if (!toc_counter) return; - + flush_output (); /* in case we are writing stdout */ - fprintf (fp, "\n<h1>%s</h1>\n<ul>\n", _("Short Contents")); + fprintf (fp, "\n<h2>%s</h2>\n<ul>\n", _("Short Contents")); + + if (contents_filename) + toc_file = filename_part (contents_filename); for (i = 0; i < toc_counter; i++) { - if ((toc_entry_alist[i])->level == 0) - { - fputs ("<li>", fp); - fprintf (fp, "<a href=\"#%s\n", toc_entry_alist[i]->name); - } - } + char *name = toc_entry_alist[i]->name; + if (toc_entry_alist[i]->level == 0) + { + if (contents_filename) + fprintf (fp, "<li><a href=\"%s#toc_%s</a>\n", + splitting ? toc_file : "", name); + else + fprintf (fp, "<a href=\"%s#%s</a>\n", + splitting ? toc_entry_alist[i]->html_file : "", name); + } + } fputs ("</ul>\n\n", fp); + if (contents_filename) + free (toc_file); } -/* short contents in ASCII (--no-headers). - May be we should create a new command line switch --ascii ? */ +/* short contents in ASCII (--no-headers). */ static void shortcontents_update_info (fp) FILE *fp; @@ -321,7 +368,7 @@ shortcontents_update_info (fp) for (i = 0; i < toc_counter; i++) { - if ((toc_entry_alist[i])->level == 0) + if (toc_entry_alist[i]->level == 0) fprintf (fp, "%s\n", toc_entry_alist[i]->name); } fputs ("\n\n", fp); @@ -337,13 +384,18 @@ rewrite_top (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) { - /* Can't rewrite standard output. No point in complaining. */ - if (!STREQ (fname, "-")) - fs_error (fname); + fs_error (fname); return -1; } @@ -442,6 +494,8 @@ cm_contents (arg) } else { + if (!executing_string && html) + html_output_head (); contents_filename = xstrdup (current_output_filename); insert_string (contents_placebo); /* just mark it, for now */ } @@ -469,6 +523,8 @@ cm_shortcontents (arg) } else { + if (!executing_string && html) + html_output_head (); shortcontents_filename = xstrdup (current_output_filename); insert_string (shortcontents_placebo); /* just mark it, for now */ } diff --git a/contrib/texinfo/makeinfo/toc.h b/contrib/texinfo/makeinfo/toc.h index a37faf78730d..654a768feaf1 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.4 1999/04/25 19:49:22 karl Exp $ + $Id: toc.h,v 1.5 2002/02/09 00:54:51 karl Exp $ Copyright (C) 1999 Free Software Foundation, Inc. @@ -32,6 +32,7 @@ extern char *shortcontents_filename; typedef struct toc_entry_elt { char *name; char *containing_node; /* Name of node containing this section. */ + char *html_file; /* Name of HTML node-file in split-HTML mode */ int number; /* counting number from 0...n independent from chapter/section can be used for anchors or references to it. */ diff --git a/contrib/texinfo/makeinfo/xml.c b/contrib/texinfo/makeinfo/xml.c new file mode 100644 index 000000000000..813b5b6b338e --- /dev/null +++ b/contrib/texinfo/makeinfo/xml.c @@ -0,0 +1,1428 @@ +/* xml.c -- xml output. + $Id: xml.c,v 1.7 2002/01/16 15:52:45 karl Exp $ + + Copyright (C) 2001, 02 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 Philippe Martin <feloy@free.fr>. */ + +#include "system.h" +#include "makeinfo.h" +#include "insertion.h" +#include "macro.h" +#include "cmds.h" +#include "lang.h" + +#include "xml.h" + +/* 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; +} 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", 1, 0 }, + { "example", 1, 0 }, + { "smallexample", 1, 0 }, + { "lisp", 1, 0 }, + { "smalllisp", 1, 0 }, + { "cartouche", 1, 0 }, + { "format", 1, 0 }, + { "smallformat", 1, 0 }, + { "display", 1, 0 }, + { "smalldisplay", 1, 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) */ + { "para", 0, 0 } /* Must be last */ + /* name / contains para / contained in para */ +}; + +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 */ + { "sect3", 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 */ + { "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 }, + { "orderedlist", 0, 0 }, /* ENUMERATE */ + { "variablelist", 0, 0 }, /* TABLE */ + { "varlistentry", 0, 0 }, /* TABLEITEM */ + { "term", 0, 0 }, /* TABLETERM */ + + { "indexterm", 0, 1 }, + + { "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, 0 }, /* 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 }, + + { "para", 0, 0 } /* Must be last */ + /* name / contains para / contained in para */ +}; + +element *xml_element_list = NULL; + + +typedef struct _replace_element +{ + int element_to_replace; + int element_containing; + int element_replacing; +} replace_element; + +/* Elements to replace - Docbook only + ------------------- + if `element_to_replace' have to be inserted + as a child of `element_containing,' + use `element_replacing' instead. + + A value of `-1' for element_replacing means `do not use any element.' +*/ + +replace_element replace_elements [] = { + { I, TABLETERM, EMPH }, + { B, TABLETERM, EMPH }, + { TT, CODE, -1 }, + { EXAMPLE, DISPLAY, -1 }, + { CODE, DFN, -1 }, + { CODE, VAR, -1 }, + { EMPH, CODE, REPLACEABLE }, + /* Add your elements to replace here */ + {-1, 0, 0} +}; + +int xml_in_menu_entry = 0; +int xml_in_menu_entry_comment = 0; +int xml_node_open = 0; +int xml_node_level = -1; +int xml_in_para = 0; +int xml_just_after_element = 0; + +int xml_no_para = 0; +char *xml_node_id = NULL; +int xml_sort_index = 0; + +static int xml_after_table_term = 0; +static int book_started = 0; +static int first_section_opened = 0; +static int in_abstract = 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; +{ + char *tem = xmalloc (strlen (id) + 1); + char *p = tem; + strcpy (tem, id); + while (*p++) + { + if (*p == ' ' || *p == '&' || *p == '/' || *p == '+') + *p = '-'; + } + p = tem; + while (*p == '-') + *p = 'i'; + return tem; +} + +int +xml_element (name) + char *name; +{ + int i; + for (i=0; i<=PARA; i++) + { + if (strcasecmp (name, texinfoml_element_list[i].name) == 0) + return i; + } + printf ("Error xml_element\n"); + return -1; +} + +void +xml_begin_document (output_filename) + char *output_filename; +{ + if (book_started) + return; + + book_started = 1; + if (docbook) + { + insert_string ("<!DOCTYPE Book PUBLIC \"-//OASIS//DTD DocBook V3.1//EN\">"); + xml_element_list = docbook_element_list; + } + else + { + insert_string ("<!DOCTYPE texinfo SYSTEM \"texinfo.dtd\">"); + xml_element_list = texinfoml_element_list; + } + if (docbook) + { + if (language_code != last_language_code) + xml_insert_element_with_attribute (TEXINFO, START, "lang=\"%s\"", language_table[language_code].abbrev); + } + else + xml_insert_element (TEXINFO, START); + if (!docbook) + { + xml_insert_element (SETFILENAME, START); + insert_string (output_filename); + xml_insert_element (SETFILENAME, END); + } +} + +/* */ +static int element_stack[256]; +static int element_stack_index = 0; + +static void +xml_push_current_element (elt) + int elt; +{ + element_stack[element_stack_index++] = elt; + if (element_stack_index > 200) + printf ("*** stack overflow (%d - %s) ***\n", + element_stack_index, + xml_element_list[elt].name); +} + +void +xml_pop_current_element () +{ + element_stack_index--; + if (element_stack_index < 0) + printf ("*** stack underflow (%d - %d) ***\n", + element_stack_index, + xml_current_element()); +} + +static int +xml_current_element () +{ + return element_stack[element_stack_index-1]; +} + +static void +xml_indent () +{ + int i; + insert ('\n'); + for (i = 0; i < element_stack_index; i++) + insert (' '); +} + +static void +xml_indent_end_para () +{ + int i; + for (i = 0; i < element_stack_index; i++) + insert (' '); +} + +void +xml_end_document () +{ + if (xml_node_open) + { + if (xml_node_level != -1) + { + xml_close_sections (xml_node_level); + xml_node_level = -1; + } + xml_insert_element (NODE, END); + } + xml_insert_element (TEXINFO, END); + insert_string ("\n"); + insert_string ("<!-- Keep this comment at the end of the file\n\ +Local variables:\n\ +mode: sgml\n\ +sgml-indent-step:1\n\ +sgml-indent-data:nil\n\ +End:\n\ +-->\n"); + if (element_stack_index != 0) + error ("Element stack index : %d\n", element_stack_index); +} + +/* MUST be 0 or 1, not true or false values */ +static int start_element_inserted = 1; + +/* NOTE: We use `elt' rather than `element' in the argument list of + the next function, since otherwise the Solaris SUNWspro compiler + barfs because `element' is a typedef declared near the beginning of + this file. */ +void +#if defined (VA_FPRINTF) && __STDC__ +xml_insert_element_with_attribute (int elt, int arg, char *format, ...) +#else +xml_insert_element_with_attribute (elt, arg, format, va_alist) + int elt; + int arg; + char *format; + va_dcl +#endif +{ + /* Look at the replace_elements table to see if we have to change the element */ + if (xml_sort_index) + return; + if (docbook) + { + replace_element *element_list = replace_elements; + while (element_list->element_to_replace >= 0) + { + if ( ( (arg == START) && + (element_list->element_containing == xml_current_element ()) && + (element_list->element_to_replace == elt) ) || + ( (arg == END) && + (element_list->element_containing == element_stack[element_stack_index-1-start_element_inserted]) && + (element_list->element_to_replace == elt) ) ) + { + elt = element_list->element_replacing; + break; + } + element_list ++; + } + + /* Forget the element */ + if (elt < 0) + { + if (arg == START) + start_element_inserted = 0; + else + /* Replace the default value, for the next time */ + start_element_inserted = 1; + return; + } + } + + if (!book_started) + return; + + if (xml_after_table_term && elt != TABLETERM) + { + xml_after_table_term = 0; + xml_insert_element (ITEM, START); + } + + if (docbook && !only_macro_expansion && (in_menu || in_detailmenu)) + return; + + if (!xml_element_list[elt].name || !strlen (xml_element_list[elt].name)) + { + /* 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_element_list[xml_current_element()].contains_para ) + { + xml_indent (); + insert_string ("<para>"); + xml_in_para = 1; + } + + + if (arg == START && xml_in_para && !xml_element_list[elt].contained_in_para) + { + xml_indent_end_para (); + insert_string ("</para>"); + xml_in_para = 0; + } + + 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 (); + + if (arg == START) + xml_push_current_element (elt); + else + xml_pop_current_element (); + + insert ('<'); + if (arg == END) + insert ('/'); + insert_string (xml_element_list[elt].name); + + /* printf ("%s ", xml_element_list[elt].name);*/ + + if (format) + { + char temp_string[2000]; /* xx no fixed limits */ +#ifdef VA_SPRINTF + va_list ap; +#endif + + VA_START (ap, format); +#ifdef VA_SPRINTF + VA_SPRINTF (temp_string, format, ap); +#else + sprintf (temp_string, format, a1, a2, a3, a4, a5, a6, a7, a8); +#endif + insert (' '); + insert_string (temp_string); + va_end (ap); + } + + if (arg == START && xml_node_id && elt != NODENAME) + { + insert_string (" id=\""); + insert_string (xml_node_id); + insert_string ("\""); + free (xml_node_id); + xml_node_id = NULL; + } + + insert ('>'); + + xml_just_after_element = 1; +} + +/* See the NOTE before xml_insert_element_with_attribute, for why we + use `elt' rather than `element' here. */ +void +xml_insert_element (int elt, int arg) +{ + xml_insert_element_with_attribute (elt, arg, NULL); +} + +void +xml_insert_entity (char *entity_name) +{ + int saved_escape_html = escape_html; + + if (!book_started) + return; + if (docbook && !only_macro_expansion && (in_menu || in_detailmenu)) + return; + + if (!xml_in_para && !xml_no_para && !only_macro_expansion + && xml_element_list[xml_current_element ()].contains_para) + { + insert_string ("<para>"); + xml_in_para = 1; + } + escape_html = 0; + insert ('&'); + escape_html = saved_escape_html; + insert_string (entity_name); + insert (';'); +} + +typedef struct _xml_section xml_section; +struct _xml_section { + int level; + char *name; + xml_section *prev; +}; + +xml_section *last_section = NULL; + +void +xml_begin_node () +{ + if (xml_node_open && ! docbook) + { + if (xml_node_level != -1) + { + xml_close_sections (xml_node_level); + xml_node_level = -1; + } + xml_insert_element (NODE, END); + } + xml_insert_element (NODE, START); + xml_node_open = 1; +} + +void +xml_close_sections (level) + int level; +{ + if (!first_section_opened && in_abstract) + { + xml_insert_element (ABSTRACT, END); + xml_insert_element (BOOKINFO, END); + first_section_opened = 1; + } + while (last_section && last_section->level >= level) + { + xml_section *temp = last_section; + xml_insert_element (xml_element(last_section->name), END); + temp = last_section; + last_section = last_section->prev; + free (temp->name); + free (temp); + } +} + +void +xml_open_section (level, name) + int level; + char *name; +{ + xml_section *sect = (xml_section *) xmalloc (sizeof (xml_section)); + + sect->level = level; + sect->name = xmalloc (1 + strlen (name)); + strcpy (sect->name, name); + sect->prev = last_section; + last_section = sect; + + if (xml_node_open && xml_node_level == -1) + xml_node_level = level; +} + +void +xml_start_menu_entry (tem) + char *tem; +{ + char *string; + discard_until ("* "); + + /* The line number was already incremented in reader_loop when we + saw the newline, and discard_until has now incremented again. */ + line_number--; + + if (xml_in_menu_entry) + { + 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 (MENUENTRY, START); + xml_in_menu_entry=1; + + xml_insert_element (MENUNODE, START); + string = expansion (tem, 0); + add_word (string); + xml_insert_element (MENUNODE, END); + free (string); + + /* The menu item may use macros, so expand them now. */ + xml_insert_element (MENUTITLE, START); + only_macro_expansion++; + get_until_in_line (1, ":", &string); + only_macro_expansion--; + execute_string ("%s", string); /* get escaping done */ + xml_insert_element (MENUTITLE, END); + free (string); + + if (looking_at ("::")) + discard_until (":"); + else + { /* discard the node name */ + get_until_in_line (0, ".", &string); + free (string); + } + input_text_offset++; /* discard the second colon or the period */ + xml_insert_element (MENUCOMMENT, START); + xml_in_menu_entry_comment ++; +} + +void +xml_end_menu () +{ + if (xml_in_menu_entry) + { + if (xml_in_menu_entry_comment) + { + xml_insert_element (MENUCOMMENT, END); + xml_in_menu_entry_comment --; + } + xml_insert_element (MENUENTRY, END); + xml_in_menu_entry--; + } + xml_insert_element (MENU, END); +} + +static int xml_last_character; + +void +xml_add_char (character) + int character; +{ + if (!book_started) + return; + if (docbook && !only_macro_expansion && (in_menu || in_detailmenu)) + return; + + if (!first_section_opened && !in_abstract && xml_current_element () == TEXINFO + && !xml_no_para && character != '\r' && character != '\n' && character != ' ') + { + xml_insert_element (BOOKINFO, START); + xml_insert_element (ABSTRACT, START); + in_abstract = 1; + } + + if (xml_after_table_term && !xml_sort_index) + { + xml_after_table_term = 0; + xml_insert_element (ITEM, START); + } + + if (xml_just_after_element && !xml_in_para && !inhibit_paragraph_indentation) + { + if (character == '\r' || character == '\n' || character == '\t' || character == ' ') + return; + xml_just_after_element = 0; + } + + if (xml_element_list[xml_current_element()].contains_para + && !xml_in_para && !only_macro_expansion && !xml_no_para) + { + xml_indent (); + insert_string ("<para>\n"); + xml_in_para = 1; + } + + if (xml_in_para) + { + 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; + } + } + } + } + + if (character == '\n' && !xml_in_para && !inhibit_paragraph_indentation) + return; + + xml_last_character = character; + + if (character == '&' && escape_html) + insert_string ("&"); + else if (character == '<' && escape_html) + insert_string ("<"); + else + insert (character); + + return; +} + +void +xml_insert_footnote (note) + char *note; +{ + xml_insert_element (FOOTNOTE, START); + insert_string ("<para>"); + execute_string ("%s", note); + insert_string ("</para>"); + xml_insert_element (FOOTNOTE, END); +} + + +/* + * Lists and Tables + */ +static int xml_in_item[256]; +static int xml_table_level = 0; + +void +xml_begin_table (type, item_function) + enum insertion_type type; + char *item_function; +{ + switch (type) + { + case ftable: + case vtable: + case table: + /*if (docbook)*/ /* 05-08 */ + { + xml_insert_element (TABLE, START); + xml_table_level ++; + xml_in_item[xml_table_level] = 0; + } + break; + case itemize: + if (!docbook) + { + xml_insert_element (ITEMIZE, START); + xml_table_level ++; + xml_in_item[xml_table_level] = 0; + xml_insert_element (ITEMFUNCTION, START); + if (*item_function == COMMAND_PREFIX + && item_function[strlen (item_function) - 1] != '}' + && command_needs_braces (item_function + 1)) + execute_string ("%s{}", item_function); + else + execute_string ("%s", item_function); + xml_insert_element (ITEMFUNCTION, END); + } + else + { + xml_insert_element_with_attribute (ITEMIZE, START, + "mark=\"%s\"", + (*item_function == COMMAND_PREFIX) ? + &item_function[1] : item_function); + xml_table_level ++; + xml_in_item[xml_table_level] = 0; + } + break; + } +} + +void +xml_end_table (type) + enum insertion_type type; +{ + switch (type) + { + case ftable: + case vtable: + case table: + /* if (docbook)*/ /* 05-08 */ + { + 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 --; + } + break; + case itemize: + if (xml_in_item[xml_table_level]) + { + xml_insert_element (ITEM, END); + xml_in_item[xml_table_level] = 0; + } + xml_insert_element (ITEMIZE, END); + xml_table_level --; + break; + } +} + +void +xml_begin_item () +{ + if (xml_in_item[xml_table_level]) + xml_insert_element (ITEM, END); + + xml_insert_element (ITEM, START); + xml_in_item[xml_table_level] = 1; +} + +void +xml_begin_table_item () +{ + 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 (TABLEITEM, START); + } + xml_insert_element (TABLETERM, START); + xml_in_item[xml_table_level] = 1; + xml_after_table_term = 0; +} + +void +xml_continue_table_item () +{ + xml_insert_element (TABLETERM, END); + xml_after_table_term = 1; +} + +void +xml_begin_enumerate (enum_arg) + 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); + } + 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); + } + 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_table_level ++; + xml_in_item[xml_table_level] = 0; +} + +void +xml_end_enumerate () +{ + if (xml_in_item[xml_table_level]) + { + xml_insert_element (ITEM, END); + xml_in_item[xml_table_level] = 0; + } + xml_insert_element (ENUMERATE, END); + xml_table_level --; +} + +static void +xml_insert_text_file (name_arg) + char *name_arg; +{ + char *fullname = xmalloc (strlen (name_arg) + 4 + 1); + FILE *image_file; + strcpy (fullname, name_arg); + strcat (fullname, ".txt"); + image_file = fopen (fullname, "r"); + if (image_file) + { + int ch; + int save_inhibit_indentation = inhibit_paragraph_indentation; + int save_filling_enabled = filling_enabled; + + xml_insert_element (TEXTOBJECT, START); + xml_insert_element (DISPLAY, START); + + inhibit_paragraph_indentation = 1; + filling_enabled = 0; + last_char_was_newline = 0; + + /* 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) + add_char (ch); + + inhibit_paragraph_indentation = save_inhibit_indentation; + filling_enabled = save_filling_enabled; + + xml_insert_element (DISPLAY, END); + xml_insert_element (TEXTOBJECT, END); + + if (fclose (image_file) != 0) + perror (fullname); + } + else + warning (_("@image file `%s' unreadable: %s"), fullname, + strerror (errno)); + + free (fullname); +} + +void +xml_insert_docbook_image (name_arg) + char *name_arg; +{ + xml_insert_element (INFORMALFIGURE, START); + xml_insert_element (MEDIAOBJECT, START); + + 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); + + 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); + + xml_insert_text_file (name_arg); + + xml_insert_element (MEDIAOBJECT, END); + xml_insert_element (INFORMALFIGURE, END); +} + +void +xml_asterisk () +{ +} + + +/* + * INDEX + */ +/* Used to separate primary and secondary entries in an index */ +#define INDEX_SEP ", " + +xml_insert_indexterm (indexterm, index) + char *indexterm; + char *index; +{ + if (!docbook) + { + xml_insert_element_with_attribute (INDEXTERM, START, "index=\"%s\"", index); + execute_string ("%s", indexterm); + xml_insert_element (INDEXTERM, END); + } + else + { + char *expanded; + char *primary = NULL, *secondary; + xml_sort_index = 1; + xml_no_para = 1; + expanded = expansion (indexterm); + xml_sort_index = 0; + xml_no_para = 0; + if (strstr (expanded+1, INDEX_SEP)) + { + primary = xmalloc (strlen (expanded) + 1); + strcpy (primary, expanded); + secondary = strstr (primary+1, INDEX_SEP); + *secondary = '\0'; + secondary += strlen (INDEX_SEP); + } + xml_insert_element_with_attribute (INDEXTERM, START, "role=\"%s\"", index); + xml_insert_element (PRIMARY, START); + if (primary) + insert_string (primary); + else + insert_string (expanded); + xml_insert_element (PRIMARY, END); + if (primary) + { + xml_insert_element (SECONDARY, START); + insert_string (secondary); + xml_insert_element (SECONDARY, END); + } + xml_insert_element (INDEXTERM, END); + free (expanded); + } +} + + +int xml_last_section_output_position = 0; +static char last_division_letter = ' '; +static char index_primary[2000]; /** xx no fixed limit */ +static int indexdivempty = 0; + +static int in_indexentry = 0; +static int in_secondary = 0; +static void +xml_close_indexentry () +{ + if (!in_indexentry) + return; + if (in_secondary) + xml_insert_element (SECONDARYIE, END); + xml_insert_element (INDEXENTRY, END); + in_secondary = 0; + in_indexentry = 0; +} + +void +xml_begin_index () +{ + /* + 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 */ + + last_section = last_section->prev; /* remove section from sections stack */ + free (temp->name); + free (temp); + + /* We put <INDEX> */ + xml_insert_element (PRINTINDEX, START); + /* Remove the final > */ + output_paragraph_offset--; + + /* and put ID="node-name"><TITLE>Title</TITLE> */ + insert_string (p); + + if (xml_index_divisions) + { + xml_insert_element (INDEXDIV, START); + indexdivempty = 1; + } +} + +void +xml_end_index () +{ + xml_close_indexentry (); + if (xml_index_divisions) + xml_insert_element (INDEXDIV, END); + xml_insert_element (PRINTINDEX, END); +} + +void +xml_index_divide (entry) + char *entry; +{ + char c; + if (strlen (entry) > (strlen (xml_element_list[CODE].name) + 2) && + strncmp (entry+1, xml_element_list[CODE].name, strlen (xml_element_list[CODE].name)) == 0) + c = entry[strlen (xml_element_list[CODE].name)+2]; + else + c = entry[0]; + if (tolower (c) != last_division_letter && isalpha (c)) + { + last_division_letter = tolower (c); + xml_close_indexentry (); + if (!indexdivempty) + { + xml_insert_element (INDEXDIV, END); + xml_insert_element (INDEXDIV, START); + } + xml_insert_element (TITLE, START); + insert (toupper (c)); + xml_insert_element (TITLE, END); + } +} + +void +xml_insert_indexentry (entry, node) + char *entry; + char *node; +{ + char *primary = NULL, *secondary; + if (xml_index_divisions) + xml_index_divide (entry); + + indexdivempty = 0; + if (strstr (entry+1, INDEX_SEP)) + { + primary = xmalloc (strlen (entry) + 1); + strcpy (primary, entry); + secondary = strstr (primary+1, INDEX_SEP); + *secondary = '\0'; + secondary += strlen (INDEX_SEP); + + if (in_secondary && strcmp (primary, index_primary) == 0) + { + xml_insert_element (SECONDARYIE, END); + xml_insert_element (SECONDARYIE, START); + insert_string (secondary); + } + else + { + xml_close_indexentry (); + xml_insert_element (INDEXENTRY, START); + in_indexentry = 1; + xml_insert_element (PRIMARYIE, START); + insert_string (primary); + xml_insert_element (PRIMARYIE, END); + xml_insert_element (SECONDARYIE, START); + insert_string (secondary); + in_secondary = 1; + } + } + else + { + xml_close_indexentry (); + xml_insert_element (INDEXENTRY, START); + in_indexentry = 1; + xml_insert_element (PRIMARYIE, START); + insert_string (entry); + } + add_word_args (", %s", _("see ")); + xml_insert_element_with_attribute (XREF, START, "linkend=\"%s\"", xml_id (node)); + xml_pop_current_element (); + + if (primary) + { + strcpy (index_primary, primary); + /* xml_insert_element (SECONDARYIE, END);*/ + /* *(secondary-1) = ',';*/ /* necessary ? */ + free (primary); + } + else + xml_insert_element (PRIMARYIE, END); + + /* xml_insert_element (INDEXENTRY, END); */ +} + +/* + * MULTITABLE + */ +void +xml_begin_multitable (ncolumns, column_widths) + 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); + xml_no_para = 1; + } + else + { + xml_insert_element (MULTITABLE, START); + for (i=0; i<ncolumns; i++) + { + xml_insert_element (COLSPEC, START); + add_word_args ("%d", column_widths[i]); + xml_insert_element (COLSPEC, END); + } + xml_no_para = 1; + } +} + +void +xml_end_multitable_row (first_row) + int first_row; +{ + if (!first_row) + { + xml_insert_element (ENTRY, END); + xml_insert_element (ROW, END); + } + xml_insert_element (ROW, START); + xml_insert_element (ENTRY, START); +} + +void +xml_end_multitable_column () +{ + xml_insert_element (ENTRY, END); + xml_insert_element (ENTRY, START); +} + +void +xml_end_multitable () +{ + if (docbook) + { + 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; + } + else + { + xml_insert_element (ENTRY, END); + xml_insert_element (ROW, END); + xml_insert_element (MULTITABLE, END); + xml_no_para = 0; + } +} diff --git a/contrib/texinfo/makeinfo/xml.h b/contrib/texinfo/makeinfo/xml.h new file mode 100644 index 000000000000..c7886178a9bc --- /dev/null +++ b/contrib/texinfo/makeinfo/xml.h @@ -0,0 +1,76 @@ +/* xml.h -- xml output declarations. + $Id: xml.h,v 1.3 2001/05/01 16:29:29 karl Exp $ + + Copyright (C) 2001 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 Philippe Martin <feloy@free.fr>. */ + +#ifndef XML_H +#define XML_H + +/* Options. */ + +/* Separate index entries into divisions for each letters. */ +extern int xml_index_divisions; +extern int xml_sort_index; + +extern int xml_node_open; +extern int xml_no_para; +extern char *xml_node_id; +extern int xml_last_section_output_position; + +enum xml_element +{ + TEXINFO=0, SETFILENAME, TITLEFONT, SETTITLE, + /* Node */ + NODE /* 4 */, NODENEXT, NODEPREV, NODEUP, + /* Structuring */ + CHAPTER /* 8 */, SECTION, SUBSECTION, SUBSUBSECTION, + TOP /* 12 */, UNNUMBERED, UNNUMBEREDSEC, UNNUMBEREDSUBSEC, UNNUMBEREDSUBSUBSEC, + APPENDIX /* 17 */, APPENDIXSEC, APPENDIXSUBSEC, APPENDIXSUBSUBSEC, + MAJORHEADING /* 21 */, CHAPHEADING, HEADING, SUBHEADING, SUBSUBHEADING, + /* Menu */ + MENU /* 26 */, MENUENTRY, MENUTITLE, MENUCOMMENT, MENUNODE, NODENAME, + /* -- */ + ACRONYM/* 32 */, TT, CODE, KBD, URL, KEY, VAR, SC, DFN, EMPH, STRONG, CITE, NOTFIXEDWIDTH, I, B, R, + TITLE, + IFINFO, + SP, CENTER, + DIRCATEGORY, + QUOTATION, EXAMPLE, SMALLEXAMPLE, LISP, SMALLLISP, CARTOUCHE, FORMAT, SMALLFORMAT, DISPLAY, SMALLDISPLAY, + FOOTNOTE, + ITEMIZE, ITEMFUNCTION, ITEM, ENUMERATE, TABLE, TABLEITEM, TABLETERM, + INDEXTERM, + XREF, XREFNODENAME, XREFINFONAME, XREFPRINTEDDESC, XREFINFOFILE, XREFPRINTEDNAME, + INFOREF, INFOREFNODENAME, INFOREFREFNAME, INFOREFINFONAME, + UREF, UREFURL, UREFDESC, UREFREPLACEMENT, + EMAIL, EMAILADDRESS, EMAILNAME, + GROUP, + PRINTINDEX, + ANCHOR, + IMAGE, + PRIMARY, SECONDARY, INFORMALFIGURE, MEDIAOBJECT, IMAGEOBJECT, IMAGEDATA, TEXTOBJECT, + INDEXENTRY, PRIMARYIE, SECONDARYIE, INDEXDIV, + MULTITABLE, TGROUP, COLSPEC, TBODY, ENTRY, ROW, + BOOKINFO, ABSTRACT, REPLACEABLE, + PARA +}; + +extern void xml_insert_element (/* int name, int arg */); +extern char *xml_id (/* char *id */); + +#endif /* XML_H */ |