193139Sru/* xml.c -- xml output.
2146515Sru   $Id: xml.c,v 1.52 2004/12/19 17:02:23 karl Exp $
393139Sru
4146515Sru   Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
593139Sru
693139Sru   This program is free software; you can redistribute it and/or modify
793139Sru   it under the terms of the GNU General Public License as published by
893139Sru   the Free Software Foundation; either version 2, or (at your option)
993139Sru   any later version.
1093139Sru
1193139Sru   This program is distributed in the hope that it will be useful,
1293139Sru   but WITHOUT ANY WARRANTY; without even the implied warranty of
1393139Sru   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1493139Sru   GNU General Public License for more details.
1593139Sru
1693139Sru   You should have received a copy of the GNU General Public License
1793139Sru   along with this program; if not, write to the Free Software
1893139Sru   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1993139Sru
20114472Sru   Originally written by Philippe Martin <feloy@free.fr>.  */
2193139Sru
2293139Sru#include "system.h"
2393139Sru#include "makeinfo.h"
2493139Sru#include "insertion.h"
25146515Sru#include "files.h"
26146515Sru#include "float.h"
2793139Sru#include "macro.h"
2893139Sru#include "cmds.h"
2993139Sru#include "lang.h"
3093139Sru
3193139Sru#include "xml.h"
3293139Sru
3393139Sru/* Options */
3493139Sruint xml_index_divisions = 1;
3593139Sru
3693139Srutypedef struct _element
3793139Sru{
3893139Sru  char name[32];
3993139Sru  int contains_para;
4093139Sru  int contained_in_para;
41146515Sru  int keep_space;
4293139Sru} element;
4393139Sru
4493139Sruelement texinfoml_element_list [] = {
45146515Sru  { "texinfo",             1, 0, 0 },
46146515Sru  { "setfilename",         0, 0, 0 },
47146515Sru  { "titlefont",           0, 0, 0 },
48146515Sru  { "settitle",            0, 0, 0 },
49146515Sru  { "documentdescription", 1, 0, 0 },
5093139Sru
51146515Sru  { "node",                1, 0, 0 },
52146515Sru  { "nodenext",            0, 0, 0 },
53146515Sru  { "nodeprev",            0, 0, 0 },
54146515Sru  { "nodeup",              0, 0, 0 },
5593139Sru
56146515Sru  { "chapter",             1, 0, 0 },
57146515Sru  { "section",             1, 0, 0 },
58146515Sru  { "subsection",          1, 0, 0 },
59146515Sru  { "subsubsection",       1, 0, 0 },
6093139Sru
61146515Sru  { "top",                 1, 0, 0 },
62146515Sru  { "unnumbered",          1, 0, 0 },
63146515Sru  { "unnumberedsec",       1, 0, 0 },
64146515Sru  { "unnumberedsubsec",    1, 0, 0 },
65146515Sru  { "unnumberedsubsubsec", 1, 0, 0 },
6693139Sru
67146515Sru  { "appendix",            1, 0, 0 },
68146515Sru  { "appendixsec",         1, 0, 0 },
69146515Sru  { "appendixsubsec",      1, 0, 0 },
70146515Sru  { "appendixsubsubsec",   1, 0, 0 },
7193139Sru
72146515Sru  { "majorheading",        0, 0, 0 },
73146515Sru  { "chapheading",         0, 0, 0 },
74146515Sru  { "heading",             0, 0, 0 },
75146515Sru  { "subheading",          0, 0, 0 },
76146515Sru  { "subsubheading",       0, 0, 0 },
7793139Sru
78146515Sru  { "titlepage",           1, 0, 0 },
79146515Sru  { "author",              0, 0, 0 },
80146515Sru  { "booktitle",           0, 0, 0 },
81146515Sru  { "booksubtitle",        0, 0, 0 },
8293139Sru
83146515Sru  { "menu",                1, 0, 0 },
84146515Sru  { "detailmenu",          1, 0, 0 },
85146515Sru  { "menuentry",           0, 0, 0 },
86146515Sru  { "menutitle",           0, 0, 0 },
87146515Sru  { "menucomment",         0, 0, 0 },
88146515Sru  { "menunode",            0, 0, 0 },
89146515Sru  { "nodename",            0, 0, 0 },
9093139Sru
91146515Sru  { "acronym",             0, 1, 0 },
92146515Sru  { "acronymword",         0, 1, 0 },
93146515Sru  { "acronymdesc",         0, 1, 0 },
9493139Sru
95146515Sru  { "abbrev",              0, 1, 0 },
96146515Sru  { "abbrevword",          0, 1, 0 },
97146515Sru  { "abbrevdesc",          0, 1, 0 },
9893139Sru
99146515Sru  { "tt",                  0, 1, 0 },
100146515Sru  { "code",                0, 1, 0 },
101146515Sru  { "command",             0, 1, 0 },
102146515Sru  { "env",                 0, 1, 0 },
103146515Sru  { "file",                0, 1, 0 },
104146515Sru  { "option",              0, 1, 0 },
105146515Sru  { "samp",                0, 1, 0 },
106146515Sru  { "kbd",                 0, 1, 0 },
107146515Sru  { "url",                 0, 1, 0 },
108146515Sru  { "key",                 0, 1, 0 },
109146515Sru  { "var",                 0, 1, 0 },
110146515Sru  { "sc",                  0, 1, 0 },
111146515Sru  { "dfn",                 0, 1, 0 },
112146515Sru  { "emph",                0, 1, 0 },
113146515Sru  { "strong",              0, 1, 0 },
114146515Sru  { "cite",                0, 1, 0 },
115146515Sru  { "notfixedwidth",       0, 1, 0 },
116146515Sru  { "i",                   0, 1, 0 },
117146515Sru  { "b",                   0, 1, 0 },
118146515Sru  { "r",                   0, 1, 0 },
119146515Sru  { "slanted",             0, 1, 0 },
120146515Sru  { "sansserif",           0, 1, 0 },
12193139Sru
122146515Sru  { "exdent",              0, 0, 0 },
12393139Sru
124146515Sru  { "title",               0, 0, 0 },
125146515Sru  { "ifinfo",              1, 0, 0 },
126146515Sru  { "sp",                  0, 0, 0 },
127146515Sru  { "center",              1, 0, 0 },
128146515Sru  { "dircategory",         0, 0, 0 },
129146515Sru  { "quotation",           1, 0, 0 },
130146515Sru  { "example",             0, 0, 1 },
131146515Sru  { "smallexample",        0, 0, 1 },
132146515Sru  { "lisp",                0, 0, 1 },
133146515Sru  { "smalllisp",           0, 0, 1 },
134146515Sru  { "cartouche",           1, 0, 0 },
135146515Sru  { "copying",             1, 0, 0 },
136146515Sru  { "format",              0, 0, 1 },
137146515Sru  { "smallformat",         0, 0, 1 },
138146515Sru  { "display",             0, 0, 1 },
139146515Sru  { "smalldisplay",        0, 0, 1 },
140146515Sru  { "verbatim",            0, 0, 1 },
141146515Sru  { "footnote",            0, 1, 0 },
142146515Sru  { "",                    0, 1, 0 }, /* LINEANNOTATION (docbook) */
14393139Sru
144146515Sru  { "",                    1, 0, 0 }, /* TIP (docbook)       */
145146515Sru  { "",                    1, 0, 0 }, /* NOTE (docbook)      */
146146515Sru  { "",                    1, 0, 0 }, /* IMPORTANT (docbook) */
147146515Sru  { "",                    1, 0, 0 }, /* WARNING (docbook)   */
148146515Sru  { "",                    1, 0, 0 }, /* CAUTION (docbook)   */
14993139Sru
150146515Sru  { "itemize",             0, 0, 0 },
151146515Sru  { "itemfunction",        0, 0, 0 },
152146515Sru  { "item",                1, 0, 0 },
153146515Sru  { "enumerate",           0, 0, 0 },
154146515Sru  { "table",               0, 0, 0 },
155146515Sru  { "tableitem",           0, 0, 0 },
156146515Sru  { "tableterm",           0, 0, 0 },
15793139Sru
158146515Sru  { "indexterm",           0, 1, 0 },
159114472Sru
160146515Sru  { "math",                0, 1, 0 },
161114472Sru
162146515Sru  { "dmn",                 0, 1, 0 },
163146515Sru
164146515Sru  { "xref",                0, 1, 0 },
165146515Sru  { "xrefnodename",        0, 1, 0 },
166146515Sru  { "xrefinfoname",        0, 1, 0 },
167146515Sru  { "xrefprinteddesc",     0, 1, 0 },
168146515Sru  { "xrefinfofile",        0, 1, 0 },
169146515Sru  { "xrefprintedname",     0, 1, 0 },
170146515Sru
171146515Sru  { "inforef",             0, 1, 0 },
172146515Sru  { "inforefnodename",     0, 1, 0 },
173146515Sru  { "inforefrefname",      0, 1, 0 },
174146515Sru  { "inforefinfoname",     0, 1, 0 },
175146515Sru
176146515Sru  { "uref",                0, 1, 0 },
177146515Sru  { "urefurl",             0, 1, 0 },
178146515Sru  { "urefdesc",            0, 1, 0 },
179146515Sru  { "urefreplacement",     0, 1, 0 },
180146515Sru
181146515Sru  { "email",               0, 1, 0 },
182146515Sru  { "emailaddress",        0, 1, 0 },
183146515Sru  { "emailname",           0, 1, 0 },
184146515Sru
185146515Sru  { "group",               0, 0, 0 },
186146515Sru  { "float",               1, 0, 0 },
187146515Sru  { "floattype",           0, 0, 0 },
188146515Sru  { "floatpos",            0, 0, 0 },
189146515Sru  { "caption",             0, 0, 0 },
190146515Sru  { "shortcaption",        0, 0, 0 },
191146515Sru
192146515Sru  { "",                    0, 0, 0 }, /* TABLE (docbook) */
193146515Sru  { "",                    0, 0, 0 }, /* FIGURE (docbook) */
194146515Sru  { "",                    0, 0, 0 }, /* EXAMPLE (docbook) */
195146515Sru  { "",                    1, 0, 0 }, /* SIDEBAR (docbook) */
196146515Sru
197146515Sru  { "printindex",          0, 0, 0 },
198146515Sru  { "listoffloats",        0, 0, 0 },
199146515Sru  { "anchor",              0, 1, 0 },
200146515Sru
201146515Sru  { "image",               0, 0, 0 },
202146515Sru  { "inlineimage",         0, 1, 0 },
203146515Sru  { "alttext",             0, 1, 0 },
204146515Sru
205146515Sru  { "",                    0, 1, 0 }, /* PRIMARY (docbook) */
206146515Sru  { "",                    0, 1, 0 }, /* SECONDARY (docbook) */
207146515Sru  { "",                    0, 0, 0 }, /* INFORMALFIGURE (docbook) */
208146515Sru  { "",                    0, 0, 0 }, /* MEDIAOBJECT (docbook) */
209146515Sru  { "",                    0, 0, 0 }, /* IMAGEOBJECT (docbook) */
210146515Sru  { "",                    0, 0, 0 }, /* IMAGEDATA (docbook) */
211146515Sru  { "",                    0, 0, 0 }, /* TEXTOBJECT (docbook) */
212146515Sru  { "",                    0, 0, 0 }, /* INDEXENTRY (docbook) */
213146515Sru  { "",                    0, 0, 0 }, /* PRIMARYIE (docbook) */
214146515Sru  { "",                    0, 0, 0 }, /* SECONDARYIE (docbook) */
215146515Sru  { "",                    0, 0, 0 }, /* INDEXDIV (docbook) */
216146515Sru  { "multitable",          0, 0, 0 },
217146515Sru  { "",                    0, 0, 0 }, /* TGROUP (docbook) */
218146515Sru  { "columnfraction",      0, 0, 0 },
219146515Sru  { "thead",               0, 0, 0 },
220146515Sru  { "tbody",               0, 0, 0 },
221146515Sru  { "entry",               0, 0, 0 },
222146515Sru  { "row",                 0, 0, 0 },
223146515Sru  { "",                    0, 0, 0 }, /* BOOKINFO (docbook) */
224146515Sru  { "",                    0, 0, 0 }, /* ABSTRACT (docbook) */
225146515Sru  { "",                    0, 0, 0 }, /* REPLACEABLE (docbook) */
226146515Sru  { "",                    0, 0, 0 }, /* ENVAR (docbook) */
227146515Sru  { "",                    0, 0, 0 }, /* COMMENT (docbook) */
228146515Sru  { "",                    0, 0, 0 }, /* FUNCTION (docbook) */
229146515Sru  { "",                    0, 0, 0 }, /* LEGALNOTICE (docbook) */
230146515Sru
231146515Sru  { "contents",            0, 0, 0 },
232146515Sru  { "shortcontents",       0, 0, 0 },
233146515Sru  { "documentlanguage",    0, 0, 0 },
234146515Sru
235146515Sru  { "setvalue",            0, 0, 0 },
236146515Sru  { "clearvalue",          0, 0, 0 },
237146515Sru
238146515Sru  { "definition",          0, 0, 0 },
239146515Sru  { "definitionterm",      0, 0, 0 },
240146515Sru  { "definitionitem",      1, 0, 0 },
241146515Sru  { "defcategory",         0, 0, 0 },
242146515Sru  { "deffunction",         0, 0, 0 },
243146515Sru  { "defvariable",         0, 0, 0 },
244146515Sru  { "defparam",            0, 0, 0 },
245146515Sru  { "defdelimiter",        0, 0, 0 },
246146515Sru  { "deftype",             0, 0, 0 },
247146515Sru  { "defparamtype",        0, 0, 0 },
248146515Sru  { "defdatatype",         0, 0, 0 },
249146515Sru  { "defclass",            0, 0, 0 },
250146515Sru  { "defclassvar",         0, 0, 0 },
251146515Sru  { "defoperation",        0, 0, 0 },
252146515Sru
253146515Sru  { "para",                0, 0, 0 } /* Must be last */
254146515Sru  /* name / contains para / contained in para / preserve space */
25593139Sru};
25693139Sru
25793139Sruelement docbook_element_list [] = {
258146515Sru  { "book",                0, 0, 0 }, /* TEXINFO */
259146515Sru  { "",                    0, 0, 0 }, /* SETFILENAME */
260146515Sru  { "",                    0, 0, 0 }, /* TITLEINFO */
261146515Sru  { "title",               0, 0, 0 }, /* SETTITLE */
262146515Sru  { "",                    1, 0, 0 }, /* DOCUMENTDESCRIPTION (?) */
26393139Sru
264146515Sru  { "",                    1, 0, 0 }, /* NODE */
265146515Sru  { "",                    0, 0, 0 }, /* NODENEXT */
266146515Sru  { "",                    0, 0, 0 }, /* NODEPREV */
267146515Sru  { "",                    0, 0, 0 }, /* NODEUP */
26893139Sru
269146515Sru  { "chapter",             1, 0, 0 },
270146515Sru  { "sect1",               1, 0, 0 }, /* SECTION */
271146515Sru  { "sect2",               1, 0, 0 }, /* SUBSECTION */
272146515Sru  { "sect3",               1, 0, 0 }, /* SUBSUBSECTION */
27393139Sru
274146515Sru  { "chapter",             1, 0, 0 }, /* TOP */
275146515Sru  { "chapter",             1, 0, 0 }, /* UNNUMBERED */
276146515Sru  { "sect1",               1, 0, 0 }, /* UNNUMBEREDSEC */
277146515Sru  { "sect2",               1, 0, 0 }, /* UNNUMBEREDSUBSEC */
278146515Sru  { "sect3",               1, 0, 0 }, /* UNNUMBEREDSUBSUBSEC */
27993139Sru
280146515Sru  { "appendix",            1, 0, 0 },
281146515Sru  { "sect1",               1, 0, 0 }, /* APPENDIXSEC */
282146515Sru  { "sect2",               1, 0, 0 }, /* APPENDIXSUBSEC */
283146515Sru  { "sect3",               1, 0, 0 }, /* APPENDIXSUBSUBSEC */
28493139Sru
285146515Sru  { "bridgehead",          0, 0, 0 }, /* MAJORHEADING */
286146515Sru  { "bridgehead",          0, 0, 0 }, /* CHAPHEADING */
287146515Sru  { "bridgehead",          0, 0, 0 }, /* HEADING */
288146515Sru  { "bridgehead",          0, 0, 0 }, /* SUBHEADING */
289146515Sru  { "bridgehead",          0, 0, 0 }, /* SUBSUBHEADING */
29093139Sru
291146515Sru  { "",                    0, 0, 0 }, /* TITLEPAGE */
292146515Sru  { "",                    0, 0, 0 }, /* AUTHOR */
293146515Sru  { "",                    0, 0, 0 }, /* BOOKTITLE */
294146515Sru  { "",                    0, 0, 0 }, /* BOOKSUBTITLE */
29593139Sru
296146515Sru  { "",                    1, 0, 0 }, /* MENU */
297146515Sru  { "",                    1, 0, 0 }, /* DETAILMENU */
298146515Sru  { "",                    1, 0, 0 }, /* MENUENTRY */
299146515Sru  { "",                    0, 0, 0 }, /* MENUTITLE */
300146515Sru  { "",                    1, 0, 0 }, /* MENUCOMMENT */
301146515Sru  { "",                    0, 0, 0 }, /* MENUNODE */
302146515Sru  { "anchor",              0, 0, 0 }, /* NODENAME */
30393139Sru
304146515Sru  { "acronym",             0, 1, 0 },
305146515Sru  { "",                    0, 1, 0 }, /* ACRONYMWORD */
306146515Sru  { "",                    0, 1, 0 }, /* ACRONYMDESC */
30793139Sru
308146515Sru  { "abbrev",              0, 1, 0 },
309146515Sru  { "",                    0, 1, 0 }, /* ABBREVWORD */
310146515Sru  { "",                    0, 1, 0 }, /* ABBREVDESC */
31193139Sru
312146515Sru  { "literal",             0, 1, 0 }, /* TT */
313146515Sru  { "literal",             0, 1, 0 }, /* CODE */
314146515Sru  { "command",             0, 1, 0 }, /* COMMAND */
315146515Sru  { "envar",               0, 1, 0 }, /* ENV */
316146515Sru  { "filename",            0, 1, 0 }, /* FILE */
317146515Sru  { "option",              0, 1, 0 }, /* OPTION */
318146515Sru  { "literal",             0, 1, 0 }, /* SAMP */
319146515Sru  { "userinput",           0, 1, 0 }, /* KBD */
320146515Sru  { "wordasword",          0, 1, 0 }, /* URL */
321146515Sru  { "keycap",              0, 1, 0 }, /* KEY */
322146515Sru  { "replaceable",         0, 1, 0 }, /* VAR */
323146515Sru  { "",                    0, 1, 0 }, /* SC */
324146515Sru  { "firstterm",           0, 1, 0 }, /* DFN */
325146515Sru  { "emphasis",            0, 1, 0 }, /* EMPH */
326146515Sru  { "emphasis",            0, 1, 0 }, /* STRONG */
327146515Sru  { "citetitle",           0, 1, 0 }, /* CITE */
328146515Sru  { "",                    0, 1, 0 }, /* NOTFIXEDWIDTH */
329146515Sru  { "wordasword",          0, 1, 0 }, /* I */
330146515Sru  { "emphasis",            0, 1, 0 }, /* B */
331146515Sru  { "",                    0, 1, 0 }, /* R */
33293139Sru
333146515Sru  { "",                    0, 0, 0 }, /* EXDENT */
33493139Sru
335146515Sru  { "title",               0, 0, 0 },
336146515Sru  { "",                    1, 0, 0 }, /* IFINFO */
337146515Sru  { "",                    0, 0, 0 }, /* SP */
338146515Sru  { "",                    1, 0, 0 }, /* CENTER */
339146515Sru  { "",                    0, 0, 0 }, /* DIRCATEGORY */
340146515Sru  { "blockquote",          1, 0, 0 }, /* QUOTATION */
341146515Sru  { "screen",              0, 0, 1 }, /* EXAMPLE */
342146515Sru  { "screen",              0, 0, 1 }, /* SMALLEXAMPLE */
343146515Sru  { "programlisting",      0, 0, 1 }, /* LISP */
344146515Sru  { "programlisting",      0, 0, 1 }, /* SMALLLISP */
345146515Sru  { "",                    1, 0, 0 }, /* CARTOUCHE */
346146515Sru  { "",                    1, 0, 0 }, /* COPYING */
347146515Sru  { "screen",              0, 1, 1 }, /* FORMAT */
348146515Sru  { "screen",              0, 1, 1 }, /* SMALLFORMAT */
349146515Sru  { "literallayout",       0, 1, 1 }, /* DISPLAY */
350146515Sru  { "literallayout",       0, 1, 1 }, /* SMALLDISPLAY */
351146515Sru  { "screen",              0, 0, 1 }, /* VERBATIM */
352146515Sru  { "footnote",            0, 1, 0 },
353146515Sru  { "lineannotation",      0, 1, 0 },
35493139Sru
355146515Sru  { "tip",                 1, 0, 0 },
356146515Sru  { "note",                1, 0, 0 },
357146515Sru  { "important",           1, 0, 0 },
358146515Sru  { "warning",             1, 0, 0 },
359146515Sru  { "caution",             1, 0, 0 },
36093139Sru
361146515Sru  { "itemizedlist",        0, 0, 0 }, /* ITEMIZE */
362146515Sru  { "",                    0, 0, 0 }, /* ITEMFUNCTION */
363146515Sru  { "listitem",            1, 0, 0 }, /* ITEM */
364146515Sru  { "orderedlist",         0, 0, 0 }, /* ENUMERATE */
365146515Sru  { "variablelist",        0, 0, 0 }, /* TABLE */
366146515Sru  { "varlistentry",        0, 0, 0 }, /* TABLEITEM */
367146515Sru  { "term",                0, 0, 0 }, /* TABLETERM */
36893139Sru
369146515Sru  { "indexterm",           0, 1, 0 }, /* INDEXTERM */
370114472Sru
371146515Sru  { "",                    0, 1, 0 }, /* MATH */
372116525Sru
373146515Sru  { "",                    0, 1, 0 }, /* DIMENSION */
374146515Sru
375146515Sru  { "xref",                0, 1, 0 }, /* XREF */
376146515Sru  { "link",                0, 1, 0 }, /* XREFNODENAME */
377146515Sru  { "",                    0, 1, 0 }, /* XREFINFONAME */
378146515Sru  { "",                    0, 1, 0 }, /* XREFPRINTEDDESC */
379146515Sru  { "",                    0, 1, 0 }, /* XREFINFOFILE */
380146515Sru  { "",                    0, 1, 0 }, /* XREFPRINTEDNAME */
381146515Sru
382146515Sru  { "",                    0, 1, 0 }, /* INFOREF */
383146515Sru  { "",                    0, 1, 0 }, /* INFOREFNODENAME */
384146515Sru  { "",                    0, 1, 0 }, /* INFOREFREFNAME */
385146515Sru  { "",                    0, 1, 0 }, /* INFOREFINFONAME */
386146515Sru
387146515Sru  { "ulink",               0, 1, 0 }, /* UREF */
388146515Sru  { "",                    0, 1, 0 }, /* UREFURL */
389146515Sru  { "",                    0, 1, 0 }, /* UREFDESC */
390146515Sru  { "",                    0, 1, 0 }, /* UREFREPLACEMENT */
391146515Sru
392146515Sru  { "ulink",               0, 1, 0 }, /* EMAIL */
393146515Sru  { "",                    0, 1, 0 }, /* EMAILADDRESS */
394146515Sru  { "",                    0, 1, 0 }, /* EMAILNAME */
395146515Sru
396146515Sru  { "",                    0, 0, 0 }, /* GROUP */
397146515Sru  { "",                    1, 0, 0 }, /* FLOAT */
398146515Sru  { "",                    0, 0, 0 }, /* FLOATTYPE */
399146515Sru  { "",                    0, 0, 0 }, /* FLOATPOS */
400146515Sru  { "",                    0, 0, 0 }, /* CAPTION */
401146515Sru  { "",                    0, 0, 0 }, /* SHORTCAPTION */
402146515Sru
403146515Sru  { "table",               0, 1, 0 },
404146515Sru  { "figure",              0, 1, 0 },
405146515Sru  { "example",             1, 1, 0 },
406146515Sru  { "sidebar",             1, 0, 0 },
407146515Sru
408146515Sru  { "index",               0, 1, 0 }, /* PRINTINDEX */
409146515Sru  { "",                    0, 1, 0 }, /* LISTOFFLOATS */
410146515Sru  { "",                    0, 1, 0 }, /* ANCHOR */
411146515Sru
412146515Sru  { "",                    0, 0, 0 }, /* IMAGE */
413146515Sru  { "inlinemediaobject",   0, 1, 0 }, /* INLINEIMAGE */
414146515Sru  { "",                    0, 0, 0 }, /* IMAGEALTTEXT */
415146515Sru
416146515Sru  { "primary",             0, 1, 0 }, /* PRIMARY */
417146515Sru  { "secondary",           0, 1, 0 },
418146515Sru  { "informalfigure",      0, 0, 0 },
419146515Sru  { "mediaobject",         0, 0, 0 },
420146515Sru  { "imageobject",         0, 1, 0 },
421146515Sru  { "imagedata",           0, 1, 0 },
422146515Sru  { "textobject",          0, 1, 0 },
423146515Sru  { "indexentry",          0, 0, 0 },
424146515Sru  { "primaryie",           0, 0, 0 },
425146515Sru  { "secondaryie",         0, 0, 0 },
426146515Sru  { "indexdiv",            0, 0, 0 },
427146515Sru  { "informaltable",       0, 0, 0 },
428146515Sru  { "tgroup",              0, 0, 0 },
429146515Sru  { "colspec",             0, 0, 0 },
430146515Sru  { "thead",               0, 0, 0 },
431146515Sru  { "tbody",               0, 0, 0 },
432146515Sru  { "entry",               0, 0, 0 },
433146515Sru  { "row",                 0, 0, 0 },
434146515Sru  { "bookinfo",            0, 0, 0 },
435146515Sru  { "abstract",            1, 0, 0 },
436146515Sru  { "replaceable",         0, 0, 0 },
437146515Sru  { "envar",               0, 1, 0 },
438146515Sru  { "comment",             0, 0, 0 },
439146515Sru  { "function",            0, 1, 0 },
440146515Sru  { "legalnotice",         1, 0, 0 },
441146515Sru
442146515Sru  { "",                    0, 0, 0 }, /* CONTENTS (xml) */
443146515Sru  { "",                    0, 0, 0 }, /* SHORTCONTENTS (xml) */
444146515Sru  { "",                    0, 0, 0 }, /* DOCUMENT LANGUAGE (xml) */
445146515Sru
446146515Sru  { "",                    0, 0, 0 }, /* SETVALUE (xml) */
447146515Sru  { "",                    0, 0, 0 }, /* CLEARVALUE (xml) */
448146515Sru
449146515Sru  { "blockquote",          1, 0, 0 }, /* DEFINITION */
450146515Sru  { "screen",              0, 0, 1 }, /* DEFINITIONTERM */
451146515Sru  { "",                    0, 0, 0 }, /* DEFINITIONITEM (xml) */
452146515Sru  { "",                    0, 0, 0 }, /* DEFCATEGORY (xml) */
453146515Sru  { "function",            0, 0, 0 }, /* DEFFUNCTION */
454146515Sru  { "varname",             0, 0, 0 }, /* DEFVARIABLE */
455146515Sru  { "varname",             0, 0, 0 }, /* DEFPARAM */
456146515Sru  { "",                    0, 0, 0 }, /* DEFDELIMITER (xml) */
457146515Sru  { "returnvalue",         0, 0, 0 }, /* DEFTYPE */
458146515Sru  { "type",                0, 0, 0 }, /* DEFPARAMTYPE */
459146515Sru  { "structname",          0, 0, 0 }, /* DEFDATATYPE */
460146515Sru  { "classname",           0, 0, 0 }, /* DEFCLASS */
461146515Sru  { "property",            0, 0, 0 }, /* DEFCLASSVAR */
462146515Sru  { "methodname",          0, 0, 0 }, /* DEFOPERATION */
463146515Sru
464146515Sru  { "para",                0, 0, 0 } /* Must be last */
465146515Sru  /* name / contains para / contained in para / preserve space */
46693139Sru};
46793139Sru
46893139Sruelement *xml_element_list = NULL;
46993139Sru
47093139Sru
47193139Srutypedef struct _replace_element
47293139Sru{
47393139Sru  int element_to_replace;
47493139Sru  int element_containing;
47593139Sru  int element_replacing;
47693139Sru} replace_element;
47793139Sru
47893139Sru/* Elements to replace - Docbook only
47993139Sru   -------------------
480114472Sru   if `element_to_replace' have to be inserted
481114472Sru   as a child of `element_containing,'
48293139Sru   use `element_replacing' instead.
48393139Sru
48493139Sru   A value of `-1' for element_replacing means `do not use any element.'
48593139Sru*/
48693139Sru
48793139Srureplace_element replace_elements [] = {
48893139Sru  { I, TABLETERM, EMPH },
48993139Sru  { B, TABLETERM, EMPH },
49093139Sru  { TT, CODE, -1 },
49193139Sru  { EXAMPLE, DISPLAY, -1 },
49293139Sru  { CODE, DFN, -1 },
49393139Sru  { CODE, VAR, -1 },
49493139Sru  { EMPH, CODE, REPLACEABLE },
495114472Sru  { VAR, VAR, -1},
496114472Sru  { VAR, B, EMPH},
497114472Sru  { B, CODE, ENVAR},
498114472Sru  { CODE, I, EMPH},
499146515Sru  { SAMP, VAR, -1 },
500114472Sru  { FORMAT, BOOKINFO, ABSTRACT },
501114472Sru  { QUOTATION, ABSTRACT, -1},
502146515Sru  { LINEANNOTATION, LINEANNOTATION, -1 },
503146515Sru  { LEGALNOTICE, ABSTRACT, -1 },
504146515Sru  { QUOTATION, QUOTATION, -1 },
505146515Sru  /* Formal versions of table and image elements.  */
506146515Sru  { MULTITABLE, FLOAT, FLOATTABLE },
507146515Sru  { INFORMALFIGURE, FLOAT, FLOATFIGURE },
508146515Sru  { CARTOUCHE, FLOAT, FLOATCARTOUCHE },
509146515Sru  /* Unnecessary markup in @defun blocks.  */
510146515Sru  { VAR, DEFPARAM, -1 },
511146515Sru  { CODE, DEFTYPE, -1 },
51293139Sru  /* Add your elements to replace here */
51393139Sru  {-1, 0, 0}
51493139Sru};
51593139Sru
51693139Sruint xml_in_menu_entry = 0;
51793139Sruint xml_in_menu_entry_comment = 0;
51893139Sruint xml_node_open = 0;
51993139Sruint xml_node_level = -1;
52093139Sruint xml_in_para = 0;
52193139Sruint xml_just_after_element = 0;
522146515Sruint xml_keep_space = 0;
52393139Sru
524146515Sruint xml_no_indent = 0;
525146515Sru
52693139Sruint xml_no_para = 0;
52793139Sruchar *xml_node_id = NULL;
52893139Sruint xml_sort_index = 0;
52993139Sru
530114472Sruint xml_in_xref_token = 0;
531114472Sruint xml_in_bookinfo = 0;
532114472Sruint xml_in_book_title = 0;
533114472Sruint xml_in_abstract = 0;
534114472Sru
535146515Sru/* Non-zero if we are handling an element that can appear between
536146515Sru   @item and @itemx, @deffn and @deffnx.  */
537146515Sruint xml_dont_touch_items_defs = 0;
538146515Sru
539146515Sru/* We need to keep footnote state, because elements inside footnote may try
540146515Sru   to close the previous parent para.  */
541146515Srustatic int xml_in_footnote = 0;
542146515Sru
54393139Srustatic int xml_after_table_term = 0;
54493139Srustatic int book_started = 0;
54593139Srustatic int first_section_opened = 0;
54693139Sru
547146515Srustatic int xml_in_tableitem[256];
548114472Srustatic int xml_in_item[256];
549114472Srustatic int xml_table_level = 0;
550114472Sru
551146515Srustatic int xml_in_def_item[256];
552146515Srustatic int xml_definition_level = 0;
553146515Sruint xml_after_def_term = 0;
554146515Sru
555114472Srustatic int in_table_title = 0;
556114472Sru
557114472Srustatic int in_indexentry = 0;
558114472Srustatic int in_secondary = 0;
559114472Srustatic int in_indexterm = 0;
560146515Sru
56193139Sruchar *
562146515Sruxml_id (char *id)
56393139Sru{
56493139Sru  char *tem = xmalloc (strlen (id) + 1);
56593139Sru  char *p = tem;
56693139Sru  strcpy (tem, id);
567114472Sru  while (*p)
568146515Sru    { /* Check if a character is allowed in ID attributes.  This list differs
569146515Sru         slightly from XML specs that it doesn't contain underscores.
570146515Sru         See http://xml.coverpages.org/sgmlsyn/sgmlsyn.htm, ``9.3 Name''  */
571146515Sru      if (!strchr ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.", *p))
572114472Sru        *p = '-';
573114472Sru      p++;
57493139Sru    }
57593139Sru  p = tem;
576146515Sru  /* First character can only be a letter.  */
577146515Sru  if (!strchr ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", *p))
57893139Sru    *p = 'i';
57993139Sru  return tem;
58093139Sru}
58193139Sru
58293139Sruint
583146515Sruxml_element (char *name)
58493139Sru{
58593139Sru  int i;
58693139Sru  for (i=0; i<=PARA; i++)
58793139Sru    {
58893139Sru      if (strcasecmp (name, texinfoml_element_list[i].name) == 0)
589114472Sru        return i;
59093139Sru    }
59193139Sru  printf ("Error xml_element\n");
59293139Sru  return -1;
59393139Sru}
59493139Sru
59593139Sruvoid
596146515Sruxml_begin_document (char *output_filename)
59793139Sru{
59893139Sru  if (book_started)
59993139Sru    return;
60093139Sru
60193139Sru  book_started = 1;
602146515Sru
603146515Sru  /* Make sure this is the very first string of the output document.  */
604146515Sru  output_paragraph_offset = 0;
605146515Sru
606146515Sru  insert_string ("<?xml version=\"1.0\"");
607146515Sru
608146515Sru  /* At this point, we register a delayed writing for document encoding,
609146515Sru     so in the end, proper encoding attribute will be inserted here.
610146515Sru     Since the user is unaware that we are implicitly executing this
611146515Sru     command, we should disable warnings temporarily, in order to avoid
612146515Sru     possible confusion.  (ie. if the output is not seekable,
613146515Sru     register_delayed_write issues a warning.)  */
614146515Sru  {
615146515Sru    extern int print_warnings;
616146515Sru    int save_print_warnings = print_warnings;
617146515Sru    print_warnings = 0;
618146515Sru    register_delayed_write ("@documentencoding");
619146515Sru    print_warnings = save_print_warnings;
620146515Sru  }
621146515Sru
622146515Sru  insert_string ("?>\n");
623146515Sru
62493139Sru  if (docbook)
62593139Sru    {
626146515Sru      insert_string ("<!DOCTYPE book PUBLIC \"-//OASIS//DTD DocBook XML V4.2//EN\" \"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd\" [\n  <!ENTITY tex \"TeX\">\n  <!ENTITY latex \"LaTeX\">\n]>");
62793139Sru      xml_element_list = docbook_element_list;
62893139Sru    }
62993139Sru  else
63093139Sru    {
631146515Sru      insert_string ("<!DOCTYPE texinfo PUBLIC \"-//GNU//DTD TexinfoML V");
632146515Sru      insert_string (VERSION);
633146515Sru      insert_string ("//EN\" \"http://www.gnu.org/software/texinfo/dtd/");
634146515Sru      insert_string (VERSION);
635146515Sru      insert_string ("/texinfo.dtd\">");
63693139Sru      xml_element_list = texinfoml_element_list;
63793139Sru    }
638146515Sru  if (language_code != last_language_code)
63993139Sru    {
640146515Sru      if (docbook)
641114472Sru        xml_insert_element_with_attribute (TEXINFO, START, "lang=\"%s\"", language_table[language_code].abbrev);
642146515Sru      else
643146515Sru	xml_insert_element_with_attribute (TEXINFO, START, "xml:lang=\"%s\"", language_table[language_code].abbrev);
64493139Sru    }
64593139Sru  if (!docbook)
64693139Sru    {
64793139Sru      xml_insert_element (SETFILENAME, START);
64893139Sru      insert_string (output_filename);
64993139Sru      xml_insert_element (SETFILENAME, END);
65093139Sru    }
65193139Sru}
65293139Sru
65393139Sru/*  */
65493139Srustatic int element_stack[256];
65593139Srustatic int element_stack_index = 0;
65693139Sru
657146515Srustatic int
658146515Sruxml_current_element (void)
659146515Sru{
660146515Sru  return element_stack[element_stack_index-1];
661146515Sru}
662146515Sru
663114472Srustatic void
664146515Sruxml_push_current_element (int elt)
66593139Sru{
66693139Sru  element_stack[element_stack_index++] = elt;
66793139Sru  if (element_stack_index > 200)
668114472Sru    printf ("*** stack overflow (%d - %s) ***\n",
669114472Sru            element_stack_index,
670114472Sru            xml_element_list[elt].name);
67193139Sru}
67293139Sru
673146515Srustatic void
674146515Sruxml_pop_current_element (void)
67593139Sru{
67693139Sru  element_stack_index--;
67793139Sru  if (element_stack_index < 0)
678114472Sru    printf ("*** stack underflow (%d - %d) ***\n",
679114472Sru            element_stack_index,
680114472Sru            xml_current_element());
68193139Sru}
68293139Sru
683146515Sruint
684146515Sruxml_current_stack_index (void)
68593139Sru{
686146515Sru  return element_stack_index;
68793139Sru}
68893139Sru
689146515Sruvoid
690146515Sruxml_end_current_element (void)
69193139Sru{
692146515Sru  xml_insert_element (xml_current_element (), END);
69393139Sru}
69493139Sru
69593139Srustatic void
696146515Sruxml_indent (void)
69793139Sru{
698146515Sru  if (xml_indentation_increment > 0)
699146515Sru    {
700146515Sru      int i;
701146515Sru      if (output_paragraph[output_paragraph_offset-1] != '\n')
702146515Sru        insert ('\n');
703146515Sru      for (i = 0; i < element_stack_index * xml_indentation_increment; i++)
704146515Sru        insert (' ');
705146515Sru    }
70693139Sru}
70793139Sru
70893139Sruvoid
709146515Sruxml_start_para (void)
71093139Sru{
711146515Sru  if (xml_in_para || xml_in_footnote
712146515Sru      || !xml_element_list[xml_current_element()].contains_para)
713146515Sru    return;
714146515Sru
715146515Sru  while (output_paragraph[output_paragraph_offset-1] == '\n')
716146515Sru    output_paragraph_offset--;
717146515Sru  xml_indent ();
718146515Sru
719146515Sru  insert_string ("<para");
720146515Sru  if (xml_no_indent)
721146515Sru    insert_string (" role=\"continues\"");
722146515Sru  insert_string (">");
723146515Sru  xml_no_indent = 0;
724146515Sru  xml_in_para = 1;
725146515Sru}
726146515Sru
727146515Sruvoid
728146515Sruxml_end_para (void)
729146515Sru{
730146515Sru  if (!xml_in_para || xml_in_footnote)
731146515Sru    return;
732146515Sru
733146515Sru  while (cr_or_whitespace(output_paragraph[output_paragraph_offset-1]))
734146515Sru    output_paragraph_offset--;
735146515Sru
736146515Sru  insert_string ("</para>");
737146515Sru  if (xml_indentation_increment > 0)
738146515Sru    insert ('\n');
739146515Sru  xml_in_para = 0;
740146515Sru}
741146515Sru
742146515Sruvoid
743146515Sruxml_end_document (void)
744146515Sru{
74593139Sru  if (xml_node_open)
74693139Sru    {
74793139Sru      if (xml_node_level != -1)
748114472Sru        {
749114472Sru          xml_close_sections (xml_node_level);
750114472Sru          xml_node_level = -1;
751114472Sru        }
75293139Sru      xml_insert_element (NODE, END);
75393139Sru    }
754114472Sru  else
755114472Sru    xml_close_sections (xml_node_level);
756114472Sru
75793139Sru  xml_insert_element (TEXINFO, END);
758146515Sru  if (xml_indentation_increment == 0)
759146515Sru    insert ('\n');
76093139Sru  insert_string ("<!-- Keep this comment at the end of the file\n\
76193139SruLocal variables:\n\
76293139Srumode: sgml\n\
76393139Srusgml-indent-step:1\n\
76493139Srusgml-indent-data:nil\n\
76593139SruEnd:\n\
76693139Sru-->\n");
76793139Sru  if (element_stack_index != 0)
76893139Sru    error ("Element stack index : %d\n", element_stack_index);
76993139Sru}
77093139Sru
77193139Sru/* MUST be 0 or 1, not true or false values */
77293139Srustatic int start_element_inserted = 1;
77393139Sru
77493139Sru/* NOTE: We use `elt' rather than `element' in the argument list of
77593139Sru   the next function, since otherwise the Solaris SUNWspro compiler
77693139Sru   barfs because `element' is a typedef declared near the beginning of
77793139Sru   this file.  */
778114472Sruvoid
77993139Sru#if defined (VA_FPRINTF) && __STDC__
78093139Sruxml_insert_element_with_attribute (int elt, int arg, char *format, ...)
78193139Sru#else
78293139Sruxml_insert_element_with_attribute (elt, arg, format, va_alist)
78393139Sru     int elt;
78493139Sru     int arg;
78593139Sru     char *format;
78693139Sru     va_dcl
78793139Sru#endif
78893139Sru{
78993139Sru  /* Look at the replace_elements table to see if we have to change the element */
79093139Sru  if (xml_sort_index)
791114472Sru      return;
79293139Sru  if (docbook)
79393139Sru    {
79493139Sru      replace_element *element_list = replace_elements;
79593139Sru      while (element_list->element_to_replace >= 0)
796114472Sru        {
797114472Sru          if ( ( (arg == START) &&
798114472Sru                 (element_list->element_containing == xml_current_element ()) &&
799114472Sru                 (element_list->element_to_replace == elt) ) ||
800114472Sru               ( (arg == END) &&
801114472Sru                 (element_list->element_containing == element_stack[element_stack_index-1-start_element_inserted]) &&
802114472Sru                 (element_list->element_to_replace == elt) ) )
803114472Sru            {
804114472Sru              elt = element_list->element_replacing;
805114472Sru              break;
806114472Sru            }
807114472Sru          element_list ++;
808114472Sru        }
809114472Sru
81093139Sru      /* Forget the element */
81193139Sru      if (elt < 0)
812114472Sru        {
813114472Sru          if (arg == START)
814114472Sru            start_element_inserted = 0;
815114472Sru          else
816114472Sru            /* Replace the default value, for the next time */
817114472Sru            start_element_inserted = 1;
818114472Sru          return;
819114472Sru        }
82093139Sru    }
82193139Sru
82293139Sru  if (!book_started)
823146515Sru    return;
82493139Sru
825146515Sru  if (!xml_dont_touch_items_defs && arg == START)
82693139Sru    {
827146515Sru      if (xml_after_table_term && elt != TABLETERM && xml_table_level
828146515Sru          && !xml_in_item[xml_table_level])
829146515Sru        {
830146515Sru          xml_after_table_term = 0;
831146515Sru          xml_insert_element (ITEM, START);
832146515Sru          xml_in_item[xml_table_level] = 1;
833146515Sru        }
834146515Sru      else if (xml_after_def_term && elt != DEFINITIONTERM)
835146515Sru        {
836146515Sru          xml_after_def_term = 0;
837146515Sru          xml_insert_element (DEFINITIONITEM, START);
838146515Sru          xml_in_def_item[xml_definition_level] = 1;
839146515Sru        }
84093139Sru    }
84193139Sru
84293139Sru  if (docbook && !only_macro_expansion && (in_menu || in_detailmenu))
84393139Sru    return;
844116525Sru
845146515Sru  if (executing_string && arg == END)
846146515Sru    switch (elt)
847146515Sru      {
848146515Sru      case TABLEITEM:
849146515Sru        xml_in_tableitem[xml_table_level] = 0;
850146515Sru        break;
851146515Sru      case ITEM:
852146515Sru        xml_in_item[xml_table_level] = 0;
853146515Sru        break;
854146515Sru      case DEFINITIONTERM:
855146515Sru        xml_in_def_item[xml_definition_level] = 0;
856146515Sru        break;
857146515Sru      }
858146515Sru
859146515Sru  /* We are special-casing FIGURE element for docbook.  It does appear in
860146515Sru     the tag stack, but not in the output.  This is to make element replacement
861146515Sru     work beautifully.  */
862146515Sru  if (docbook && elt == FLOAT)
863146515Sru    {
864146515Sru      if (arg == START)
865146515Sru        xml_push_current_element (elt);
866146515Sru      else
867146515Sru        xml_pop_current_element ();
868146515Sru      return;
869146515Sru    }
870146515Sru
87193139Sru  if (!xml_element_list[elt].name || !strlen (xml_element_list[elt].name))
87293139Sru    {
873114472Sru      /*printf ("Warning: Inserting empty element %d\n", elt);*/
87493139Sru      return;
87593139Sru    }
87693139Sru
87793139Sru  if (arg == START && !xml_in_para && !xml_no_para
878146515Sru      && xml_element_list[elt].contained_in_para)
879146515Sru    xml_start_para ();
88093139Sru
88193139Sru  if (arg == START && xml_in_para && !xml_element_list[elt].contained_in_para)
882146515Sru    xml_end_para ();
883114472Sru
88493139Sru  if (arg == END && xml_in_para && !xml_element_list[elt].contained_in_para)
885146515Sru    xml_end_para ();
88693139Sru
887146515Sru  if (docbook && xml_table_level && !in_table_title
888146515Sru      && !xml_in_tableitem[xml_table_level] && !xml_in_item[xml_table_level]
889114472Sru      && arg == START && elt != TABLEITEM && elt != TABLETERM
890114472Sru      && !in_indexterm && xml_current_element() == TABLE)
891114472Sru    {
892114472Sru      in_table_title = 1;
893114472Sru      xml_insert_element (TITLE, START);
894114472Sru    }
895114472Sru
896146515Sru  if (arg == START && !xml_in_para && !xml_keep_space
897146515Sru      && !xml_element_list[elt].contained_in_para)
898146515Sru    xml_indent ();
899114472Sru
90093139Sru  if (arg == START)
90193139Sru    xml_push_current_element (elt);
90293139Sru  else
90393139Sru    xml_pop_current_element ();
90493139Sru
905146515Sru  /* Eat one newline before </example> and the like.  */
906146515Sru  if (!docbook && arg == END
907146515Sru      && (xml_element_list[elt].keep_space || elt == GROUP)
908146515Sru      && output_paragraph[output_paragraph_offset-1] == '\n')
909146515Sru    output_paragraph_offset--;
910146515Sru
911146515Sru  /* And eat whitespace before </entry> in @multitables.  */
912146515Sru  if (arg == END && elt == ENTRY)
913146515Sru      while (cr_or_whitespace(output_paragraph[output_paragraph_offset-1]))
914146515Sru    output_paragraph_offset--;
915146515Sru
916146515Sru  /* Indent elements that can contain <para>.  */
917146515Sru  if (arg == END && !xml_in_para && !xml_keep_space
918146515Sru      && xml_element_list[elt].contains_para)
919146515Sru    xml_indent ();
920146515Sru
921146515Sru  /* Here are the elements we want indented.  These do not contain <para>
922146515Sru     directly.  */
923146515Sru  if (arg == END && (elt == MENUENTRY || elt == ITEMIZE || elt == ENUMERATE
924146515Sru        || elt == TABLEITEM || elt == TABLE
925146515Sru        || elt == MULTITABLE || elt == TGROUP || elt == THEAD || elt == TBODY
926146515Sru        || elt == ROW || elt == INFORMALFIGURE
927146515Sru        || (!docbook && (elt == DEFINITION || elt == DEFINITIONTERM))))
928146515Sru    xml_indent ();
929146515Sru
93093139Sru  insert ('<');
93193139Sru  if (arg == END)
93293139Sru    insert ('/');
93393139Sru  insert_string (xml_element_list[elt].name);
934114472Sru
93593139Sru  /*  printf ("%s ", xml_element_list[elt].name);*/
93693139Sru
93793139Sru  if (format)
93893139Sru    {
93993139Sru      char temp_string[2000]; /* xx no fixed limits */
94093139Sru#ifdef VA_SPRINTF
94193139Sru      va_list ap;
94293139Sru#endif
94393139Sru
94493139Sru      VA_START (ap, format);
94593139Sru#ifdef VA_SPRINTF
94693139Sru      VA_SPRINTF (temp_string, format, ap);
94793139Sru#else
94893139Sru      sprintf (temp_string, format, a1, a2, a3, a4, a5, a6, a7, a8);
949114472Sru#endif
95093139Sru      insert (' ');
95193139Sru      insert_string (temp_string);
95293139Sru      va_end (ap);
95393139Sru    }
95493139Sru
95593139Sru  if (arg == START && xml_node_id && elt != NODENAME)
95693139Sru    {
95793139Sru      insert_string (" id=\"");
95893139Sru      insert_string (xml_node_id);
959146515Sru      insert ('"');
96093139Sru      free (xml_node_id);
96193139Sru      xml_node_id = NULL;
96293139Sru    }
96393139Sru
964146515Sru  if (xml_element_list[elt].keep_space)
965146515Sru    {
966146515Sru      if (arg == START)
967146515Sru	{
968146515Sru          if (!docbook)
969146515Sru            insert_string (" xml:space=\"preserve\"");
970146515Sru	  xml_keep_space++;
971146515Sru	}
972146515Sru      else
973146515Sru	xml_keep_space--;
974146515Sru    }
975146515Sru
97693139Sru  insert ('>');
97793139Sru
978146515Sru  if (!xml_in_para && !xml_element_list[elt].contained_in_para
979146515Sru      && xml_element_list[elt].contains_para && xml_indentation_increment > 0)
980146515Sru    insert ('\n');
981146515Sru
98293139Sru  xml_just_after_element = 1;
98393139Sru}
98493139Sru
98593139Sru/* See the NOTE before xml_insert_element_with_attribute, for why we
98693139Sru   use `elt' rather than `element' here.  */
98793139Sruvoid
98893139Sruxml_insert_element (int elt, int arg)
98993139Sru{
99093139Sru  xml_insert_element_with_attribute (elt, arg, NULL);
99193139Sru}
99293139Sru
99393139Sruvoid
99493139Sruxml_insert_entity (char *entity_name)
99593139Sru{
99693139Sru  int saved_escape_html = escape_html;
99793139Sru
99893139Sru  if (!book_started)
99993139Sru    return;
100093139Sru  if (docbook && !only_macro_expansion && (in_menu || in_detailmenu))
100193139Sru    return;
100293139Sru
1003114472Sru  if (!xml_in_para && !xml_no_para && !only_macro_expansion
1004114472Sru      && xml_element_list[xml_current_element ()].contains_para
1005114472Sru      && !in_fixed_width_font)
1006146515Sru    xml_start_para ();
1007146515Sru
100893139Sru  escape_html = 0;
1009146515Sru  add_char ('&');
101093139Sru  escape_html = saved_escape_html;
101193139Sru  insert_string (entity_name);
1012146515Sru  add_char (';');
101393139Sru}
101493139Sru
101593139Srutypedef struct _xml_section xml_section;
101693139Srustruct _xml_section {
101793139Sru  int level;
101893139Sru  char *name;
101993139Sru  xml_section *prev;
102093139Sru};
102193139Sru
102293139Sruxml_section *last_section = NULL;
102393139Sru
102493139Sruvoid
1025146515Sruxml_begin_node (void)
102693139Sru{
1027114472Sru  first_section_opened = 1;
1028114472Sru  if (xml_in_abstract)
1029114472Sru    {
1030114472Sru      xml_insert_element (ABSTRACT, END);
1031114472Sru      xml_in_abstract = 0;
1032114472Sru    }
1033114472Sru  if (xml_in_bookinfo)
1034114472Sru    {
1035114472Sru      xml_insert_element (BOOKINFO, END);
1036114472Sru      xml_in_bookinfo = 0;
1037114472Sru    }
103893139Sru  if (xml_node_open && ! docbook)
103993139Sru    {
104093139Sru      if (xml_node_level != -1)
1041114472Sru        {
1042114472Sru          xml_close_sections (xml_node_level);
1043114472Sru          xml_node_level = -1;
1044114472Sru        }
104593139Sru      xml_insert_element (NODE, END);
104693139Sru    }
104793139Sru  xml_insert_element (NODE, START);
104893139Sru  xml_node_open = 1;
104993139Sru}
105093139Sru
105193139Sruvoid
1052146515Sruxml_close_sections (int level)
105393139Sru{
1054114472Sru  if (!first_section_opened)
105593139Sru    {
1056114472Sru      if (xml_in_abstract)
1057114472Sru	{
1058114472Sru	  xml_insert_element (ABSTRACT, END);
1059114472Sru	  xml_in_abstract = 0;
1060114472Sru	}
1061114472Sru      if (xml_in_bookinfo)
1062114472Sru	{
1063114472Sru	  xml_insert_element (BOOKINFO, END);
1064114472Sru	  xml_in_bookinfo = 0;
1065114472Sru	}
106693139Sru      first_section_opened = 1;
106793139Sru    }
1068114472Sru
106993139Sru  while (last_section && last_section->level >= level)
107093139Sru    {
107193139Sru      xml_section *temp = last_section;
107293139Sru      xml_insert_element (xml_element(last_section->name), END);
107393139Sru      temp = last_section;
107493139Sru      last_section = last_section->prev;
107593139Sru      free (temp->name);
107693139Sru      free (temp);
107793139Sru    }
107893139Sru}
107993139Sru
108093139Sruvoid
1081146515Sruxml_open_section (int level, char *name)
108293139Sru{
108393139Sru  xml_section *sect = (xml_section *) xmalloc (sizeof (xml_section));
108493139Sru
108593139Sru  sect->level = level;
108693139Sru  sect->name = xmalloc (1 + strlen (name));
108793139Sru  strcpy (sect->name, name);
108893139Sru  sect->prev = last_section;
108993139Sru  last_section = sect;
109093139Sru
109193139Sru  if (xml_node_open && xml_node_level == -1)
109293139Sru    xml_node_level = level;
109393139Sru}
109493139Sru
109593139Sruvoid
1096146515Sruxml_start_menu_entry (char *tem)
109793139Sru{
109893139Sru  char *string;
109993139Sru  discard_until ("* ");
110093139Sru
110193139Sru  /* The line number was already incremented in reader_loop when we
110293139Sru     saw the newline, and discard_until has now incremented again.  */
110393139Sru  line_number--;
110493139Sru
110593139Sru  if (xml_in_menu_entry)
110693139Sru    {
110793139Sru      if (xml_in_menu_entry_comment)
1108114472Sru        {
1109114472Sru          xml_insert_element (MENUCOMMENT, END);
1110114472Sru          xml_in_menu_entry_comment=0;
1111114472Sru        }
111293139Sru      xml_insert_element (MENUENTRY, END);
111393139Sru      xml_in_menu_entry=0;
111493139Sru    }
111593139Sru  xml_insert_element (MENUENTRY, START);
111693139Sru  xml_in_menu_entry=1;
111793139Sru
111893139Sru  xml_insert_element (MENUNODE, START);
111993139Sru  string = expansion (tem, 0);
112093139Sru  add_word (string);
112193139Sru  xml_insert_element (MENUNODE, END);
112293139Sru  free (string);
1123114472Sru
112493139Sru  /* The menu item may use macros, so expand them now.  */
112593139Sru  xml_insert_element (MENUTITLE, START);
112693139Sru  only_macro_expansion++;
112793139Sru  get_until_in_line (1, ":", &string);
112893139Sru  only_macro_expansion--;
112993139Sru  execute_string ("%s", string); /* get escaping done */
113093139Sru  xml_insert_element (MENUTITLE, END);
113193139Sru  free (string);
113293139Sru
113393139Sru  if (looking_at ("::"))
113493139Sru    discard_until (":");
113593139Sru  else
113693139Sru    { /* discard the node name */
113793139Sru      get_until_in_line (0, ".", &string);
113893139Sru      free (string);
113993139Sru    }
1140114472Sru  input_text_offset++;  /* discard the second colon or the period */
1141146515Sru  skip_whitespace_and_newlines();
114293139Sru  xml_insert_element (MENUCOMMENT, START);
114393139Sru  xml_in_menu_entry_comment ++;
114493139Sru}
114593139Sru
114693139Sruvoid
1147146515Sruxml_end_menu (void)
114893139Sru{
114993139Sru  if (xml_in_menu_entry)
115093139Sru    {
115193139Sru      if (xml_in_menu_entry_comment)
1152114472Sru        {
1153114472Sru          xml_insert_element (MENUCOMMENT, END);
1154114472Sru          xml_in_menu_entry_comment --;
1155114472Sru        }
115693139Sru      xml_insert_element (MENUENTRY, END);
115793139Sru      xml_in_menu_entry--;
115893139Sru    }
115993139Sru  xml_insert_element (MENU, END);
116093139Sru}
116193139Sru
116293139Srustatic int xml_last_character;
116393139Sru
116493139Sruvoid
1165146515Sruxml_add_char (int character)
116693139Sru{
116793139Sru  if (!book_started)
1168114472Sru      return;
116993139Sru  if (docbook && !only_macro_expansion && (in_menu || in_detailmenu))
117093139Sru    return;
1171116525Sru
1172146515Sru  if (docbook && xml_table_level && !in_table_title
1173146515Sru      && !xml_in_item[xml_table_level] && !xml_in_tableitem[xml_table_level]
1174114472Sru      && !cr_or_whitespace (character) && !in_indexterm)
1175114472Sru    {
1176114472Sru      in_table_title = 1;
1177114472Sru      xml_insert_element (TITLE, START);
1178114472Sru    }
117993139Sru
1180114472Sru  if (!first_section_opened && !xml_in_abstract && !xml_in_book_title
1181146515Sru      && !xml_no_para && character != '\r' && character != '\n'
1182146515Sru      && character != ' ' && !is_in_insertion_of_type (copying))
118393139Sru    {
1184114472Sru      if (!xml_in_bookinfo)
1185114472Sru	{
1186114472Sru	  xml_insert_element (BOOKINFO, START);
1187114472Sru	  xml_in_bookinfo = 1;
1188114472Sru	}
118993139Sru      xml_insert_element (ABSTRACT, START);
1190114472Sru      xml_in_abstract = 1;
119193139Sru    }
119293139Sru
1193146515Sru  if (!xml_sort_index && !xml_in_xref_token && !xml_dont_touch_items_defs)
119493139Sru    {
1195146515Sru      if (xml_after_table_term && xml_table_level
1196146515Sru          && !xml_in_item[xml_table_level])
1197146515Sru        {
1198146515Sru          xml_after_table_term = 0;
1199146515Sru          xml_insert_element (ITEM, START);
1200146515Sru          xml_in_item[xml_table_level] = 1;
1201146515Sru        }
1202146515Sru      else if (xml_after_def_term)
1203146515Sru        {
1204146515Sru          xml_after_def_term = 0;
1205146515Sru          xml_insert_element (DEFINITIONITEM, START);
1206146515Sru          xml_in_def_item[xml_definition_level] = 1;
1207146515Sru        }
120893139Sru    }
1209114472Sru
121093139Sru  if (xml_just_after_element && !xml_in_para && !inhibit_paragraph_indentation)
121193139Sru    {
121293139Sru      if (character == '\r' || character == '\n' || character == '\t' || character == ' ')
1213114472Sru        return;
1214114472Sru      xml_just_after_element = 0;
121593139Sru    }
1216114472Sru
1217114472Sru  if (xml_element_list[xml_current_element()].contains_para
1218114472Sru      && !xml_in_para && !only_macro_expansion && !xml_no_para
1219114472Sru      && !cr_or_whitespace (character) && !in_fixed_width_font)
1220146515Sru    xml_start_para ();
1221146515Sru
1222146515Sru  if (xml_in_para && character == '\n' && xml_last_character == '\n'
1223146515Sru      && !only_macro_expansion && !xml_no_para
1224146515Sru      && xml_element_list[xml_current_element()].contains_para )
122593139Sru    {
1226146515Sru      xml_end_para ();
1227146515Sru      xml_just_after_element = 1;
1228146515Sru      return;
122993139Sru    }
1230114472Sru
1231146515Sru  if (xml_in_menu_entry_comment && character == '\n' && xml_last_character == '\n')
123293139Sru    {
1233146515Sru      xml_insert_element (MENUCOMMENT, END);
1234146515Sru      xml_in_menu_entry_comment = 0;
1235146515Sru      xml_insert_element (MENUENTRY, END);
1236146515Sru      xml_in_menu_entry = 0;
123793139Sru    }
1238114472Sru
1239146515Sru  if (xml_in_menu_entry_comment && whitespace(character)
1240146515Sru      && cr_or_whitespace(xml_last_character))
1241146515Sru    return;
1242146515Sru
124393139Sru  if (character == '\n' && !xml_in_para && !inhibit_paragraph_indentation)
124493139Sru    return;
124593139Sru
124693139Sru  xml_last_character = character;
124793139Sru
124893139Sru  if (character == '&' && escape_html)
124993139Sru      insert_string ("&amp;");
125093139Sru  else if (character == '<' && escape_html)
125193139Sru      insert_string ("&lt;");
1252146515Sru  else if (character == '\n' && !xml_keep_space)
1253146515Sru    {
1254146515Sru      if (!xml_in_para && xml_just_after_element && !multitable_active)
1255146515Sru	return;
1256146515Sru      else
1257146515Sru	insert (docbook ? '\n' : ' ');
1258146515Sru    }
125993139Sru  else
126093139Sru    insert (character);
1261114472Sru
126293139Sru  return;
126393139Sru}
126493139Sru
126593139Sruvoid
1266146515Sruxml_insert_footnote (char *note)
126793139Sru{
1268146515Sru  if (!xml_in_para)
1269146515Sru    xml_start_para ();
1270146515Sru
1271146515Sru  xml_in_footnote = 1;
127293139Sru  xml_insert_element (FOOTNOTE, START);
127393139Sru  insert_string ("<para>");
127493139Sru  execute_string ("%s", note);
127593139Sru  insert_string ("</para>");
127693139Sru  xml_insert_element (FOOTNOTE, END);
1277146515Sru  xml_in_footnote = 0;
127893139Sru}
127993139Sru
1280146515Sru/* We need to keep the quotation stack ourself, because insertion_stack
1281146515Sru   loses item_function when we are closing the block, so we don't know
1282146515Sru   what to close then.  */
1283146515Srutypedef struct quotation_elt
1284146515Sru{
1285146515Sru  struct quotation_elt *next;
1286146515Sru  char *type;
1287146515Sru} QUOTATION_ELT;
128893139Sru
1289146515Srustatic QUOTATION_ELT *quotation_stack = NULL;
1290146515Sru
1291146515Sruvoid
1292146515Sruxml_insert_quotation (char *type, int arg)
1293146515Sru{
1294146515Sru  int quotation_started = 0;
1295146515Sru
1296146515Sru  if (arg == START)
1297146515Sru    {
1298146515Sru      QUOTATION_ELT *new = xmalloc (sizeof (QUOTATION_ELT));
1299146515Sru      new->type = xstrdup (type);
1300146515Sru      new->next = quotation_stack;
1301146515Sru      quotation_stack = new;
1302146515Sru    }
1303146515Sru  else
1304146515Sru    type = quotation_stack->type;
1305146515Sru
1306146515Sru  /* Make use of special quotation styles of Docbook if we can.  */
1307146515Sru  if (docbook && strlen(type))
1308146515Sru    {
1309146515Sru      /* Let's assume it started.  */
1310146515Sru      quotation_started = 1;
1311146515Sru
1312146515Sru      if (strcasecmp (type, "tip") == 0)
1313146515Sru        xml_insert_element (TIP, arg);
1314146515Sru      else if (strcasecmp (type, "note") == 0)
1315146515Sru        xml_insert_element (NOTE, arg);
1316146515Sru      else if (strcasecmp (type, "important") == 0)
1317146515Sru        xml_insert_element (IMPORTANT, arg);
1318146515Sru      else if (strcasecmp (type, "warning") == 0)
1319146515Sru        xml_insert_element (WARNING, arg);
1320146515Sru      else if (strcasecmp (type, "caution") == 0)
1321146515Sru        xml_insert_element (CAUTION, arg);
1322146515Sru      else
1323146515Sru        /* Didn't find a known quotation type :\ */
1324146515Sru        quotation_started = 0;
1325146515Sru    }
1326146515Sru
1327146515Sru  if (!quotation_started)
1328146515Sru    {
1329146515Sru      xml_insert_element (QUOTATION, arg);
1330146515Sru      if (strlen(type) && arg == START)
1331146515Sru        execute_string ("@b{%s:} ", type);
1332146515Sru    }
1333146515Sru
1334146515Sru  if (arg == END)
1335146515Sru    {
1336146515Sru      QUOTATION_ELT *temp = quotation_stack;
1337146515Sru      if (temp == NULL)
1338146515Sru        return;
1339146515Sru      quotation_stack = quotation_stack->next;
1340146515Sru      free(temp->type);
1341146515Sru      free(temp);
1342146515Sru    }
1343146515Sru}
1344146515Sru
1345146515Sru/* Starting generic docbook floats.  Just starts elt with correct label
1346146515Sru   and id attributes, and inserts title.  */
1347146515Sruvoid
1348146515Sruxml_begin_docbook_float (int elt)
1349146515Sru{
1350146515Sru  if (current_float_used_title ())	/* in a nested float */
1351146515Sru    {
1352146515Sru      xml_insert_element (elt, START);	/* just insert the tag */
1353146515Sru      return;
1354146515Sru    }
1355146515Sru
1356146515Sru
1357146515Sru  /* OK, need the title, tag, etc. */
1358146515Sru  if (elt == CARTOUCHE)    /* no labels on <sidebar> */
1359146515Sru    {
1360146515Sru       if (strlen (current_float_id ()) == 0)
1361146515Sru          xml_insert_element (elt, START);
1362146515Sru       else
1363146515Sru          xml_insert_element_with_attribute (elt, START,
1364146515Sru              "id=\"%s\"", xml_id (current_float_id ()));
1365146515Sru    }
1366146515Sru  else if (strlen (current_float_id ()) == 0)
1367146515Sru    xml_insert_element_with_attribute (elt, START, "label=\"\"");
1368146515Sru  else
1369146515Sru    xml_insert_element_with_attribute (elt, START,
1370146515Sru        "id=\"%s\" label=\"%s\"", xml_id (current_float_id ()),
1371146515Sru        current_float_number ());
1372146515Sru
1373146515Sru  xml_insert_element (TITLE, START);
1374146515Sru  execute_string ("%s", current_float_title ());
1375146515Sru  xml_insert_element (TITLE, END);
1376146515Sru
1377146515Sru  current_float_set_title_used ();	/* mark this title, tag, etc used */
1378146515Sru}
1379146515Sru
138093139Sru/*
138193139Sru * Lists and Tables
138293139Sru */
138393139Sruvoid
1384146515Sruxml_begin_table (int type, char *item_function)
138593139Sru{
138693139Sru  switch (type)
138793139Sru    {
138893139Sru    case ftable:
138993139Sru    case vtable:
139093139Sru    case table:
139193139Sru      /*if (docbook)*/ /* 05-08 */
1392114472Sru        {
1393114472Sru          xml_insert_element (TABLE, START);
1394114472Sru          xml_table_level ++;
1395146515Sru          xml_in_tableitem[xml_table_level] = 0;
1396114472Sru          xml_in_item[xml_table_level] = 0;
1397146515Sru          xml_after_table_term = 0;
1398114472Sru        }
139993139Sru      break;
140093139Sru    case itemize:
140193139Sru      if (!docbook)
1402114472Sru        {
1403114472Sru          xml_insert_element (ITEMIZE, START);
1404114472Sru          xml_table_level ++;
1405114472Sru          xml_in_item[xml_table_level] = 0;
1406114472Sru          xml_insert_element (ITEMFUNCTION, START);
1407114472Sru          if (*item_function == COMMAND_PREFIX
1408114472Sru              && item_function[strlen (item_function) - 1] != '}'
1409114472Sru              && command_needs_braces (item_function + 1))
1410114472Sru            execute_string ("%s{}", item_function);
1411114472Sru          else
1412114472Sru            execute_string ("%s", item_function);
1413114472Sru          xml_insert_element (ITEMFUNCTION, END);
1414114472Sru        }
1415114472Sru      else
1416114472Sru        {
1417114472Sru          xml_insert_element_with_attribute (ITEMIZE, START,
1418114472Sru                                             "mark=\"%s\"",
1419114472Sru                                             (*item_function == COMMAND_PREFIX) ?
1420114472Sru                                             &item_function[1] : item_function);
1421114472Sru          xml_table_level ++;
1422114472Sru          xml_in_item[xml_table_level] = 0;
1423114472Sru        }
142493139Sru      break;
142593139Sru    }
142693139Sru}
142793139Sru
142893139Sruvoid
1429146515Sruxml_end_table (int type)
143093139Sru{
143193139Sru  switch (type)
143293139Sru    {
143393139Sru    case ftable:
143493139Sru    case vtable:
143593139Sru    case table:
1436146515Sru      if (xml_in_item[xml_table_level])
1437114472Sru        {
1438146515Sru          xml_insert_element (ITEM, END);
1439146515Sru          xml_in_item[xml_table_level] = 0;
1440114472Sru        }
1441146515Sru      if (xml_in_tableitem[xml_table_level])
1442146515Sru        {
1443146515Sru          xml_insert_element (TABLEITEM, END);
1444146515Sru          xml_in_tableitem[xml_table_level] = 0;
1445146515Sru        }
1446146515Sru      xml_insert_element (TABLE, END);
1447146515Sru      xml_after_table_term = 0;
1448146515Sru      xml_table_level --;
1449146515Sru
145093139Sru      break;
145193139Sru    case itemize:
145293139Sru      if (xml_in_item[xml_table_level])
1453114472Sru        {
1454114472Sru          xml_insert_element (ITEM, END);
1455114472Sru          xml_in_item[xml_table_level] = 0;
1456114472Sru        }
1457114472Sru      /* gnat-style manual contains an itemized list without items! */
1458114472Sru      if (in_table_title)
145993139Sru	{
1460114472Sru	  xml_insert_element (TITLE, END);
1461114472Sru	  in_table_title = 0;
146293139Sru	}
146393139Sru      xml_insert_element (ITEMIZE, END);
146493139Sru      xml_table_level --;
146593139Sru      break;
146693139Sru    }
146793139Sru}
146893139Sru
146993139Sruvoid
1470146515Sruxml_begin_item (void)
147193139Sru{
147293139Sru  if (xml_in_item[xml_table_level])
147393139Sru    xml_insert_element (ITEM, END);
147493139Sru
147593139Sru  xml_insert_element (ITEM, START);
147693139Sru  xml_in_item[xml_table_level] = 1;
147793139Sru}
147893139Sru
147993139Sruvoid
1480146515Sruxml_begin_table_item (void)
148193139Sru{
148293139Sru  if (!xml_after_table_term)
148393139Sru    {
148493139Sru      if (xml_in_item[xml_table_level])
1485146515Sru        xml_insert_element (ITEM, END);
1486146515Sru      if (xml_in_tableitem[xml_table_level])
1487146515Sru        xml_insert_element (TABLEITEM, END);
1488146515Sru
1489114472Sru      if (in_table_title)
149093139Sru	{
1491114472Sru	  in_table_title = 0;
1492114472Sru	  xml_insert_element (TITLE, END);
149393139Sru	}
149493139Sru      xml_insert_element (TABLEITEM, START);
149593139Sru    }
149693139Sru  xml_insert_element (TABLETERM, START);
1497146515Sru  xml_in_tableitem[xml_table_level] = 1;
1498146515Sru  xml_in_item[xml_table_level] = 0;
149993139Sru  xml_after_table_term = 0;
150093139Sru}
150193139Sru
150293139Sruvoid
1503146515Sruxml_continue_table_item (void)
150493139Sru{
150593139Sru  xml_insert_element (TABLETERM, END);
150693139Sru  xml_after_table_term = 1;
1507146515Sru  xml_in_item[xml_table_level] = 0;
150893139Sru}
150993139Sru
151093139Sruvoid
1511146515Sruxml_begin_enumerate (char *enum_arg)
151293139Sru{
151393139Sru  if (!docbook)
151493139Sru    xml_insert_element_with_attribute (ENUMERATE, START, "first=\"%s\"", enum_arg);
151593139Sru  else
1516114472Sru    {
151793139Sru      if (isdigit (*enum_arg))
1518146515Sru        {
1519146515Sru          int enum_val = atoi (enum_arg);
1520146515Sru
1521146515Sru          /* Have to check the value, not just the first digit.  */
1522146515Sru          if (enum_val == 0)
1523146515Sru            xml_insert_element_with_attribute (ENUMERATE, START,
1524146515Sru                "numeration=\"arabic\" role=\"0\"", NULL);
1525146515Sru          else if (enum_val == 1)
1526146515Sru            xml_insert_element_with_attribute (ENUMERATE, START,
1527146515Sru                "numeration=\"arabic\"", NULL);
1528146515Sru          else
1529146515Sru            xml_insert_element_with_attribute (ENUMERATE, START,
1530146515Sru                "continuation=\"continues\" numeration=\"arabic\"", NULL);
1531146515Sru        }
153293139Sru      else if (isupper (*enum_arg))
1533114472Sru        {
1534146515Sru          if (enum_arg[0] == 'A')
1535146515Sru            xml_insert_element_with_attribute (ENUMERATE, START,
1536146515Sru                "numeration=\"upperalpha\"", NULL);
1537146515Sru          else
1538146515Sru            xml_insert_element_with_attribute (ENUMERATE, START,
1539146515Sru                "continuation=\"continues\" numeration=\"upperalpha\"", NULL);
1540146515Sru        }
154193139Sru      else
1542114472Sru        {
1543114472Sru          if (enum_arg[0] == 'a')
1544146515Sru            xml_insert_element_with_attribute (ENUMERATE, START,
1545146515Sru                "numeration=\"loweralpha\"", NULL);
1546146515Sru          else
1547146515Sru            xml_insert_element_with_attribute (ENUMERATE, START,
1548146515Sru                "continuation=\"continues\" numeration=\"loweralpha\"", NULL);
1549114472Sru        }
155093139Sru    }
155193139Sru  xml_table_level ++;
155293139Sru  xml_in_item[xml_table_level] = 0;
155393139Sru}
155493139Sru
155593139Sruvoid
1556146515Sruxml_end_enumerate (void)
155793139Sru{
155893139Sru  if (xml_in_item[xml_table_level])
155993139Sru    {
156093139Sru      xml_insert_element (ITEM, END);
156193139Sru      xml_in_item[xml_table_level] = 0;
156293139Sru    }
156393139Sru  xml_insert_element (ENUMERATE, END);
156493139Sru  xml_table_level --;
156593139Sru}
156693139Sru
156793139Srustatic void
1568146515Sruxml_insert_text_file (char *name_arg)
156993139Sru{
157093139Sru  char *fullname = xmalloc (strlen (name_arg) + 4 + 1);
157193139Sru  FILE *image_file;
157293139Sru  strcpy (fullname, name_arg);
157393139Sru  strcat (fullname, ".txt");
157493139Sru  image_file = fopen (fullname, "r");
157593139Sru  if (image_file)
157693139Sru    {
157793139Sru      int ch;
157893139Sru      int save_inhibit_indentation = inhibit_paragraph_indentation;
157993139Sru      int save_filling_enabled = filling_enabled;
1580114472Sru
158193139Sru      xml_insert_element (TEXTOBJECT, START);
158293139Sru      xml_insert_element (DISPLAY, START);
158393139Sru
158493139Sru      inhibit_paragraph_indentation = 1;
158593139Sru      filling_enabled = 0;
158693139Sru      last_char_was_newline = 0;
1587114472Sru
158893139Sru      /* Maybe we need to remove the final newline if the image
1589114472Sru         file is only one line to allow in-line images.  On the
1590114472Sru         other hand, they could just make the file without a
1591114472Sru         final newline.  */
159293139Sru      while ((ch = getc (image_file)) != EOF)
1593114472Sru        add_char (ch);
1594114472Sru
159593139Sru      inhibit_paragraph_indentation = save_inhibit_indentation;
159693139Sru      filling_enabled = save_filling_enabled;
159793139Sru
159893139Sru      xml_insert_element (DISPLAY, END);
159993139Sru      xml_insert_element (TEXTOBJECT, END);
1600114472Sru
160193139Sru      if (fclose (image_file) != 0)
1602114472Sru        perror (fullname);
160393139Sru    }
160493139Sru  else
160593139Sru    warning (_("@image file `%s' unreadable: %s"), fullname,
1606114472Sru             strerror (errno));
1607114472Sru
160893139Sru  free (fullname);
160993139Sru}
161093139Sru
1611146515Sru/* If NAME.EXT is accessible or FORCE is nonzero, insert a docbook
1612146515Sru   imagedata element for FMT.  Return 1 if inserted something, 0 else.  */
1613146515Sru
1614146515Srustatic int
1615146515Srutry_docbook_image (const char *name, const char *ext, const char *fmt,
1616146515Sru                   int force)
1617146515Sru{
1618146515Sru  int used = 0;
1619146515Sru  char *fullname = xmalloc (strlen (name) + 1 + strlen (ext) + 1);
1620146515Sru  sprintf (fullname, "%s.%s", name, ext);
1621146515Sru
1622146515Sru  if (force || access (fullname, R_OK) == 0)
1623146515Sru   {
1624146515Sru     xml_insert_element (IMAGEOBJECT, START);
1625146515Sru     xml_insert_element_with_attribute (IMAGEDATA, START,
1626146515Sru       "fileref=\"%s\" format=\"%s\"", fullname, fmt);
1627146515Sru     xml_insert_element (IMAGEDATA, END);
1628146515Sru     xml_insert_element (IMAGEOBJECT, END);
1629146515Sru     used = 1;
1630146515Sru   }
1631146515Sru
1632146515Sru free (fullname);
1633146515Sru return used;
1634146515Sru}
1635146515Sru
1636146515Sru
163793139Sruvoid
1638146515Sruxml_insert_docbook_image (char *name_arg)
163993139Sru{
1640146515Sru  int found = 0;
1641146515Sru  int elt = xml_in_para ? INLINEIMAGE : MEDIAOBJECT;
164293139Sru
1643146515Sru  if (is_in_insertion_of_type (floatenv))
1644146515Sru    xml_begin_docbook_float (INFORMALFIGURE);
1645146515Sru  else if (!xml_in_para)
1646146515Sru    xml_insert_element (INFORMALFIGURE, START);
164793139Sru
1648146515Sru  xml_no_para++;
164993139Sru
1650146515Sru  xml_insert_element (elt, START);
1651146515Sru
1652146515Sru  /* A selected few from http://docbook.org/tdg/en/html/imagedata.html.  */
1653146515Sru  if (try_docbook_image (name_arg, "eps", "EPS", 0))
1654146515Sru    found++;
1655146515Sru  if (try_docbook_image (name_arg, "gif", "GIF", 0))
1656146515Sru    found++;
1657146515Sru  if (try_docbook_image (name_arg, "jpg", "JPG", 0))
1658146515Sru    found++;
1659146515Sru  if (try_docbook_image (name_arg, "jpeg", "JPEG", 0))
1660146515Sru    found++;
1661146515Sru  if (try_docbook_image (name_arg, "pdf", "PDF", 0))
1662146515Sru    found++;
1663146515Sru  if (try_docbook_image (name_arg, "png", "PNG", 0))
1664146515Sru    found++;
1665146515Sru  if (try_docbook_image (name_arg, "svg", "SVG", 0))
1666146515Sru    found++;
1667146515Sru
1668146515Sru  /* If no luck so far, just assume we'll eventually have a jpg.  */
1669146515Sru  if (!found)
1670146515Sru    try_docbook_image (name_arg, "jpg", "JPG", 1);
1671146515Sru
167293139Sru  xml_insert_text_file (name_arg);
1673146515Sru  xml_insert_element (elt, END);
167493139Sru
1675146515Sru  xml_no_para--;
1676146515Sru
1677146515Sru  if (elt == MEDIAOBJECT)
1678146515Sru    xml_insert_element (INFORMALFIGURE, END);
167993139Sru}
168093139Sru
168193139Sruvoid
1682146515Sruxml_asterisk (void)
168393139Sru{
168493139Sru}
168593139Sru
168693139Sru
168793139Sru/*
168893139Sru *     INDEX
168993139Sru */
1690114472Sru/* Used to separate primary and secondary entries in an index -- we need
1691114472Sru   to have real multilivel indexing support, not just string analysis.  */
1692114472Sru#define INDEX_SEP "@this string will never appear@" /* was , */
169393139Sru
1694146515Srutypedef struct
1695146515Sru{
1696146515Sru  char *from;
1697146515Sru  char *to;
1698146515Sru} XML_SYNONYM;
1699146515Sru
1700146515Srustatic XML_SYNONYM **xml_synonyms = NULL;
1701146515Srustatic int xml_synonyms_count = 0;
1702146515Sru
1703116525Sruvoid
1704146515Sruxml_insert_indexterm (char *indexterm, char *index)
170593139Sru{
1706146515Sru  /* @index commands can appear between @item and @itemx, @deffn and @deffnx.  */
170793139Sru  if (!docbook)
170893139Sru    {
1709146515Sru      /* Check to see if we need to do index redirection per @synindex.  */
1710146515Sru      int i;
1711146515Sru      for (i = 0; i < xml_synonyms_count; i++)
1712146515Sru        {
1713146515Sru          if (STREQ (xml_synonyms[i]->from, index))
1714146515Sru            index = xstrdup (xml_synonyms[i]->to);
1715146515Sru        }
1716146515Sru
1717146515Sru      xml_dont_touch_items_defs++;
171893139Sru      xml_insert_element_with_attribute (INDEXTERM, START, "index=\"%s\"", index);
1719114472Sru      in_indexterm = 1;
172093139Sru      execute_string ("%s", indexterm);
172193139Sru      xml_insert_element (INDEXTERM, END);
1722114472Sru      in_indexterm = 0;
1723146515Sru      xml_dont_touch_items_defs--;
172493139Sru    }
172593139Sru  else
1726114472Sru    {
1727146515Sru      char *primary = NULL, *secondary = NULL;
1728114472Sru      if (strstr (indexterm+1, INDEX_SEP))
1729114472Sru        {
1730114472Sru          primary = xmalloc (strlen (indexterm) + 1);
1731114472Sru          strcpy (primary, indexterm);
1732114472Sru          secondary = strstr (primary+1, INDEX_SEP);
1733114472Sru          *secondary = '\0';
1734114472Sru          secondary += strlen (INDEX_SEP);
1735114472Sru        }
173693139Sru      xml_insert_element_with_attribute (INDEXTERM, START, "role=\"%s\"", index);
1737114472Sru      in_indexterm = 1;
173893139Sru      xml_insert_element (PRIMARY, START);
173993139Sru      if (primary)
1740146515Sru        execute_string ("%s", primary);
174193139Sru      else
1742146515Sru        execute_string ("%s", indexterm);
174393139Sru      xml_insert_element (PRIMARY, END);
174493139Sru      if (primary)
1745114472Sru        {
1746114472Sru          xml_insert_element (SECONDARY, START);
1747146515Sru          execute_string ("%s", secondary);
1748114472Sru          xml_insert_element (SECONDARY, END);
1749114472Sru        }
175093139Sru      xml_insert_element (INDEXTERM, END);
1751114472Sru      in_indexterm = 0;
175293139Sru    }
175393139Sru}
175493139Sru
175593139Sru
175693139Sruint xml_last_section_output_position = 0;
175793139Srustatic char last_division_letter = ' ';
175893139Srustatic char index_primary[2000]; /** xx no fixed limit */
175993139Srustatic int indexdivempty = 0;
176093139Sru
1761114472Srustatic void
1762146515Sruxml_close_indexentry (void)
176393139Sru{
176493139Sru  if (!in_indexentry)
176593139Sru    return;
176693139Sru  if (in_secondary)
176793139Sru    xml_insert_element (SECONDARYIE, END);
176893139Sru  xml_insert_element (INDEXENTRY, END);
176993139Sru  in_secondary = 0;
177093139Sru  in_indexentry = 0;
177193139Sru}
177293139Sru
177393139Sruvoid
1774146515Sruxml_begin_index (void)
177593139Sru{
1776146515Sru  typedef struct xml_index_title {
1777146515Sru      struct xml_index_title *next;
1778146515Sru      char *title;
1779146515Sru  } XML_INDEX_TITLE;
178093139Sru
1781146515Sru  static XML_INDEX_TITLE *xml_index_titles = NULL;
178293139Sru
1783146515Sru  if (!handling_delayed_writes)
1784146515Sru    { /* We assume that we just opened a section, and so that the last output is
1785146515Sru         <SECTION ID="node-name"><TITLE>Title</TITLE>
1786146515Sru         where SECTION can be CHAPTER, ...  */
178793139Sru
1788146515Sru      XML_INDEX_TITLE *new = xmalloc (sizeof (XML_INDEX_TITLE));
1789146515Sru      xml_section *temp = last_section;
179093139Sru
1791146515Sru      int l = output_paragraph_offset-xml_last_section_output_position;
1792146515Sru      char *tmp = xmalloc (l+1);
1793146515Sru      char *p = tmp;
1794146515Sru      strncpy (tmp, (char *) output_paragraph, l);
179593139Sru
1796146515Sru      /* We remove <SECTION */
1797146515Sru      tmp[l] = '\0';
1798146515Sru      while (*p != '<')
1799146515Sru        p++;
1800146515Sru      while (*p != ' ')
1801146515Sru        p++;
1802146515Sru      /* ... and its label attribute.  */
1803146515Sru      if (strncmp (p, " label=", 7) == 0)
1804146515Sru        {
1805146515Sru          p++;
1806146515Sru          while (*p != ' ')
1807146515Sru            p++;
1808146515Sru        }
1809114472Sru
1810146515Sru      output_paragraph_offset = xml_last_section_output_position;
1811146515Sru      xml_last_section_output_position = 0;
1812146515Sru
1813146515Sru      xml_pop_current_element (); /* remove section element from elements stack */
1814146515Sru
1815146515Sru      if (last_section)
1816146515Sru        last_section = last_section->prev; /* remove section from sections stack */
1817146515Sru      if (temp)
1818146515Sru        {
1819146515Sru          free (temp->name);
1820146515Sru          free (temp);
1821146515Sru        }
1822146515Sru
1823146515Sru      new->title = xstrdup (p);
1824146515Sru      new->next = xml_index_titles;
1825146515Sru      xml_index_titles = new;
1826146515Sru    }
1827146515Sru  else
1828114472Sru    {
1829146515Sru      static int xml_index_titles_reversed = 0;
1830114472Sru
1831146515Sru      if (!xml_index_titles_reversed)
1832146515Sru        {
1833146515Sru          xml_index_titles = (XML_INDEX_TITLE *) reverse_list
1834146515Sru            ((GENERIC_LIST *) xml_index_titles);
1835146515Sru          xml_index_titles_reversed = 1;
1836146515Sru        }
183793139Sru
1838146515Sru      /* We put <INDEX> */
1839146515Sru      xml_insert_element (PRINTINDEX, START);
1840146515Sru      if (xml_index_titles)
1841146515Sru        {
1842146515Sru          /* Remove the final > */
1843146515Sru          output_paragraph_offset--;
1844146515Sru          /* and put  ID="node-name"><TITLE>Title</TITLE> */
1845146515Sru          insert_string (xml_index_titles->title);
1846146515Sru          free (xml_index_titles->title);
1847146515Sru          xml_index_titles = xml_index_titles->next;
1848146515Sru        }
184993139Sru
1850146515Sru      if (xml_index_divisions)
1851146515Sru        {
1852146515Sru          xml_insert_element (INDEXDIV, START);
1853146515Sru          indexdivempty = 1;
1854146515Sru        }
185593139Sru    }
185693139Sru}
185793139Sru
185893139Sruvoid
1859146515Sruxml_end_index (void)
186093139Sru{
186193139Sru  xml_close_indexentry ();
1862114472Sru  if (xml_index_divisions)
186393139Sru    xml_insert_element (INDEXDIV, END);
1864114472Sru  xml_insert_element (PRINTINDEX, END);
186593139Sru}
186693139Sru
1867146515Srustatic void
1868146515Sruxml_index_divide (char *entry)
186993139Sru{
187093139Sru  char c;
1871114472Sru  if (strlen (entry) > (strlen (xml_element_list[CODE].name) + 2) &&
1872114472Sru      strncmp (entry+1, xml_element_list[CODE].name, strlen (xml_element_list[CODE].name)) == 0)
187393139Sru    c = entry[strlen (xml_element_list[CODE].name)+2];
1874114472Sru  else
187593139Sru    c = entry[0];
187693139Sru  if (tolower (c) != last_division_letter && isalpha (c))
187793139Sru    {
187893139Sru      last_division_letter = tolower (c);
187993139Sru      xml_close_indexentry ();
188093139Sru      if (!indexdivempty)
1881114472Sru        {
1882114472Sru          xml_insert_element (INDEXDIV, END);
1883114472Sru          xml_insert_element (INDEXDIV, START);
1884114472Sru        }
188593139Sru      xml_insert_element (TITLE, START);
188693139Sru      insert (toupper (c));
188793139Sru      xml_insert_element (TITLE, END);
188893139Sru    }
188993139Sru}
189093139Sru
189193139Sruvoid
1892146515Sruxml_insert_indexentry (char *entry, char *node)
189393139Sru{
189493139Sru  char *primary = NULL, *secondary;
189593139Sru  if (xml_index_divisions)
189693139Sru    xml_index_divide (entry);
189793139Sru
189893139Sru  indexdivempty = 0;
189993139Sru  if (strstr (entry+1, INDEX_SEP))
190093139Sru    {
190193139Sru      primary = xmalloc (strlen (entry) + 1);
190293139Sru      strcpy (primary, entry);
190393139Sru      secondary = strstr (primary+1, INDEX_SEP);
190493139Sru      *secondary = '\0';
190593139Sru      secondary += strlen (INDEX_SEP);
190693139Sru
190793139Sru      if (in_secondary && strcmp (primary, index_primary) == 0)
1908114472Sru        {
1909114472Sru          xml_insert_element (SECONDARYIE, END);
1910114472Sru          xml_insert_element (SECONDARYIE, START);
1911146515Sru          execute_string ("%s", secondary);
1912114472Sru        }
191393139Sru      else
1914114472Sru        {
1915114472Sru          xml_close_indexentry ();
1916114472Sru          xml_insert_element (INDEXENTRY, START);
1917114472Sru          in_indexentry = 1;
1918114472Sru          xml_insert_element (PRIMARYIE, START);
1919146515Sru          execute_string ("%s", primary);
1920114472Sru          xml_insert_element (PRIMARYIE, END);
1921114472Sru          xml_insert_element (SECONDARYIE, START);
1922146515Sru          execute_string ("%s", secondary);
1923114472Sru          in_secondary = 1;
1924114472Sru        }
192593139Sru    }
192693139Sru  else
192793139Sru    {
192893139Sru      xml_close_indexentry ();
192993139Sru      xml_insert_element (INDEXENTRY, START);
193093139Sru      in_indexentry = 1;
193193139Sru      xml_insert_element (PRIMARYIE, START);
1932146515Sru      execute_string ("%s", entry);
193393139Sru    }
1934146515Sru  add_word (", ");
193593139Sru
1936146515Sru  /* Don't link to @unnumbered sections directly.
1937146515Sru     We are disabling warnings temporarily, otherwise these xrefs
1938146515Sru     will cause bogus warnings about missing punctuation.  */
1939146515Sru  {
1940146515Sru    extern int print_warnings;
1941146515Sru    int save_print_warnings = print_warnings;
1942146515Sru    print_warnings = 0;
1943146515Sru    execute_string ("%cxref{%s}", COMMAND_PREFIX, xstrdup (node));
1944146515Sru    print_warnings = save_print_warnings;
1945146515Sru  }
1946146515Sru
194793139Sru  if (primary)
194893139Sru    {
194993139Sru      strcpy (index_primary, primary);
195093139Sru      /*      xml_insert_element (SECONDARYIE, END);*/
195193139Sru      /*     *(secondary-1) = ',';*/ /* necessary ? */
195293139Sru      free (primary);
195393139Sru    }
195493139Sru  else
195593139Sru    xml_insert_element (PRIMARYIE, END);
195693139Sru
195793139Sru  /*  xml_insert_element (INDEXENTRY, END); */
195893139Sru}
195993139Sru
1960146515Sruvoid
1961146515Sruxml_synindex (char *from, char *to)
1962146515Sru{
1963146515Sru  int i, slot;
1964146515Sru
1965146515Sru  slot = -1;
1966146515Sru  for (i = 0; i < xml_synonyms_count; i++)
1967146515Sru    if (!xml_synonyms[i])
1968146515Sru      {
1969146515Sru        slot = i;
1970146515Sru        break;
1971146515Sru      }
1972146515Sru
1973146515Sru  if (slot < 0)
1974146515Sru    {
1975146515Sru      slot = xml_synonyms_count;
1976146515Sru      xml_synonyms_count++;
1977146515Sru
1978146515Sru      xml_synonyms = (XML_SYNONYM **) xrealloc (xml_synonyms,
1979146515Sru          (xml_synonyms_count + 1) * sizeof (XML_SYNONYM *));
1980146515Sru    }
1981146515Sru
1982146515Sru  xml_synonyms[slot] = xmalloc (sizeof (XML_SYNONYM));
1983146515Sru  xml_synonyms[slot]->from = xstrdup (from);
1984146515Sru  xml_synonyms[slot]->to = xstrdup (to);
1985146515Sru}
1986146515Sru
198793139Sru/*
198893139Sru * MULTITABLE
198993139Sru */
1990146515Sru
1991146515Srustatic int multitable_columns_count;
1992146515Srustatic int *multitable_column_widths;
1993146515Sru
199493139Sruvoid
1995146515Sruxml_begin_multitable (int ncolumns, int *column_widths)
199693139Sru{
199793139Sru  int i;
199893139Sru  if (docbook)
199993139Sru    {
2000146515Sru      if (is_in_insertion_of_type (floatenv))
2001146515Sru        xml_begin_docbook_float (MULTITABLE);
2002146515Sru      else
2003146515Sru        xml_insert_element (MULTITABLE, START);
2004146515Sru
2005146515Sru      multitable_columns_count = ncolumns;
2006146515Sru      multitable_column_widths = xmalloc (sizeof (int) * ncolumns);
2007146515Sru      memcpy (multitable_column_widths, column_widths,
2008146515Sru          sizeof (int) * ncolumns);
2009146515Sru
201093139Sru      xml_no_para = 1;
201193139Sru    }
2012114472Sru  else
201393139Sru    {
201493139Sru      xml_insert_element (MULTITABLE, START);
201593139Sru      for (i=0; i<ncolumns; i++)
2016114472Sru        {
2017114472Sru          xml_insert_element (COLSPEC, START);
2018114472Sru          add_word_args ("%d", column_widths[i]);
2019114472Sru          xml_insert_element (COLSPEC, END);
2020114472Sru        }
202193139Sru      xml_no_para = 1;
202293139Sru    }
202393139Sru}
202493139Sru
2025146515Srustatic void
2026146515Sruxml_begin_multitable_group (void)
2027146515Sru{
2028146515Sru  int i;
2029146515Sru
2030146515Sru  xml_insert_element_with_attribute (TGROUP, START, "cols=\"%d\"",
2031146515Sru      multitable_columns_count);
2032146515Sru
2033146515Sru  for (i=0; i < multitable_columns_count; i++)
2034146515Sru    {
2035146515Sru      xml_insert_element_with_attribute (COLSPEC, START,
2036146515Sru          "colwidth=\"%d*\"", multitable_column_widths[i]);
2037146515Sru      xml_insert_element (COLSPEC, END);
2038146515Sru    }
2039146515Sru}
2040146515Sru
204193139Sruvoid
2042146515Sruxml_end_multitable_row (int first_row)
204393139Sru{
204493139Sru  if (!first_row)
204593139Sru    {
204693139Sru      xml_insert_element (ENTRY, END);
204793139Sru      xml_insert_element (ROW, END);
204893139Sru    }
2049146515Sru
2050146515Sru  if (headitem_flag)
2051146515Sru    {
2052146515Sru      if (!first_row)
2053146515Sru        {
2054146515Sru          if (after_headitem)
2055146515Sru            xml_insert_element (THEAD, END);
2056146515Sru          else
2057146515Sru            xml_insert_element (TBODY, END);
2058146515Sru          xml_insert_element (TGROUP, END);
2059146515Sru        }
2060146515Sru
2061146515Sru      xml_begin_multitable_group ();
2062146515Sru      xml_insert_element (THEAD, START);
2063146515Sru    }
2064146515Sru  else if (first_row)
2065146515Sru    {
2066146515Sru      xml_begin_multitable_group ();
2067146515Sru      xml_insert_element (TBODY, START);
2068146515Sru    }
2069146515Sru  else if (after_headitem)
2070146515Sru    {
2071146515Sru      xml_insert_element (THEAD, END);
2072146515Sru      xml_insert_element (TBODY, START);
2073146515Sru    }
2074146515Sru  else if (first_row)
2075146515Sru    xml_insert_element (TBODY, START);
2076146515Sru
207793139Sru  xml_insert_element (ROW, START);
207893139Sru  xml_insert_element (ENTRY, START);
207993139Sru}
208093139Sru
208193139Sruvoid
2082146515Sruxml_end_multitable_column (void)
208393139Sru{
208493139Sru  xml_insert_element (ENTRY, END);
208593139Sru  xml_insert_element (ENTRY, START);
208693139Sru}
208793139Sru
208893139Sruvoid
2089146515Sruxml_end_multitable (void)
209093139Sru{
2091146515Sru  xml_insert_element (ENTRY, END);
2092146515Sru  xml_insert_element (ROW, END);
2093146515Sru
2094146515Sru  if (after_headitem)
209593139Sru    {
2096146515Sru      if (docbook)
2097146515Sru        warning (_("@headitem as the last item of @multitable produces invalid Docbook documents"));
2098146515Sru      xml_insert_element (THEAD, END);
209993139Sru    }
2100114472Sru  else
2101146515Sru    xml_insert_element (TBODY, END);
2102146515Sru
2103146515Sru  if (docbook)
2104146515Sru    xml_insert_element (TGROUP, END);
2105146515Sru
2106146515Sru  xml_insert_element (MULTITABLE, END);
2107146515Sru  xml_no_para = 0;
2108146515Sru}
2109146515Sru
2110146515Sru/*
2111146515Sru * Parameters in @def definitions
2112146515Sru */
2113146515Sru
2114146515Sru#define DEFUN_SELF_DELIMITING(c) \
2115146515Sru  ((c) == '(' || (c) == ')' || (c) == '[' || (c) == ']')
2116146515Sru
2117146515Sruvoid
2118146515Sruxml_process_defun_args (char **defun_args, int auto_var_p)
2119146515Sru{
2120146515Sru  int pending_space = 0;
2121146515Sru  int just_after_paramtype = 0;
2122146515Sru
2123146515Sru  for (;;)
212493139Sru    {
2125146515Sru      char *defun_arg = *defun_args++;
2126146515Sru
2127146515Sru      if (defun_arg == NULL)
2128146515Sru        break;
2129146515Sru
2130146515Sru      if (defun_arg[0] == ' ')
2131146515Sru        {
2132146515Sru          pending_space = 1;
2133146515Sru          continue;
2134146515Sru        }
2135146515Sru
2136146515Sru      if (pending_space)
2137146515Sru        {
2138146515Sru          add_char (' ');
2139146515Sru          pending_space = 0;
2140146515Sru        }
2141146515Sru
2142146515Sru      if (DEFUN_SELF_DELIMITING (defun_arg[0]))
2143146515Sru        {
2144146515Sru	  xml_insert_element (DEFDELIMITER, START);
2145146515Sru          add_char (defun_arg[0]);
2146146515Sru	  xml_insert_element (DEFDELIMITER, END);
2147146515Sru	  just_after_paramtype = 0;
2148146515Sru        }
2149146515Sru      else if (defun_arg[0] == '&')
2150146515Sru	{
2151146515Sru	  xml_insert_element (DEFPARAM, START);
2152146515Sru	  add_word (defun_arg);
2153146515Sru	  xml_insert_element (DEFPARAM, END);
2154146515Sru	  just_after_paramtype = 0;
2155146515Sru	}
2156146515Sru      else if (defun_arg[0] == COMMAND_PREFIX || just_after_paramtype)
2157146515Sru	{
2158146515Sru	  xml_insert_element (DEFPARAM, START);
2159146515Sru	  execute_string ("%s", defun_arg);
2160146515Sru	  xml_insert_element (DEFPARAM, END);
2161146515Sru	  just_after_paramtype = 0;
2162146515Sru	}
2163146515Sru      else if (defun_arg[0] == ',' || defun_arg[0] == ';')
2164146515Sru	{
2165146515Sru	  xml_insert_element (DEFDELIMITER, START);
2166146515Sru	  add_word (defun_arg);
2167146515Sru	  xml_insert_element (DEFDELIMITER, END);
2168146515Sru	  just_after_paramtype = 0;
2169146515Sru	}
2170146515Sru      else if (auto_var_p)
2171146515Sru	{
2172146515Sru	  xml_insert_element (DEFPARAM, START);
2173146515Sru	  add_word (defun_arg);
2174146515Sru	  xml_insert_element (DEFPARAM, END);
2175146515Sru	  just_after_paramtype = 0;
2176146515Sru	}
2177146515Sru      else
2178146515Sru	{
2179146515Sru	  xml_insert_element (DEFPARAMTYPE, START);
2180146515Sru	  add_word (defun_arg);
2181146515Sru	  xml_insert_element (DEFPARAMTYPE, END);
2182146515Sru	  just_after_paramtype = 1;
2183146515Sru	}
218493139Sru    }
218593139Sru}
2186146515Sru
2187146515Sruvoid
2188146515Sruxml_begin_definition (void)
2189146515Sru{
2190146515Sru  xml_insert_element (DEFINITION, START);
2191146515Sru  xml_definition_level ++;
2192146515Sru  xml_in_def_item[xml_definition_level] = 0;
2193146515Sru}
2194146515Sru
2195146515Sruvoid
2196146515Sruxml_end_definition (void)
2197146515Sru{
2198146515Sru  if (xml_in_def_item[xml_definition_level])
2199146515Sru    {
2200146515Sru      xml_insert_element (DEFINITIONITEM, END);
2201146515Sru      xml_in_def_item[xml_definition_level] = 0;
2202146515Sru    }
2203146515Sru  xml_after_def_term = 0;
2204146515Sru  xml_insert_element (DEFINITION, END);
2205146515Sru  xml_definition_level --;
2206146515Sru}
2207146515Sru
2208146515Sruvoid
2209146515Sruxml_begin_def_term (int base_type, const char *category,
2210146515Sru    char *defined_name, char *type_name, char *type_name2)
2211146515Sru{
2212146515Sru  xml_after_def_term = 0;
2213146515Sru  xml_insert_element (DEFINITIONTERM, START);
2214146515Sru
2215146515Sru  /* Index entry */
2216146515Sru  switch (base_type)
2217146515Sru    {
2218146515Sru    case deffn:
2219146515Sru    case deftypefn:
2220146515Sru      execute_string ("@findex %s\n", defined_name);
2221146515Sru      break;
2222146515Sru    case defvr:
2223146515Sru    case deftypevr:
2224146515Sru    case defcv:
2225146515Sru      execute_string ("@vindex %s\n", defined_name);
2226146515Sru      break;
2227146515Sru    case deftypecv:
2228146515Sru    case deftypeivar:
2229146515Sru      execute_string ("@vindex %s %s %s\n", defined_name, _("of"), type_name);
2230146515Sru      break;
2231146515Sru    case deftypemethod:
2232146515Sru    case defop:
2233146515Sru    case deftypeop:
2234146515Sru      execute_string ("@findex %s %s %s\n", defined_name, _("on"), type_name);
2235146515Sru      break;
2236146515Sru    case deftp:
2237146515Sru      execute_string ("@tindex %s\n", defined_name);
2238146515Sru      break;
2239146515Sru    }
2240146515Sru
2241146515Sru  /* Start with category.  */
2242146515Sru  xml_insert_element (DEFCATEGORY, START);
2243146515Sru  execute_string (docbook ? "--- %s:" : "%s", category);
2244146515Sru  xml_insert_element (DEFCATEGORY, END);
2245146515Sru  add_char(' ');
2246146515Sru
2247146515Sru  /* Output type name first for typed definitions.  */
2248146515Sru  switch (base_type)
2249146515Sru    {
2250146515Sru    case deffn:
2251146515Sru    case defvr:
2252146515Sru    case deftp:
2253146515Sru      break;
2254146515Sru
2255146515Sru    case deftypefn:
2256146515Sru    case deftypevr:
2257146515Sru      xml_insert_element (DEFTYPE, START);
2258146515Sru      execute_string ("%s", type_name);
2259146515Sru      xml_insert_element (DEFTYPE, END);
2260146515Sru      add_char (' ');
2261146515Sru      break;
2262146515Sru
2263146515Sru    case deftypecv:
2264146515Sru    case deftypeivar:
2265146515Sru    case deftypemethod:
2266146515Sru    case deftypeop:
2267146515Sru      xml_insert_element (DEFTYPE, START);
2268146515Sru      execute_string ("%s", type_name2);
2269146515Sru      xml_insert_element (DEFTYPE, END);
2270146515Sru      add_char (' ');
2271146515Sru      break;
2272146515Sru
2273146515Sru    default:
2274146515Sru      xml_insert_element (DEFCLASS, START);
2275146515Sru      execute_string ("%s", type_name);
2276146515Sru      xml_insert_element (DEFCLASS, END);
2277146515Sru      add_char (' ');
2278146515Sru      break;
2279146515Sru    }
2280146515Sru
2281146515Sru  /* Categorize rest of the definitions.  */
2282146515Sru  switch (base_type)
2283146515Sru    {
2284146515Sru    case deffn:
2285146515Sru    case deftypefn:
2286146515Sru      xml_insert_element (DEFFUNCTION, START);
2287146515Sru      execute_string ("%s", defined_name);
2288146515Sru      xml_insert_element (DEFFUNCTION, END);
2289146515Sru      break;
2290146515Sru
2291146515Sru    case defvr:
2292146515Sru    case deftypevr:
2293146515Sru      xml_insert_element (DEFVARIABLE, START);
2294146515Sru      execute_string ("%s", defined_name);
2295146515Sru      xml_insert_element (DEFVARIABLE, END);
2296146515Sru      break;
2297146515Sru
2298146515Sru    case deftp:
2299146515Sru      xml_insert_element (DEFDATATYPE, START);
2300146515Sru      execute_string ("%s", defined_name);
2301146515Sru      xml_insert_element (DEFDATATYPE, END);
2302146515Sru      break;
2303146515Sru
2304146515Sru    case defcv:
2305146515Sru    case deftypecv:
2306146515Sru    case deftypeivar:
2307146515Sru      xml_insert_element (DEFCLASSVAR, START);
2308146515Sru      execute_string ("%s", defined_name);
2309146515Sru      xml_insert_element (DEFCLASSVAR, END);
2310146515Sru      break;
2311146515Sru
2312146515Sru    case defop:
2313146515Sru    case deftypeop:
2314146515Sru    case deftypemethod:
2315146515Sru      /* Operation / Method */
2316146515Sru      xml_insert_element (DEFOPERATION, START);
2317146515Sru      execute_string ("%s", defined_name);
2318146515Sru      xml_insert_element (DEFOPERATION, END);
2319146515Sru      break;
2320146515Sru    }
2321146515Sru}
2322146515Sru
2323146515Sruvoid
2324146515Sruxml_end_def_term (void)
2325146515Sru{
2326146515Sru  xml_insert_element (DEFINITIONTERM, END);
2327146515Sru  xml_after_def_term = 1;
2328146515Sru}
2329