xref: /openbsd-src/gnu/usr.bin/texinfo/makeinfo/xml.c (revision 2aa28d40be840ec36ac7652a87eedb182920201f)
1f8dd34f6Sespie /* xml.c -- xml output.
2*2aa28d40Sguenther    $Id: xml.c,v 1.4 2024/08/16 22:57:44 guenther Exp $
3f8dd34f6Sespie 
4a1acfa9bSespie    Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
5f8dd34f6Sespie 
6f8dd34f6Sespie    This program is free software; you can redistribute it and/or modify
7f8dd34f6Sespie    it under the terms of the GNU General Public License as published by
8f8dd34f6Sespie    the Free Software Foundation; either version 2, or (at your option)
9f8dd34f6Sespie    any later version.
10f8dd34f6Sespie 
11f8dd34f6Sespie    This program is distributed in the hope that it will be useful,
12f8dd34f6Sespie    but WITHOUT ANY WARRANTY; without even the implied warranty of
13f8dd34f6Sespie    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14f8dd34f6Sespie    GNU General Public License for more details.
15f8dd34f6Sespie 
16f8dd34f6Sespie    You should have received a copy of the GNU General Public License
17f8dd34f6Sespie    along with this program; if not, write to the Free Software
18f8dd34f6Sespie    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19f8dd34f6Sespie 
20a1acfa9bSespie    Originally written by Philippe Martin <feloy@free.fr>.  */
21f8dd34f6Sespie 
22f8dd34f6Sespie #include "system.h"
23f8dd34f6Sespie #include "makeinfo.h"
24f8dd34f6Sespie #include "insertion.h"
25a1acfa9bSespie #include "files.h"
26a1acfa9bSespie #include "float.h"
27f8dd34f6Sespie #include "macro.h"
28f8dd34f6Sespie #include "cmds.h"
29f8dd34f6Sespie #include "lang.h"
30f8dd34f6Sespie 
31f8dd34f6Sespie #include "xml.h"
32f8dd34f6Sespie 
33f8dd34f6Sespie /* Options */
34f8dd34f6Sespie int xml_index_divisions = 1;
35f8dd34f6Sespie 
36f8dd34f6Sespie typedef struct _element
37f8dd34f6Sespie {
38f8dd34f6Sespie   char name[32];
39f8dd34f6Sespie   int contains_para;
40f8dd34f6Sespie   int contained_in_para;
41a1acfa9bSespie   int keep_space;
42f8dd34f6Sespie } element;
43f8dd34f6Sespie 
44f8dd34f6Sespie element texinfoml_element_list [] = {
45a1acfa9bSespie   { "texinfo",             1, 0, 0 },
46a1acfa9bSespie   { "setfilename",         0, 0, 0 },
47a1acfa9bSespie   { "titlefont",           0, 0, 0 },
48a1acfa9bSespie   { "settitle",            0, 0, 0 },
49a1acfa9bSespie   { "documentdescription", 1, 0, 0 },
50f8dd34f6Sespie 
51a1acfa9bSespie   { "node",                1, 0, 0 },
52a1acfa9bSespie   { "nodenext",            0, 0, 0 },
53a1acfa9bSespie   { "nodeprev",            0, 0, 0 },
54a1acfa9bSespie   { "nodeup",              0, 0, 0 },
55f8dd34f6Sespie 
56a1acfa9bSespie   { "chapter",             1, 0, 0 },
57a1acfa9bSespie   { "section",             1, 0, 0 },
58a1acfa9bSespie   { "subsection",          1, 0, 0 },
59a1acfa9bSespie   { "subsubsection",       1, 0, 0 },
60f8dd34f6Sespie 
61a1acfa9bSespie   { "top",                 1, 0, 0 },
62a1acfa9bSespie   { "unnumbered",          1, 0, 0 },
63a1acfa9bSespie   { "unnumberedsec",       1, 0, 0 },
64a1acfa9bSespie   { "unnumberedsubsec",    1, 0, 0 },
65a1acfa9bSespie   { "unnumberedsubsubsec", 1, 0, 0 },
66f8dd34f6Sespie 
67a1acfa9bSespie   { "appendix",            1, 0, 0 },
68a1acfa9bSespie   { "appendixsec",         1, 0, 0 },
69a1acfa9bSespie   { "appendixsubsec",      1, 0, 0 },
70a1acfa9bSespie   { "appendixsubsubsec",   1, 0, 0 },
71f8dd34f6Sespie 
72a1acfa9bSespie   { "majorheading",        0, 0, 0 },
73a1acfa9bSespie   { "chapheading",         0, 0, 0 },
74a1acfa9bSespie   { "heading",             0, 0, 0 },
75a1acfa9bSespie   { "subheading",          0, 0, 0 },
76a1acfa9bSespie   { "subsubheading",       0, 0, 0 },
77f8dd34f6Sespie 
78a1acfa9bSespie   { "titlepage",           1, 0, 0 },
79a1acfa9bSespie   { "author",              0, 0, 0 },
80a1acfa9bSespie   { "booktitle",           0, 0, 0 },
81a1acfa9bSespie   { "booksubtitle",        0, 0, 0 },
82f8dd34f6Sespie 
83a1acfa9bSespie   { "menu",                1, 0, 0 },
84a1acfa9bSespie   { "detailmenu",          1, 0, 0 },
85a1acfa9bSespie   { "menuentry",           0, 0, 0 },
86a1acfa9bSespie   { "menutitle",           0, 0, 0 },
87a1acfa9bSespie   { "menucomment",         0, 0, 0 },
88a1acfa9bSespie   { "menunode",            0, 0, 0 },
89a1acfa9bSespie   { "nodename",            0, 0, 0 },
90f8dd34f6Sespie 
91a1acfa9bSespie   { "acronym",             0, 1, 0 },
92a1acfa9bSespie   { "acronymword",         0, 1, 0 },
93a1acfa9bSespie   { "acronymdesc",         0, 1, 0 },
94f8dd34f6Sespie 
95a1acfa9bSespie   { "abbrev",              0, 1, 0 },
96a1acfa9bSespie   { "abbrevword",          0, 1, 0 },
97a1acfa9bSespie   { "abbrevdesc",          0, 1, 0 },
98f8dd34f6Sespie 
99a1acfa9bSespie   { "tt",                  0, 1, 0 },
100a1acfa9bSespie   { "code",                0, 1, 0 },
101a1acfa9bSespie   { "command",             0, 1, 0 },
102a1acfa9bSespie   { "env",                 0, 1, 0 },
103a1acfa9bSespie   { "file",                0, 1, 0 },
104a1acfa9bSespie   { "option",              0, 1, 0 },
105a1acfa9bSespie   { "samp",                0, 1, 0 },
106a1acfa9bSespie   { "kbd",                 0, 1, 0 },
107a1acfa9bSespie   { "url",                 0, 1, 0 },
108a1acfa9bSespie   { "key",                 0, 1, 0 },
109a1acfa9bSespie   { "var",                 0, 1, 0 },
110a1acfa9bSespie   { "sc",                  0, 1, 0 },
111a1acfa9bSespie   { "dfn",                 0, 1, 0 },
112a1acfa9bSespie   { "emph",                0, 1, 0 },
113a1acfa9bSespie   { "strong",              0, 1, 0 },
114a1acfa9bSespie   { "cite",                0, 1, 0 },
115a1acfa9bSespie   { "notfixedwidth",       0, 1, 0 },
116a1acfa9bSespie   { "i",                   0, 1, 0 },
117a1acfa9bSespie   { "b",                   0, 1, 0 },
118a1acfa9bSespie   { "r",                   0, 1, 0 },
119a1acfa9bSespie   { "slanted",             0, 1, 0 },
120a1acfa9bSespie   { "sansserif",           0, 1, 0 },
121f8dd34f6Sespie 
122a1acfa9bSespie   { "exdent",              0, 0, 0 },
123f8dd34f6Sespie 
124a1acfa9bSespie   { "title",               0, 0, 0 },
125a1acfa9bSespie   { "ifinfo",              1, 0, 0 },
126a1acfa9bSespie   { "sp",                  0, 0, 0 },
127a1acfa9bSespie   { "center",              1, 0, 0 },
128a1acfa9bSespie   { "dircategory",         0, 0, 0 },
129a1acfa9bSespie   { "quotation",           1, 0, 0 },
130a1acfa9bSespie   { "example",             0, 0, 1 },
131a1acfa9bSespie   { "smallexample",        0, 0, 1 },
132a1acfa9bSespie   { "lisp",                0, 0, 1 },
133a1acfa9bSespie   { "smalllisp",           0, 0, 1 },
134a1acfa9bSespie   { "cartouche",           1, 0, 0 },
135a1acfa9bSespie   { "copying",             1, 0, 0 },
136a1acfa9bSespie   { "format",              0, 0, 1 },
137a1acfa9bSespie   { "smallformat",         0, 0, 1 },
138a1acfa9bSespie   { "display",             0, 0, 1 },
139a1acfa9bSespie   { "smalldisplay",        0, 0, 1 },
140a1acfa9bSespie   { "verbatim",            0, 0, 1 },
141a1acfa9bSespie   { "footnote",            0, 1, 0 },
142a1acfa9bSespie   { "",                    0, 1, 0 }, /* LINEANNOTATION (docbook) */
143f8dd34f6Sespie 
144a1acfa9bSespie   { "",                    1, 0, 0 }, /* TIP (docbook)       */
145a1acfa9bSespie   { "",                    1, 0, 0 }, /* NOTE (docbook)      */
146a1acfa9bSespie   { "",                    1, 0, 0 }, /* IMPORTANT (docbook) */
147a1acfa9bSespie   { "",                    1, 0, 0 }, /* WARNING (docbook)   */
148a1acfa9bSespie   { "",                    1, 0, 0 }, /* CAUTION (docbook)   */
149f8dd34f6Sespie 
150a1acfa9bSespie   { "itemize",             0, 0, 0 },
151a1acfa9bSespie   { "itemfunction",        0, 0, 0 },
152a1acfa9bSespie   { "item",                1, 0, 0 },
153a1acfa9bSespie   { "enumerate",           0, 0, 0 },
154a1acfa9bSespie   { "table",               0, 0, 0 },
155a1acfa9bSespie   { "tableitem",           0, 0, 0 },
156a1acfa9bSespie   { "tableterm",           0, 0, 0 },
157f8dd34f6Sespie 
158a1acfa9bSespie   { "indexterm",           0, 1, 0 },
159f8dd34f6Sespie 
160a1acfa9bSespie   { "math",                0, 1, 0 },
161a1acfa9bSespie 
162a1acfa9bSespie   { "dmn",                 0, 1, 0 },
163a1acfa9bSespie 
164a1acfa9bSespie   { "xref",                0, 1, 0 },
165a1acfa9bSespie   { "xrefnodename",        0, 1, 0 },
166a1acfa9bSespie   { "xrefinfoname",        0, 1, 0 },
167a1acfa9bSespie   { "xrefprinteddesc",     0, 1, 0 },
168a1acfa9bSespie   { "xrefinfofile",        0, 1, 0 },
169a1acfa9bSespie   { "xrefprintedname",     0, 1, 0 },
170a1acfa9bSespie 
171a1acfa9bSespie   { "inforef",             0, 1, 0 },
172a1acfa9bSespie   { "inforefnodename",     0, 1, 0 },
173a1acfa9bSespie   { "inforefrefname",      0, 1, 0 },
174a1acfa9bSespie   { "inforefinfoname",     0, 1, 0 },
175a1acfa9bSespie 
176a1acfa9bSespie   { "uref",                0, 1, 0 },
177a1acfa9bSespie   { "urefurl",             0, 1, 0 },
178a1acfa9bSespie   { "urefdesc",            0, 1, 0 },
179a1acfa9bSespie   { "urefreplacement",     0, 1, 0 },
180a1acfa9bSespie 
181a1acfa9bSespie   { "email",               0, 1, 0 },
182a1acfa9bSespie   { "emailaddress",        0, 1, 0 },
183a1acfa9bSespie   { "emailname",           0, 1, 0 },
184a1acfa9bSespie 
185a1acfa9bSespie   { "group",               0, 0, 0 },
186a1acfa9bSespie   { "float",               1, 0, 0 },
187a1acfa9bSespie   { "floattype",           0, 0, 0 },
188a1acfa9bSespie   { "floatpos",            0, 0, 0 },
189a1acfa9bSespie   { "caption",             0, 0, 0 },
190a1acfa9bSespie   { "shortcaption",        0, 0, 0 },
191a1acfa9bSespie 
192a1acfa9bSespie   { "",                    0, 0, 0 }, /* TABLE (docbook) */
193a1acfa9bSespie   { "",                    0, 0, 0 }, /* FIGURE (docbook) */
194a1acfa9bSespie   { "",                    0, 0, 0 }, /* EXAMPLE (docbook) */
195a1acfa9bSespie   { "",                    1, 0, 0 }, /* SIDEBAR (docbook) */
196a1acfa9bSespie 
197a1acfa9bSespie   { "printindex",          0, 0, 0 },
198a1acfa9bSespie   { "listoffloats",        0, 0, 0 },
199a1acfa9bSespie   { "anchor",              0, 1, 0 },
200a1acfa9bSespie 
201a1acfa9bSespie   { "image",               0, 0, 0 },
202a1acfa9bSespie   { "inlineimage",         0, 1, 0 },
203a1acfa9bSespie   { "alttext",             0, 1, 0 },
204a1acfa9bSespie 
205a1acfa9bSespie   { "",                    0, 1, 0 }, /* PRIMARY (docbook) */
206a1acfa9bSespie   { "",                    0, 1, 0 }, /* SECONDARY (docbook) */
207a1acfa9bSespie   { "",                    0, 0, 0 }, /* INFORMALFIGURE (docbook) */
208a1acfa9bSespie   { "",                    0, 0, 0 }, /* MEDIAOBJECT (docbook) */
209a1acfa9bSespie   { "",                    0, 0, 0 }, /* IMAGEOBJECT (docbook) */
210a1acfa9bSespie   { "",                    0, 0, 0 }, /* IMAGEDATA (docbook) */
211a1acfa9bSespie   { "",                    0, 0, 0 }, /* TEXTOBJECT (docbook) */
212a1acfa9bSespie   { "",                    0, 0, 0 }, /* INDEXENTRY (docbook) */
213a1acfa9bSespie   { "",                    0, 0, 0 }, /* PRIMARYIE (docbook) */
214a1acfa9bSespie   { "",                    0, 0, 0 }, /* SECONDARYIE (docbook) */
215a1acfa9bSespie   { "",                    0, 0, 0 }, /* INDEXDIV (docbook) */
216a1acfa9bSespie   { "multitable",          0, 0, 0 },
217a1acfa9bSespie   { "",                    0, 0, 0 }, /* TGROUP (docbook) */
218a1acfa9bSespie   { "columnfraction",      0, 0, 0 },
219a1acfa9bSespie   { "thead",               0, 0, 0 },
220a1acfa9bSespie   { "tbody",               0, 0, 0 },
221a1acfa9bSespie   { "entry",               0, 0, 0 },
222a1acfa9bSespie   { "row",                 0, 0, 0 },
223a1acfa9bSespie   { "",                    0, 0, 0 }, /* BOOKINFO (docbook) */
224a1acfa9bSespie   { "",                    0, 0, 0 }, /* ABSTRACT (docbook) */
225a1acfa9bSespie   { "",                    0, 0, 0 }, /* REPLACEABLE (docbook) */
226a1acfa9bSespie   { "",                    0, 0, 0 }, /* ENVAR (docbook) */
227a1acfa9bSespie   { "",                    0, 0, 0 }, /* COMMENT (docbook) */
228a1acfa9bSespie   { "",                    0, 0, 0 }, /* FUNCTION (docbook) */
229a1acfa9bSespie   { "",                    0, 0, 0 }, /* LEGALNOTICE (docbook) */
230a1acfa9bSespie 
231a1acfa9bSespie   { "contents",            0, 0, 0 },
232a1acfa9bSespie   { "shortcontents",       0, 0, 0 },
233a1acfa9bSespie   { "documentlanguage",    0, 0, 0 },
234a1acfa9bSespie 
235a1acfa9bSespie   { "setvalue",            0, 0, 0 },
236a1acfa9bSespie   { "clearvalue",          0, 0, 0 },
237a1acfa9bSespie 
238a1acfa9bSespie   { "definition",          0, 0, 0 },
239a1acfa9bSespie   { "definitionterm",      0, 0, 0 },
240a1acfa9bSespie   { "definitionitem",      1, 0, 0 },
241a1acfa9bSespie   { "defcategory",         0, 0, 0 },
242a1acfa9bSespie   { "deffunction",         0, 0, 0 },
243a1acfa9bSespie   { "defvariable",         0, 0, 0 },
244a1acfa9bSespie   { "defparam",            0, 0, 0 },
245a1acfa9bSespie   { "defdelimiter",        0, 0, 0 },
246a1acfa9bSespie   { "deftype",             0, 0, 0 },
247a1acfa9bSespie   { "defparamtype",        0, 0, 0 },
248a1acfa9bSespie   { "defdatatype",         0, 0, 0 },
249a1acfa9bSespie   { "defclass",            0, 0, 0 },
250a1acfa9bSespie   { "defclassvar",         0, 0, 0 },
251a1acfa9bSespie   { "defoperation",        0, 0, 0 },
252a1acfa9bSespie 
253a1acfa9bSespie   { "para",                0, 0, 0 } /* Must be last */
254a1acfa9bSespie   /* name / contains para / contained in para / preserve space */
255f8dd34f6Sespie };
256f8dd34f6Sespie 
257f8dd34f6Sespie element docbook_element_list [] = {
258a1acfa9bSespie   { "book",                0, 0, 0 }, /* TEXINFO */
259a1acfa9bSespie   { "",                    0, 0, 0 }, /* SETFILENAME */
260a1acfa9bSespie   { "",                    0, 0, 0 }, /* TITLEINFO */
261a1acfa9bSespie   { "title",               0, 0, 0 }, /* SETTITLE */
262a1acfa9bSespie   { "",                    1, 0, 0 }, /* DOCUMENTDESCRIPTION (?) */
263f8dd34f6Sespie 
264a1acfa9bSespie   { "",                    1, 0, 0 }, /* NODE */
265a1acfa9bSespie   { "",                    0, 0, 0 }, /* NODENEXT */
266a1acfa9bSespie   { "",                    0, 0, 0 }, /* NODEPREV */
267a1acfa9bSespie   { "",                    0, 0, 0 }, /* NODEUP */
268f8dd34f6Sespie 
269a1acfa9bSespie   { "chapter",             1, 0, 0 },
270a1acfa9bSespie   { "sect1",               1, 0, 0 }, /* SECTION */
271a1acfa9bSespie   { "sect2",               1, 0, 0 }, /* SUBSECTION */
272a1acfa9bSespie   { "sect3",               1, 0, 0 }, /* SUBSUBSECTION */
273f8dd34f6Sespie 
274a1acfa9bSespie   { "chapter",             1, 0, 0 }, /* TOP */
275a1acfa9bSespie   { "chapter",             1, 0, 0 }, /* UNNUMBERED */
276a1acfa9bSespie   { "sect1",               1, 0, 0 }, /* UNNUMBEREDSEC */
277a1acfa9bSespie   { "sect2",               1, 0, 0 }, /* UNNUMBEREDSUBSEC */
278a1acfa9bSespie   { "sect3",               1, 0, 0 }, /* UNNUMBEREDSUBSUBSEC */
279f8dd34f6Sespie 
280a1acfa9bSespie   { "appendix",            1, 0, 0 },
281a1acfa9bSespie   { "sect1",               1, 0, 0 }, /* APPENDIXSEC */
282a1acfa9bSespie   { "sect2",               1, 0, 0 }, /* APPENDIXSUBSEC */
283a1acfa9bSespie   { "sect3",               1, 0, 0 }, /* APPENDIXSUBSUBSEC */
284f8dd34f6Sespie 
285a1acfa9bSespie   { "bridgehead",          0, 0, 0 }, /* MAJORHEADING */
286a1acfa9bSespie   { "bridgehead",          0, 0, 0 }, /* CHAPHEADING */
287a1acfa9bSespie   { "bridgehead",          0, 0, 0 }, /* HEADING */
288a1acfa9bSespie   { "bridgehead",          0, 0, 0 }, /* SUBHEADING */
289a1acfa9bSespie   { "bridgehead",          0, 0, 0 }, /* SUBSUBHEADING */
290f8dd34f6Sespie 
291a1acfa9bSespie   { "",                    0, 0, 0 }, /* TITLEPAGE */
292a1acfa9bSespie   { "",                    0, 0, 0 }, /* AUTHOR */
293a1acfa9bSespie   { "",                    0, 0, 0 }, /* BOOKTITLE */
294a1acfa9bSespie   { "",                    0, 0, 0 }, /* BOOKSUBTITLE */
295f8dd34f6Sespie 
296a1acfa9bSespie   { "",                    1, 0, 0 }, /* MENU */
297a1acfa9bSespie   { "",                    1, 0, 0 }, /* DETAILMENU */
298a1acfa9bSespie   { "",                    1, 0, 0 }, /* MENUENTRY */
299a1acfa9bSespie   { "",                    0, 0, 0 }, /* MENUTITLE */
300a1acfa9bSespie   { "",                    1, 0, 0 }, /* MENUCOMMENT */
301a1acfa9bSespie   { "",                    0, 0, 0 }, /* MENUNODE */
302a1acfa9bSespie   { "anchor",              0, 0, 0 }, /* NODENAME */
303f8dd34f6Sespie 
304a1acfa9bSespie   { "acronym",             0, 1, 0 },
305a1acfa9bSespie   { "",                    0, 1, 0 }, /* ACRONYMWORD */
306a1acfa9bSespie   { "",                    0, 1, 0 }, /* ACRONYMDESC */
307f8dd34f6Sespie 
308a1acfa9bSespie   { "abbrev",              0, 1, 0 },
309a1acfa9bSespie   { "",                    0, 1, 0 }, /* ABBREVWORD */
310a1acfa9bSespie   { "",                    0, 1, 0 }, /* ABBREVDESC */
311f8dd34f6Sespie 
312a1acfa9bSespie   { "literal",             0, 1, 0 }, /* TT */
313a1acfa9bSespie   { "literal",             0, 1, 0 }, /* CODE */
314a1acfa9bSespie   { "command",             0, 1, 0 }, /* COMMAND */
315a1acfa9bSespie   { "envar",               0, 1, 0 }, /* ENV */
316a1acfa9bSespie   { "filename",            0, 1, 0 }, /* FILE */
317a1acfa9bSespie   { "option",              0, 1, 0 }, /* OPTION */
318a1acfa9bSespie   { "literal",             0, 1, 0 }, /* SAMP */
319a1acfa9bSespie   { "userinput",           0, 1, 0 }, /* KBD */
320a1acfa9bSespie   { "wordasword",          0, 1, 0 }, /* URL */
321a1acfa9bSespie   { "keycap",              0, 1, 0 }, /* KEY */
322a1acfa9bSespie   { "replaceable",         0, 1, 0 }, /* VAR */
323a1acfa9bSespie   { "",                    0, 1, 0 }, /* SC */
324a1acfa9bSespie   { "firstterm",           0, 1, 0 }, /* DFN */
325a1acfa9bSespie   { "emphasis",            0, 1, 0 }, /* EMPH */
326a1acfa9bSespie   { "emphasis",            0, 1, 0 }, /* STRONG */
327a1acfa9bSespie   { "citetitle",           0, 1, 0 }, /* CITE */
328a1acfa9bSespie   { "",                    0, 1, 0 }, /* NOTFIXEDWIDTH */
329a1acfa9bSespie   { "wordasword",          0, 1, 0 }, /* I */
330a1acfa9bSespie   { "emphasis",            0, 1, 0 }, /* B */
331a1acfa9bSespie   { "",                    0, 1, 0 }, /* R */
332f8dd34f6Sespie 
333a1acfa9bSespie   { "",                    0, 0, 0 }, /* EXDENT */
334f8dd34f6Sespie 
335a1acfa9bSespie   { "title",               0, 0, 0 },
336a1acfa9bSespie   { "",                    1, 0, 0 }, /* IFINFO */
337a1acfa9bSespie   { "",                    0, 0, 0 }, /* SP */
338a1acfa9bSespie   { "",                    1, 0, 0 }, /* CENTER */
339a1acfa9bSespie   { "",                    0, 0, 0 }, /* DIRCATEGORY */
340a1acfa9bSespie   { "blockquote",          1, 0, 0 }, /* QUOTATION */
341a1acfa9bSespie   { "screen",              0, 0, 1 }, /* EXAMPLE */
342a1acfa9bSespie   { "screen",              0, 0, 1 }, /* SMALLEXAMPLE */
343a1acfa9bSespie   { "programlisting",      0, 0, 1 }, /* LISP */
344a1acfa9bSespie   { "programlisting",      0, 0, 1 }, /* SMALLLISP */
345a1acfa9bSespie   { "",                    1, 0, 0 }, /* CARTOUCHE */
346a1acfa9bSespie   { "",                    1, 0, 0 }, /* COPYING */
347a1acfa9bSespie   { "screen",              0, 1, 1 }, /* FORMAT */
348a1acfa9bSespie   { "screen",              0, 1, 1 }, /* SMALLFORMAT */
349a1acfa9bSespie   { "literallayout",       0, 1, 1 }, /* DISPLAY */
350a1acfa9bSespie   { "literallayout",       0, 1, 1 }, /* SMALLDISPLAY */
351a1acfa9bSespie   { "screen",              0, 0, 1 }, /* VERBATIM */
352a1acfa9bSespie   { "footnote",            0, 1, 0 },
353a1acfa9bSespie   { "lineannotation",      0, 1, 0 },
354f8dd34f6Sespie 
355a1acfa9bSespie   { "tip",                 1, 0, 0 },
356a1acfa9bSespie   { "note",                1, 0, 0 },
357a1acfa9bSespie   { "important",           1, 0, 0 },
358a1acfa9bSespie   { "warning",             1, 0, 0 },
359a1acfa9bSespie   { "caution",             1, 0, 0 },
360f8dd34f6Sespie 
361a1acfa9bSespie   { "itemizedlist",        0, 0, 0 }, /* ITEMIZE */
362a1acfa9bSespie   { "",                    0, 0, 0 }, /* ITEMFUNCTION */
363a1acfa9bSespie   { "listitem",            1, 0, 0 }, /* ITEM */
364a1acfa9bSespie   { "orderedlist",         0, 0, 0 }, /* ENUMERATE */
365a1acfa9bSespie   { "variablelist",        0, 0, 0 }, /* TABLE */
366a1acfa9bSespie   { "varlistentry",        0, 0, 0 }, /* TABLEITEM */
367a1acfa9bSespie   { "term",                0, 0, 0 }, /* TABLETERM */
368f8dd34f6Sespie 
369a1acfa9bSespie   { "indexterm",           0, 1, 0 }, /* INDEXTERM */
370f8dd34f6Sespie 
371a1acfa9bSespie   { "",                    0, 1, 0 }, /* MATH */
372f8dd34f6Sespie 
373a1acfa9bSespie   { "",                    0, 1, 0 }, /* DIMENSION */
374a1acfa9bSespie 
375a1acfa9bSespie   { "xref",                0, 1, 0 }, /* XREF */
376a1acfa9bSespie   { "link",                0, 1, 0 }, /* XREFNODENAME */
377a1acfa9bSespie   { "",                    0, 1, 0 }, /* XREFINFONAME */
378a1acfa9bSespie   { "",                    0, 1, 0 }, /* XREFPRINTEDDESC */
379a1acfa9bSespie   { "",                    0, 1, 0 }, /* XREFINFOFILE */
380a1acfa9bSespie   { "",                    0, 1, 0 }, /* XREFPRINTEDNAME */
381a1acfa9bSespie 
382a1acfa9bSespie   { "",                    0, 1, 0 }, /* INFOREF */
383a1acfa9bSespie   { "",                    0, 1, 0 }, /* INFOREFNODENAME */
384a1acfa9bSespie   { "",                    0, 1, 0 }, /* INFOREFREFNAME */
385a1acfa9bSespie   { "",                    0, 1, 0 }, /* INFOREFINFONAME */
386a1acfa9bSespie 
387a1acfa9bSespie   { "ulink",               0, 1, 0 }, /* UREF */
388a1acfa9bSespie   { "",                    0, 1, 0 }, /* UREFURL */
389a1acfa9bSespie   { "",                    0, 1, 0 }, /* UREFDESC */
390a1acfa9bSespie   { "",                    0, 1, 0 }, /* UREFREPLACEMENT */
391a1acfa9bSespie 
392a1acfa9bSespie   { "ulink",               0, 1, 0 }, /* EMAIL */
393a1acfa9bSespie   { "",                    0, 1, 0 }, /* EMAILADDRESS */
394a1acfa9bSespie   { "",                    0, 1, 0 }, /* EMAILNAME */
395a1acfa9bSespie 
396a1acfa9bSespie   { "",                    0, 0, 0 }, /* GROUP */
397a1acfa9bSespie   { "",                    1, 0, 0 }, /* FLOAT */
398a1acfa9bSespie   { "",                    0, 0, 0 }, /* FLOATTYPE */
399a1acfa9bSespie   { "",                    0, 0, 0 }, /* FLOATPOS */
400a1acfa9bSespie   { "",                    0, 0, 0 }, /* CAPTION */
401a1acfa9bSespie   { "",                    0, 0, 0 }, /* SHORTCAPTION */
402a1acfa9bSespie 
403a1acfa9bSespie   { "table",               0, 1, 0 },
404a1acfa9bSespie   { "figure",              0, 1, 0 },
405a1acfa9bSespie   { "example",             1, 1, 0 },
406a1acfa9bSespie   { "sidebar",             1, 0, 0 },
407a1acfa9bSespie 
408a1acfa9bSespie   { "index",               0, 1, 0 }, /* PRINTINDEX */
409a1acfa9bSespie   { "",                    0, 1, 0 }, /* LISTOFFLOATS */
410a1acfa9bSespie   { "",                    0, 1, 0 }, /* ANCHOR */
411a1acfa9bSespie 
412a1acfa9bSespie   { "",                    0, 0, 0 }, /* IMAGE */
413a1acfa9bSespie   { "inlinemediaobject",   0, 1, 0 }, /* INLINEIMAGE */
414a1acfa9bSespie   { "",                    0, 0, 0 }, /* IMAGEALTTEXT */
415a1acfa9bSespie 
416a1acfa9bSespie   { "primary",             0, 1, 0 }, /* PRIMARY */
417a1acfa9bSespie   { "secondary",           0, 1, 0 },
418a1acfa9bSespie   { "informalfigure",      0, 0, 0 },
419a1acfa9bSespie   { "mediaobject",         0, 0, 0 },
420a1acfa9bSespie   { "imageobject",         0, 1, 0 },
421a1acfa9bSespie   { "imagedata",           0, 1, 0 },
422a1acfa9bSespie   { "textobject",          0, 1, 0 },
423a1acfa9bSespie   { "indexentry",          0, 0, 0 },
424a1acfa9bSespie   { "primaryie",           0, 0, 0 },
425a1acfa9bSespie   { "secondaryie",         0, 0, 0 },
426a1acfa9bSespie   { "indexdiv",            0, 0, 0 },
427a1acfa9bSespie   { "informaltable",       0, 0, 0 },
428a1acfa9bSespie   { "tgroup",              0, 0, 0 },
429a1acfa9bSespie   { "colspec",             0, 0, 0 },
430a1acfa9bSespie   { "thead",               0, 0, 0 },
431a1acfa9bSespie   { "tbody",               0, 0, 0 },
432a1acfa9bSespie   { "entry",               0, 0, 0 },
433a1acfa9bSespie   { "row",                 0, 0, 0 },
434a1acfa9bSespie   { "bookinfo",            0, 0, 0 },
435a1acfa9bSespie   { "abstract",            1, 0, 0 },
436a1acfa9bSespie   { "replaceable",         0, 0, 0 },
437a1acfa9bSespie   { "envar",               0, 1, 0 },
438a1acfa9bSespie   { "comment",             0, 0, 0 },
439a1acfa9bSespie   { "function",            0, 1, 0 },
440a1acfa9bSespie   { "legalnotice",         1, 0, 0 },
441a1acfa9bSespie 
442a1acfa9bSespie   { "",                    0, 0, 0 }, /* CONTENTS (xml) */
443a1acfa9bSespie   { "",                    0, 0, 0 }, /* SHORTCONTENTS (xml) */
444a1acfa9bSespie   { "",                    0, 0, 0 }, /* DOCUMENT LANGUAGE (xml) */
445a1acfa9bSespie 
446a1acfa9bSespie   { "",                    0, 0, 0 }, /* SETVALUE (xml) */
447a1acfa9bSespie   { "",                    0, 0, 0 }, /* CLEARVALUE (xml) */
448a1acfa9bSespie 
449a1acfa9bSespie   { "blockquote",          1, 0, 0 }, /* DEFINITION */
450a1acfa9bSespie   { "screen",              0, 0, 1 }, /* DEFINITIONTERM */
451a1acfa9bSespie   { "",                    0, 0, 0 }, /* DEFINITIONITEM (xml) */
452a1acfa9bSespie   { "",                    0, 0, 0 }, /* DEFCATEGORY (xml) */
453a1acfa9bSespie   { "function",            0, 0, 0 }, /* DEFFUNCTION */
454a1acfa9bSespie   { "varname",             0, 0, 0 }, /* DEFVARIABLE */
455a1acfa9bSespie   { "varname",             0, 0, 0 }, /* DEFPARAM */
456a1acfa9bSespie   { "",                    0, 0, 0 }, /* DEFDELIMITER (xml) */
457a1acfa9bSespie   { "returnvalue",         0, 0, 0 }, /* DEFTYPE */
458a1acfa9bSespie   { "type",                0, 0, 0 }, /* DEFPARAMTYPE */
459a1acfa9bSespie   { "structname",          0, 0, 0 }, /* DEFDATATYPE */
460a1acfa9bSespie   { "classname",           0, 0, 0 }, /* DEFCLASS */
461a1acfa9bSespie   { "property",            0, 0, 0 }, /* DEFCLASSVAR */
462a1acfa9bSespie   { "methodname",          0, 0, 0 }, /* DEFOPERATION */
463a1acfa9bSespie 
464a1acfa9bSespie   { "para",                0, 0, 0 } /* Must be last */
465a1acfa9bSespie   /* name / contains para / contained in para / preserve space */
466f8dd34f6Sespie };
467f8dd34f6Sespie 
468f8dd34f6Sespie element *xml_element_list = NULL;
469f8dd34f6Sespie 
470f8dd34f6Sespie 
471f8dd34f6Sespie typedef struct _replace_element
472f8dd34f6Sespie {
473f8dd34f6Sespie   int element_to_replace;
474f8dd34f6Sespie   int element_containing;
475f8dd34f6Sespie   int element_replacing;
476f8dd34f6Sespie } replace_element;
477f8dd34f6Sespie 
478f8dd34f6Sespie /* Elements to replace - Docbook only
479f8dd34f6Sespie    -------------------
480f8dd34f6Sespie    if `element_to_replace' have to be inserted
481f8dd34f6Sespie    as a child of `element_containing,'
482f8dd34f6Sespie    use `element_replacing' instead.
483f8dd34f6Sespie 
484f8dd34f6Sespie    A value of `-1' for element_replacing means `do not use any element.'
485f8dd34f6Sespie */
486f8dd34f6Sespie 
487f8dd34f6Sespie replace_element replace_elements [] = {
488f8dd34f6Sespie   { I, TABLETERM, EMPH },
489f8dd34f6Sespie   { B, TABLETERM, EMPH },
490f8dd34f6Sespie   { TT, CODE, -1 },
491f8dd34f6Sespie   { EXAMPLE, DISPLAY, -1 },
492f8dd34f6Sespie   { CODE, DFN, -1 },
493f8dd34f6Sespie   { CODE, VAR, -1 },
494f8dd34f6Sespie   { EMPH, CODE, REPLACEABLE },
495a1acfa9bSespie   { VAR, VAR, -1},
496a1acfa9bSespie   { VAR, B, EMPH},
497a1acfa9bSespie   { B, CODE, ENVAR},
498a1acfa9bSespie   { CODE, I, EMPH},
499a1acfa9bSespie   { SAMP, VAR, -1 },
500a1acfa9bSespie   { FORMAT, BOOKINFO, ABSTRACT },
501a1acfa9bSespie   { QUOTATION, ABSTRACT, -1},
502a1acfa9bSespie   { LINEANNOTATION, LINEANNOTATION, -1 },
503a1acfa9bSespie   { LEGALNOTICE, ABSTRACT, -1 },
504a1acfa9bSespie   { QUOTATION, QUOTATION, -1 },
505a1acfa9bSespie   /* Formal versions of table and image elements.  */
506a1acfa9bSespie   { MULTITABLE, FLOAT, FLOATTABLE },
507a1acfa9bSespie   { INFORMALFIGURE, FLOAT, FLOATFIGURE },
508a1acfa9bSespie   { CARTOUCHE, FLOAT, FLOATCARTOUCHE },
509a1acfa9bSespie   /* Unnecessary markup in @defun blocks.  */
510a1acfa9bSespie   { VAR, DEFPARAM, -1 },
511a1acfa9bSespie   { CODE, DEFTYPE, -1 },
512f8dd34f6Sespie   /* Add your elements to replace here */
513f8dd34f6Sespie   {-1, 0, 0}
514f8dd34f6Sespie };
515f8dd34f6Sespie 
516f8dd34f6Sespie int xml_in_menu_entry = 0;
517f8dd34f6Sespie int xml_in_menu_entry_comment = 0;
518f8dd34f6Sespie int xml_node_open = 0;
519f8dd34f6Sespie int xml_node_level = -1;
520f8dd34f6Sespie int xml_in_para = 0;
521f8dd34f6Sespie int xml_just_after_element = 0;
522a1acfa9bSespie int xml_keep_space = 0;
523a1acfa9bSespie 
524a1acfa9bSespie int xml_no_indent = 0;
525f8dd34f6Sespie 
526f8dd34f6Sespie int xml_no_para = 0;
527f8dd34f6Sespie char *xml_node_id = NULL;
528f8dd34f6Sespie int xml_sort_index = 0;
529f8dd34f6Sespie 
530a1acfa9bSespie int xml_in_xref_token = 0;
531a1acfa9bSespie int xml_in_bookinfo = 0;
532a1acfa9bSespie int xml_in_book_title = 0;
533a1acfa9bSespie int xml_in_abstract = 0;
534a1acfa9bSespie 
535a1acfa9bSespie /* Non-zero if we are handling an element that can appear between
536a1acfa9bSespie    @item and @itemx, @deffn and @deffnx.  */
537a1acfa9bSespie int xml_dont_touch_items_defs = 0;
538a1acfa9bSespie 
539a1acfa9bSespie /* We need to keep footnote state, because elements inside footnote may try
540a1acfa9bSespie    to close the previous parent para.  */
541a1acfa9bSespie static int xml_in_footnote = 0;
542a1acfa9bSespie 
543f8dd34f6Sespie static int xml_after_table_term = 0;
544f8dd34f6Sespie static int book_started = 0;
545f8dd34f6Sespie static int first_section_opened = 0;
546f8dd34f6Sespie 
547a1acfa9bSespie static int xml_in_tableitem[256];
548a1acfa9bSespie static int xml_in_item[256];
549a1acfa9bSespie static int xml_table_level = 0;
550f8dd34f6Sespie 
551a1acfa9bSespie static int xml_in_def_item[256];
552a1acfa9bSespie static int xml_definition_level = 0;
553a1acfa9bSespie int xml_after_def_term = 0;
554f8dd34f6Sespie 
555a1acfa9bSespie static int in_table_title = 0;
556a1acfa9bSespie 
557a1acfa9bSespie static int in_indexentry = 0;
558a1acfa9bSespie static int in_secondary = 0;
559a1acfa9bSespie static int in_indexterm = 0;
560a1acfa9bSespie 
561f8dd34f6Sespie char *
562a1acfa9bSespie xml_id (char *id)
563f8dd34f6Sespie {
564f8dd34f6Sespie   char *tem = xmalloc (strlen (id) + 1);
565f8dd34f6Sespie   char *p = tem;
566f8dd34f6Sespie   strcpy (tem, id);
567a1acfa9bSespie   while (*p)
568a1acfa9bSespie     { /* Check if a character is allowed in ID attributes.  This list differs
569a1acfa9bSespie          slightly from XML specs that it doesn't contain underscores.
570a1acfa9bSespie          See http://xml.coverpages.org/sgmlsyn/sgmlsyn.htm, ``9.3 Name''  */
571a1acfa9bSespie       if (!strchr ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.", *p))
572f8dd34f6Sespie         *p = '-';
573a1acfa9bSespie       p++;
574f8dd34f6Sespie     }
575f8dd34f6Sespie   p = tem;
576a1acfa9bSespie   /* First character can only be a letter.  */
577a1acfa9bSespie   if (!strchr ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", *p))
578f8dd34f6Sespie     *p = 'i';
579f8dd34f6Sespie   return tem;
580f8dd34f6Sespie }
581f8dd34f6Sespie 
582f8dd34f6Sespie int
583a1acfa9bSespie xml_element (char *name)
584f8dd34f6Sespie {
585f8dd34f6Sespie   int i;
586f8dd34f6Sespie   for (i=0; i<=PARA; i++)
587f8dd34f6Sespie     {
588f8dd34f6Sespie       if (strcasecmp (name, texinfoml_element_list[i].name) == 0)
589f8dd34f6Sespie         return i;
590f8dd34f6Sespie     }
591f8dd34f6Sespie   printf ("Error xml_element\n");
592f8dd34f6Sespie   return -1;
593f8dd34f6Sespie }
594f8dd34f6Sespie 
595f8dd34f6Sespie void
596a1acfa9bSespie xml_begin_document (char *output_filename)
597f8dd34f6Sespie {
598f8dd34f6Sespie   if (book_started)
599f8dd34f6Sespie     return;
600f8dd34f6Sespie 
601f8dd34f6Sespie   book_started = 1;
602a1acfa9bSespie 
603a1acfa9bSespie   /* Make sure this is the very first string of the output document.  */
604a1acfa9bSespie   output_paragraph_offset = 0;
605a1acfa9bSespie 
606a1acfa9bSespie   insert_string ("<?xml version=\"1.0\"");
607a1acfa9bSespie 
608a1acfa9bSespie   /* At this point, we register a delayed writing for document encoding,
609a1acfa9bSespie      so in the end, proper encoding attribute will be inserted here.
610a1acfa9bSespie      Since the user is unaware that we are implicitly executing this
611a1acfa9bSespie      command, we should disable warnings temporarily, in order to avoid
612a1acfa9bSespie      possible confusion.  (ie. if the output is not seekable,
613a1acfa9bSespie      register_delayed_write issues a warning.)  */
614a1acfa9bSespie   {
615a1acfa9bSespie     extern int print_warnings;
616a1acfa9bSespie     int save_print_warnings = print_warnings;
617a1acfa9bSespie     print_warnings = 0;
618a1acfa9bSespie     register_delayed_write ("@documentencoding");
619a1acfa9bSespie     print_warnings = save_print_warnings;
620a1acfa9bSespie   }
621a1acfa9bSespie 
622a1acfa9bSespie   insert_string ("?>\n");
623a1acfa9bSespie 
624f8dd34f6Sespie   if (docbook)
625f8dd34f6Sespie     {
626a1acfa9bSespie       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]>");
627f8dd34f6Sespie       xml_element_list = docbook_element_list;
628f8dd34f6Sespie     }
629f8dd34f6Sespie   else
630f8dd34f6Sespie     {
631a1acfa9bSespie       insert_string ("<!DOCTYPE texinfo PUBLIC \"-//GNU//DTD TexinfoML V");
632a1acfa9bSespie       insert_string (VERSION);
633a1acfa9bSespie       insert_string ("//EN\" \"http://www.gnu.org/software/texinfo/dtd/");
634a1acfa9bSespie       insert_string (VERSION);
635a1acfa9bSespie       insert_string ("/texinfo.dtd\">");
636f8dd34f6Sespie       xml_element_list = texinfoml_element_list;
637f8dd34f6Sespie     }
638f8dd34f6Sespie   if (language_code != last_language_code)
639a1acfa9bSespie     {
640a1acfa9bSespie       if (docbook)
641f8dd34f6Sespie         xml_insert_element_with_attribute (TEXINFO, START, "lang=\"%s\"", language_table[language_code].abbrev);
642f8dd34f6Sespie       else
643a1acfa9bSespie 	xml_insert_element_with_attribute (TEXINFO, START, "xml:lang=\"%s\"", language_table[language_code].abbrev);
644a1acfa9bSespie     }
645f8dd34f6Sespie   if (!docbook)
646f8dd34f6Sespie     {
647f8dd34f6Sespie       xml_insert_element (SETFILENAME, START);
648f8dd34f6Sespie       insert_string (output_filename);
649f8dd34f6Sespie       xml_insert_element (SETFILENAME, END);
650f8dd34f6Sespie     }
651f8dd34f6Sespie }
652f8dd34f6Sespie 
653f8dd34f6Sespie /*  */
654f8dd34f6Sespie static int element_stack[256];
655f8dd34f6Sespie static int element_stack_index = 0;
656f8dd34f6Sespie 
657a1acfa9bSespie static int
658a1acfa9bSespie xml_current_element (void)
659a1acfa9bSespie {
660a1acfa9bSespie   return element_stack[element_stack_index-1];
661a1acfa9bSespie }
662a1acfa9bSespie 
663f8dd34f6Sespie static void
664a1acfa9bSespie xml_push_current_element (int elt)
665f8dd34f6Sespie {
666f8dd34f6Sespie   element_stack[element_stack_index++] = elt;
667f8dd34f6Sespie   if (element_stack_index > 200)
668f8dd34f6Sespie     printf ("*** stack overflow (%d - %s) ***\n",
669f8dd34f6Sespie             element_stack_index,
670f8dd34f6Sespie             xml_element_list[elt].name);
671f8dd34f6Sespie }
672f8dd34f6Sespie 
673a1acfa9bSespie static void
674a1acfa9bSespie xml_pop_current_element (void)
675f8dd34f6Sespie {
676f8dd34f6Sespie   element_stack_index--;
677f8dd34f6Sespie   if (element_stack_index < 0)
678f8dd34f6Sespie     printf ("*** stack underflow (%d - %d) ***\n",
679f8dd34f6Sespie             element_stack_index,
680f8dd34f6Sespie             xml_current_element());
681f8dd34f6Sespie }
682f8dd34f6Sespie 
683a1acfa9bSespie int
684a1acfa9bSespie xml_current_stack_index (void)
685f8dd34f6Sespie {
686a1acfa9bSespie   return element_stack_index;
687f8dd34f6Sespie }
688f8dd34f6Sespie 
689f8dd34f6Sespie void
690a1acfa9bSespie xml_end_current_element (void)
691a1acfa9bSespie {
692a1acfa9bSespie   xml_insert_element (xml_current_element (), END);
693a1acfa9bSespie }
694a1acfa9bSespie 
695a1acfa9bSespie static void
696a1acfa9bSespie xml_indent (void)
697a1acfa9bSespie {
698a1acfa9bSespie   if (xml_indentation_increment > 0)
699a1acfa9bSespie     {
700a1acfa9bSespie       int i;
70191e5054cSotto       if (output_paragraph_offset > 0
70291e5054cSotto 	  && output_paragraph[output_paragraph_offset-1] != '\n')
703a1acfa9bSespie         insert ('\n');
704a1acfa9bSespie       for (i = 0; i < element_stack_index * xml_indentation_increment; i++)
705a1acfa9bSespie         insert (' ');
706a1acfa9bSespie     }
707a1acfa9bSespie }
708a1acfa9bSespie 
709a1acfa9bSespie void
710a1acfa9bSespie xml_start_para (void)
711a1acfa9bSespie {
712a1acfa9bSespie   if (xml_in_para || xml_in_footnote
713a1acfa9bSespie       || !xml_element_list[xml_current_element()].contains_para)
714a1acfa9bSespie     return;
715a1acfa9bSespie 
71691e5054cSotto   while (output_paragraph_offset > 0
71791e5054cSotto          && output_paragraph[output_paragraph_offset-1] == '\n')
718a1acfa9bSespie     output_paragraph_offset--;
719a1acfa9bSespie   xml_indent ();
720a1acfa9bSespie 
721a1acfa9bSespie   insert_string ("<para");
722a1acfa9bSespie   if (xml_no_indent)
723a1acfa9bSespie     insert_string (" role=\"continues\"");
724a1acfa9bSespie   insert_string (">");
725a1acfa9bSespie   xml_no_indent = 0;
726a1acfa9bSespie   xml_in_para = 1;
727a1acfa9bSespie }
728a1acfa9bSespie 
729a1acfa9bSespie void
730a1acfa9bSespie xml_end_para (void)
731a1acfa9bSespie {
732a1acfa9bSespie   if (!xml_in_para || xml_in_footnote)
733a1acfa9bSespie     return;
734a1acfa9bSespie 
73591e5054cSotto   while (output_paragraph_offset > 0
73691e5054cSotto 	 && cr_or_whitespace(output_paragraph[output_paragraph_offset-1]))
737a1acfa9bSespie     output_paragraph_offset--;
738a1acfa9bSespie 
739a1acfa9bSespie   insert_string ("</para>");
740a1acfa9bSespie   if (xml_indentation_increment > 0)
741a1acfa9bSespie     insert ('\n');
742a1acfa9bSespie   xml_in_para = 0;
743a1acfa9bSespie }
744a1acfa9bSespie 
745a1acfa9bSespie void
746a1acfa9bSespie xml_end_document (void)
747f8dd34f6Sespie {
748f8dd34f6Sespie   if (xml_node_open)
749f8dd34f6Sespie     {
750f8dd34f6Sespie       if (xml_node_level != -1)
751f8dd34f6Sespie         {
752f8dd34f6Sespie           xml_close_sections (xml_node_level);
753f8dd34f6Sespie           xml_node_level = -1;
754f8dd34f6Sespie         }
755f8dd34f6Sespie       xml_insert_element (NODE, END);
756f8dd34f6Sespie     }
757a1acfa9bSespie   else
758a1acfa9bSespie     xml_close_sections (xml_node_level);
759a1acfa9bSespie 
760f8dd34f6Sespie   xml_insert_element (TEXINFO, END);
761a1acfa9bSespie   if (xml_indentation_increment == 0)
762a1acfa9bSespie     insert ('\n');
763f8dd34f6Sespie   insert_string ("<!-- Keep this comment at the end of the file\n\
764f8dd34f6Sespie Local variables:\n\
765f8dd34f6Sespie mode: sgml\n\
766f8dd34f6Sespie sgml-indent-step:1\n\
767f8dd34f6Sespie sgml-indent-data:nil\n\
768f8dd34f6Sespie End:\n\
769f8dd34f6Sespie -->\n");
770f8dd34f6Sespie   if (element_stack_index != 0)
771f8dd34f6Sespie     error ("Element stack index : %d\n", element_stack_index);
772f8dd34f6Sespie }
773f8dd34f6Sespie 
774f8dd34f6Sespie /* MUST be 0 or 1, not true or false values */
775f8dd34f6Sespie static int start_element_inserted = 1;
776f8dd34f6Sespie 
777f8dd34f6Sespie /* NOTE: We use `elt' rather than `element' in the argument list of
778f8dd34f6Sespie    the next function, since otherwise the Solaris SUNWspro compiler
779f8dd34f6Sespie    barfs because `element' is a typedef declared near the beginning of
780f8dd34f6Sespie    this file.  */
781f8dd34f6Sespie void
782f8dd34f6Sespie #if defined (VA_FPRINTF) && __STDC__
783f8dd34f6Sespie xml_insert_element_with_attribute (int elt, int arg, char *format, ...)
784f8dd34f6Sespie #else
785f8dd34f6Sespie xml_insert_element_with_attribute (elt, arg, format, va_alist)
786f8dd34f6Sespie      int elt;
787f8dd34f6Sespie      int arg;
788f8dd34f6Sespie      char *format;
789f8dd34f6Sespie      va_dcl
790f8dd34f6Sespie #endif
791f8dd34f6Sespie {
792f8dd34f6Sespie   /* Look at the replace_elements table to see if we have to change the element */
793f8dd34f6Sespie   if (xml_sort_index)
794f8dd34f6Sespie       return;
795f8dd34f6Sespie   if (docbook)
796f8dd34f6Sespie     {
797f8dd34f6Sespie       replace_element *element_list = replace_elements;
798f8dd34f6Sespie       while (element_list->element_to_replace >= 0)
799f8dd34f6Sespie         {
800f8dd34f6Sespie           if ( ( (arg == START) &&
801f8dd34f6Sespie                  (element_list->element_containing == xml_current_element ()) &&
802f8dd34f6Sespie                  (element_list->element_to_replace == elt) ) ||
803f8dd34f6Sespie                ( (arg == END) &&
804f8dd34f6Sespie                  (element_list->element_containing == element_stack[element_stack_index-1-start_element_inserted]) &&
805f8dd34f6Sespie                  (element_list->element_to_replace == elt) ) )
806f8dd34f6Sespie             {
807f8dd34f6Sespie               elt = element_list->element_replacing;
808f8dd34f6Sespie               break;
809f8dd34f6Sespie             }
810f8dd34f6Sespie           element_list ++;
811f8dd34f6Sespie         }
812f8dd34f6Sespie 
813f8dd34f6Sespie       /* Forget the element */
814f8dd34f6Sespie       if (elt < 0)
815f8dd34f6Sespie         {
816f8dd34f6Sespie           if (arg == START)
817f8dd34f6Sespie             start_element_inserted = 0;
818f8dd34f6Sespie           else
819f8dd34f6Sespie             /* Replace the default value, for the next time */
820f8dd34f6Sespie             start_element_inserted = 1;
821f8dd34f6Sespie           return;
822f8dd34f6Sespie         }
823f8dd34f6Sespie     }
824f8dd34f6Sespie 
825f8dd34f6Sespie   if (!book_started)
826f8dd34f6Sespie     return;
827f8dd34f6Sespie 
828a1acfa9bSespie   if (!xml_dont_touch_items_defs && arg == START)
829a1acfa9bSespie     {
830a1acfa9bSespie       if (xml_after_table_term && elt != TABLETERM && xml_table_level
831a1acfa9bSespie           && !xml_in_item[xml_table_level])
832f8dd34f6Sespie         {
833f8dd34f6Sespie           xml_after_table_term = 0;
834f8dd34f6Sespie           xml_insert_element (ITEM, START);
835a1acfa9bSespie           xml_in_item[xml_table_level] = 1;
836a1acfa9bSespie         }
837a1acfa9bSespie       else if (xml_after_def_term && elt != DEFINITIONTERM)
838a1acfa9bSespie         {
839a1acfa9bSespie           xml_after_def_term = 0;
840a1acfa9bSespie           xml_insert_element (DEFINITIONITEM, START);
841a1acfa9bSespie           xml_in_def_item[xml_definition_level] = 1;
842a1acfa9bSespie         }
843f8dd34f6Sespie     }
844f8dd34f6Sespie 
845f8dd34f6Sespie   if (docbook && !only_macro_expansion && (in_menu || in_detailmenu))
846f8dd34f6Sespie     return;
847f8dd34f6Sespie 
848a1acfa9bSespie   if (executing_string && arg == END)
849a1acfa9bSespie     switch (elt)
850a1acfa9bSespie       {
851a1acfa9bSespie       case TABLEITEM:
852a1acfa9bSespie         xml_in_tableitem[xml_table_level] = 0;
853a1acfa9bSespie         break;
854a1acfa9bSespie       case ITEM:
855a1acfa9bSespie         xml_in_item[xml_table_level] = 0;
856a1acfa9bSespie         break;
857a1acfa9bSespie       case DEFINITIONTERM:
858a1acfa9bSespie         xml_in_def_item[xml_definition_level] = 0;
859a1acfa9bSespie         break;
860a1acfa9bSespie       }
861a1acfa9bSespie 
862a1acfa9bSespie   /* We are special-casing FIGURE element for docbook.  It does appear in
863a1acfa9bSespie      the tag stack, but not in the output.  This is to make element replacement
864a1acfa9bSespie      work beautifully.  */
865a1acfa9bSespie   if (docbook && elt == FLOAT)
866a1acfa9bSespie     {
867a1acfa9bSespie       if (arg == START)
868a1acfa9bSespie         xml_push_current_element (elt);
869a1acfa9bSespie       else
870a1acfa9bSespie         xml_pop_current_element ();
871a1acfa9bSespie       return;
872a1acfa9bSespie     }
873a1acfa9bSespie 
874*2aa28d40Sguenther   if (!strlen (xml_element_list[elt].name))
875f8dd34f6Sespie     {
876f8dd34f6Sespie       /*printf ("Warning: Inserting empty element %d\n", elt);*/
877f8dd34f6Sespie       return;
878f8dd34f6Sespie     }
879f8dd34f6Sespie 
880f8dd34f6Sespie   if (arg == START && !xml_in_para && !xml_no_para
881a1acfa9bSespie       && xml_element_list[elt].contained_in_para)
882a1acfa9bSespie     xml_start_para ();
883f8dd34f6Sespie 
884f8dd34f6Sespie   if (arg == START && xml_in_para && !xml_element_list[elt].contained_in_para)
885a1acfa9bSespie     xml_end_para ();
886f8dd34f6Sespie 
887f8dd34f6Sespie   if (arg == END && xml_in_para && !xml_element_list[elt].contained_in_para)
888a1acfa9bSespie     xml_end_para ();
889a1acfa9bSespie 
890a1acfa9bSespie   if (docbook && xml_table_level && !in_table_title
891a1acfa9bSespie       && !xml_in_tableitem[xml_table_level] && !xml_in_item[xml_table_level]
892a1acfa9bSespie       && arg == START && elt != TABLEITEM && elt != TABLETERM
893a1acfa9bSespie       && !in_indexterm && xml_current_element() == TABLE)
894f8dd34f6Sespie     {
895a1acfa9bSespie       in_table_title = 1;
896a1acfa9bSespie       xml_insert_element (TITLE, START);
897f8dd34f6Sespie     }
898f8dd34f6Sespie 
899a1acfa9bSespie   if (arg == START && !xml_in_para && !xml_keep_space
900a1acfa9bSespie       && !xml_element_list[elt].contained_in_para)
901f8dd34f6Sespie     xml_indent ();
902f8dd34f6Sespie 
903f8dd34f6Sespie   if (arg == START)
904f8dd34f6Sespie     xml_push_current_element (elt);
905f8dd34f6Sespie   else
906f8dd34f6Sespie     xml_pop_current_element ();
907f8dd34f6Sespie 
908a1acfa9bSespie   /* Eat one newline before </example> and the like.  */
909a1acfa9bSespie   if (!docbook && arg == END
910a1acfa9bSespie       && (xml_element_list[elt].keep_space || elt == GROUP)
91191e5054cSotto       && output_paragraph_offset > 0
912a1acfa9bSespie       && output_paragraph[output_paragraph_offset-1] == '\n')
913a1acfa9bSespie     output_paragraph_offset--;
914a1acfa9bSespie 
915a1acfa9bSespie   /* And eat whitespace before </entry> in @multitables.  */
916a1acfa9bSespie   if (arg == END && elt == ENTRY)
91791e5054cSotto       while (output_paragraph_offset > 0
91891e5054cSotto 	     && cr_or_whitespace(output_paragraph[output_paragraph_offset-1]))
919a1acfa9bSespie     output_paragraph_offset--;
920a1acfa9bSespie 
921a1acfa9bSespie   /* Indent elements that can contain <para>.  */
922a1acfa9bSespie   if (arg == END && !xml_in_para && !xml_keep_space
923a1acfa9bSespie       && xml_element_list[elt].contains_para)
924a1acfa9bSespie     xml_indent ();
925a1acfa9bSespie 
926a1acfa9bSespie   /* Here are the elements we want indented.  These do not contain <para>
927a1acfa9bSespie      directly.  */
928a1acfa9bSespie   if (arg == END && (elt == MENUENTRY || elt == ITEMIZE || elt == ENUMERATE
929a1acfa9bSespie         || elt == TABLEITEM || elt == TABLE
930a1acfa9bSespie         || elt == MULTITABLE || elt == TGROUP || elt == THEAD || elt == TBODY
931a1acfa9bSespie         || elt == ROW || elt == INFORMALFIGURE
932a1acfa9bSespie         || (!docbook && (elt == DEFINITION || elt == DEFINITIONTERM))))
933a1acfa9bSespie     xml_indent ();
934a1acfa9bSespie 
935f8dd34f6Sespie   insert ('<');
936f8dd34f6Sespie   if (arg == END)
937f8dd34f6Sespie     insert ('/');
938f8dd34f6Sespie   insert_string (xml_element_list[elt].name);
939f8dd34f6Sespie 
940f8dd34f6Sespie   /*  printf ("%s ", xml_element_list[elt].name);*/
941f8dd34f6Sespie 
942f8dd34f6Sespie   if (format)
943f8dd34f6Sespie     {
944f8dd34f6Sespie       char temp_string[2000]; /* xx no fixed limits */
945f8dd34f6Sespie #ifdef VA_SPRINTF
946f8dd34f6Sespie       va_list ap;
947f8dd34f6Sespie #endif
948f8dd34f6Sespie 
949f8dd34f6Sespie       VA_START (ap, format);
950f8dd34f6Sespie #ifdef VA_SPRINTF
951f8dd34f6Sespie       VA_SPRINTF (temp_string, format, ap);
952f8dd34f6Sespie #else
953f8dd34f6Sespie       sprintf (temp_string, format, a1, a2, a3, a4, a5, a6, a7, a8);
954f8dd34f6Sespie #endif
955f8dd34f6Sespie       insert (' ');
956f8dd34f6Sespie       insert_string (temp_string);
957f8dd34f6Sespie       va_end (ap);
958f8dd34f6Sespie     }
959f8dd34f6Sespie 
960f8dd34f6Sespie   if (arg == START && xml_node_id && elt != NODENAME)
961f8dd34f6Sespie     {
962f8dd34f6Sespie       insert_string (" id=\"");
963f8dd34f6Sespie       insert_string (xml_node_id);
964a1acfa9bSespie       insert ('"');
965f8dd34f6Sespie       free (xml_node_id);
966f8dd34f6Sespie       xml_node_id = NULL;
967f8dd34f6Sespie     }
968f8dd34f6Sespie 
969a1acfa9bSespie   if (xml_element_list[elt].keep_space)
970a1acfa9bSespie     {
971a1acfa9bSespie       if (arg == START)
972a1acfa9bSespie 	{
973a1acfa9bSespie           if (!docbook)
974a1acfa9bSespie             insert_string (" xml:space=\"preserve\"");
975a1acfa9bSespie 	  xml_keep_space++;
976a1acfa9bSespie 	}
977a1acfa9bSespie       else
978a1acfa9bSespie 	xml_keep_space--;
979a1acfa9bSespie     }
980a1acfa9bSespie 
981f8dd34f6Sespie   insert ('>');
982f8dd34f6Sespie 
983a1acfa9bSespie   if (!xml_in_para && !xml_element_list[elt].contained_in_para
984a1acfa9bSespie       && xml_element_list[elt].contains_para && xml_indentation_increment > 0)
985a1acfa9bSespie     insert ('\n');
986a1acfa9bSespie 
987f8dd34f6Sespie   xml_just_after_element = 1;
988f8dd34f6Sespie }
989f8dd34f6Sespie 
990f8dd34f6Sespie /* See the NOTE before xml_insert_element_with_attribute, for why we
991f8dd34f6Sespie    use `elt' rather than `element' here.  */
992f8dd34f6Sespie void
993f8dd34f6Sespie xml_insert_element (int elt, int arg)
994f8dd34f6Sespie {
995f8dd34f6Sespie   xml_insert_element_with_attribute (elt, arg, NULL);
996f8dd34f6Sespie }
997f8dd34f6Sespie 
998f8dd34f6Sespie void
999f8dd34f6Sespie xml_insert_entity (char *entity_name)
1000f8dd34f6Sespie {
1001f8dd34f6Sespie   int saved_escape_html = escape_html;
1002f8dd34f6Sespie 
1003f8dd34f6Sespie   if (!book_started)
1004f8dd34f6Sespie     return;
1005f8dd34f6Sespie   if (docbook && !only_macro_expansion && (in_menu || in_detailmenu))
1006f8dd34f6Sespie     return;
1007f8dd34f6Sespie 
1008f8dd34f6Sespie   if (!xml_in_para && !xml_no_para && !only_macro_expansion
1009a1acfa9bSespie       && xml_element_list[xml_current_element ()].contains_para
1010a1acfa9bSespie       && !in_fixed_width_font)
1011a1acfa9bSespie     xml_start_para ();
1012a1acfa9bSespie 
1013f8dd34f6Sespie   escape_html = 0;
1014a1acfa9bSespie   add_char ('&');
1015f8dd34f6Sespie   escape_html = saved_escape_html;
1016f8dd34f6Sespie   insert_string (entity_name);
1017a1acfa9bSespie   add_char (';');
1018f8dd34f6Sespie }
1019f8dd34f6Sespie 
1020f8dd34f6Sespie typedef struct _xml_section xml_section;
1021f8dd34f6Sespie struct _xml_section {
1022f8dd34f6Sespie   int level;
1023f8dd34f6Sespie   char *name;
1024f8dd34f6Sespie   xml_section *prev;
1025f8dd34f6Sespie };
1026f8dd34f6Sespie 
1027f8dd34f6Sespie xml_section *last_section = NULL;
1028f8dd34f6Sespie 
1029f8dd34f6Sespie void
1030a1acfa9bSespie xml_begin_node (void)
1031f8dd34f6Sespie {
1032a1acfa9bSespie   first_section_opened = 1;
1033a1acfa9bSespie   if (xml_in_abstract)
1034a1acfa9bSespie     {
1035a1acfa9bSespie       xml_insert_element (ABSTRACT, END);
1036a1acfa9bSespie       xml_in_abstract = 0;
1037a1acfa9bSespie     }
1038a1acfa9bSespie   if (xml_in_bookinfo)
1039a1acfa9bSespie     {
1040a1acfa9bSespie       xml_insert_element (BOOKINFO, END);
1041a1acfa9bSespie       xml_in_bookinfo = 0;
1042a1acfa9bSespie     }
1043f8dd34f6Sespie   if (xml_node_open && ! docbook)
1044f8dd34f6Sespie     {
1045f8dd34f6Sespie       if (xml_node_level != -1)
1046f8dd34f6Sespie         {
1047f8dd34f6Sespie           xml_close_sections (xml_node_level);
1048f8dd34f6Sespie           xml_node_level = -1;
1049f8dd34f6Sespie         }
1050f8dd34f6Sespie       xml_insert_element (NODE, END);
1051f8dd34f6Sespie     }
1052f8dd34f6Sespie   xml_insert_element (NODE, START);
1053f8dd34f6Sespie   xml_node_open = 1;
1054f8dd34f6Sespie }
1055f8dd34f6Sespie 
1056f8dd34f6Sespie void
1057a1acfa9bSespie xml_close_sections (int level)
1058f8dd34f6Sespie {
1059a1acfa9bSespie   if (!first_section_opened)
1060a1acfa9bSespie     {
1061a1acfa9bSespie       if (xml_in_abstract)
1062f8dd34f6Sespie 	{
1063f8dd34f6Sespie 	  xml_insert_element (ABSTRACT, END);
1064a1acfa9bSespie 	  xml_in_abstract = 0;
1065a1acfa9bSespie 	}
1066a1acfa9bSespie       if (xml_in_bookinfo)
1067a1acfa9bSespie 	{
1068f8dd34f6Sespie 	  xml_insert_element (BOOKINFO, END);
1069a1acfa9bSespie 	  xml_in_bookinfo = 0;
1070a1acfa9bSespie 	}
1071f8dd34f6Sespie       first_section_opened = 1;
1072f8dd34f6Sespie     }
1073a1acfa9bSespie 
1074f8dd34f6Sespie   while (last_section && last_section->level >= level)
1075f8dd34f6Sespie     {
1076f8dd34f6Sespie       xml_section *temp = last_section;
1077f8dd34f6Sespie       xml_insert_element (xml_element(last_section->name), END);
1078f8dd34f6Sespie       temp = last_section;
1079f8dd34f6Sespie       last_section = last_section->prev;
1080f8dd34f6Sespie       free (temp->name);
1081f8dd34f6Sespie       free (temp);
1082f8dd34f6Sespie     }
1083f8dd34f6Sespie }
1084f8dd34f6Sespie 
1085f8dd34f6Sespie void
1086a1acfa9bSespie xml_open_section (int level, char *name)
1087f8dd34f6Sespie {
1088f8dd34f6Sespie   xml_section *sect = (xml_section *) xmalloc (sizeof (xml_section));
1089f8dd34f6Sespie 
1090f8dd34f6Sespie   sect->level = level;
1091f8dd34f6Sespie   sect->name = xmalloc (1 + strlen (name));
1092f8dd34f6Sespie   strcpy (sect->name, name);
1093f8dd34f6Sespie   sect->prev = last_section;
1094f8dd34f6Sespie   last_section = sect;
1095f8dd34f6Sespie 
1096f8dd34f6Sespie   if (xml_node_open && xml_node_level == -1)
1097f8dd34f6Sespie     xml_node_level = level;
1098f8dd34f6Sespie }
1099f8dd34f6Sespie 
1100f8dd34f6Sespie void
1101a1acfa9bSespie xml_start_menu_entry (char *tem)
1102f8dd34f6Sespie {
1103f8dd34f6Sespie   char *string;
1104f8dd34f6Sespie   discard_until ("* ");
1105f8dd34f6Sespie 
1106f8dd34f6Sespie   /* The line number was already incremented in reader_loop when we
1107f8dd34f6Sespie      saw the newline, and discard_until has now incremented again.  */
1108f8dd34f6Sespie   line_number--;
1109f8dd34f6Sespie 
1110f8dd34f6Sespie   if (xml_in_menu_entry)
1111f8dd34f6Sespie     {
1112f8dd34f6Sespie       if (xml_in_menu_entry_comment)
1113f8dd34f6Sespie         {
1114f8dd34f6Sespie           xml_insert_element (MENUCOMMENT, END);
1115f8dd34f6Sespie           xml_in_menu_entry_comment=0;
1116f8dd34f6Sespie         }
1117f8dd34f6Sespie       xml_insert_element (MENUENTRY, END);
1118f8dd34f6Sespie       xml_in_menu_entry=0;
1119f8dd34f6Sespie     }
1120f8dd34f6Sespie   xml_insert_element (MENUENTRY, START);
1121f8dd34f6Sespie   xml_in_menu_entry=1;
1122f8dd34f6Sespie 
1123f8dd34f6Sespie   xml_insert_element (MENUNODE, START);
1124f8dd34f6Sespie   string = expansion (tem, 0);
1125f8dd34f6Sespie   add_word (string);
1126f8dd34f6Sespie   xml_insert_element (MENUNODE, END);
1127f8dd34f6Sespie   free (string);
1128f8dd34f6Sespie 
1129f8dd34f6Sespie   /* The menu item may use macros, so expand them now.  */
1130f8dd34f6Sespie   xml_insert_element (MENUTITLE, START);
1131f8dd34f6Sespie   only_macro_expansion++;
1132f8dd34f6Sespie   get_until_in_line (1, ":", &string);
1133f8dd34f6Sespie   only_macro_expansion--;
1134f8dd34f6Sespie   execute_string ("%s", string); /* get escaping done */
1135f8dd34f6Sespie   xml_insert_element (MENUTITLE, END);
1136f8dd34f6Sespie   free (string);
1137f8dd34f6Sespie 
1138f8dd34f6Sespie   if (looking_at ("::"))
1139f8dd34f6Sespie     discard_until (":");
1140f8dd34f6Sespie   else
1141f8dd34f6Sespie     { /* discard the node name */
1142f8dd34f6Sespie       get_until_in_line (0, ".", &string);
1143f8dd34f6Sespie       free (string);
1144f8dd34f6Sespie     }
1145f8dd34f6Sespie   input_text_offset++;  /* discard the second colon or the period */
1146a1acfa9bSespie   skip_whitespace_and_newlines();
1147f8dd34f6Sespie   xml_insert_element (MENUCOMMENT, START);
1148f8dd34f6Sespie   xml_in_menu_entry_comment ++;
1149f8dd34f6Sespie }
1150f8dd34f6Sespie 
1151f8dd34f6Sespie void
1152a1acfa9bSespie xml_end_menu (void)
1153f8dd34f6Sespie {
1154f8dd34f6Sespie   if (xml_in_menu_entry)
1155f8dd34f6Sespie     {
1156f8dd34f6Sespie       if (xml_in_menu_entry_comment)
1157f8dd34f6Sespie         {
1158f8dd34f6Sespie           xml_insert_element (MENUCOMMENT, END);
1159f8dd34f6Sespie           xml_in_menu_entry_comment --;
1160f8dd34f6Sespie         }
1161f8dd34f6Sespie       xml_insert_element (MENUENTRY, END);
1162f8dd34f6Sespie       xml_in_menu_entry--;
1163f8dd34f6Sespie     }
1164f8dd34f6Sespie   xml_insert_element (MENU, END);
1165f8dd34f6Sespie }
1166f8dd34f6Sespie 
1167f8dd34f6Sespie static int xml_last_character;
1168f8dd34f6Sespie 
1169f8dd34f6Sespie void
1170a1acfa9bSespie xml_add_char (int character)
1171f8dd34f6Sespie {
1172f8dd34f6Sespie   if (!book_started)
1173f8dd34f6Sespie       return;
1174f8dd34f6Sespie   if (docbook && !only_macro_expansion && (in_menu || in_detailmenu))
1175f8dd34f6Sespie     return;
1176f8dd34f6Sespie 
1177a1acfa9bSespie   if (docbook && xml_table_level && !in_table_title
1178a1acfa9bSespie       && !xml_in_item[xml_table_level] && !xml_in_tableitem[xml_table_level]
1179a1acfa9bSespie       && !cr_or_whitespace (character) && !in_indexterm)
1180f8dd34f6Sespie     {
1181a1acfa9bSespie       in_table_title = 1;
1182a1acfa9bSespie       xml_insert_element (TITLE, START);
1183f8dd34f6Sespie     }
1184f8dd34f6Sespie 
1185a1acfa9bSespie   if (!first_section_opened && !xml_in_abstract && !xml_in_book_title
1186a1acfa9bSespie       && !xml_no_para && character != '\r' && character != '\n'
1187a1acfa9bSespie       && character != ' ' && !is_in_insertion_of_type (copying))
1188a1acfa9bSespie     {
1189a1acfa9bSespie       if (!xml_in_bookinfo)
1190a1acfa9bSespie 	{
1191a1acfa9bSespie 	  xml_insert_element (BOOKINFO, START);
1192a1acfa9bSespie 	  xml_in_bookinfo = 1;
1193a1acfa9bSespie 	}
1194a1acfa9bSespie       xml_insert_element (ABSTRACT, START);
1195a1acfa9bSespie       xml_in_abstract = 1;
1196a1acfa9bSespie     }
1197a1acfa9bSespie 
1198a1acfa9bSespie   if (!xml_sort_index && !xml_in_xref_token && !xml_dont_touch_items_defs)
1199a1acfa9bSespie     {
1200a1acfa9bSespie       if (xml_after_table_term && xml_table_level
1201a1acfa9bSespie           && !xml_in_item[xml_table_level])
1202f8dd34f6Sespie         {
1203f8dd34f6Sespie           xml_after_table_term = 0;
1204f8dd34f6Sespie           xml_insert_element (ITEM, START);
1205a1acfa9bSespie           xml_in_item[xml_table_level] = 1;
1206a1acfa9bSespie         }
1207a1acfa9bSespie       else if (xml_after_def_term)
1208a1acfa9bSespie         {
1209a1acfa9bSespie           xml_after_def_term = 0;
1210a1acfa9bSespie           xml_insert_element (DEFINITIONITEM, START);
1211a1acfa9bSespie           xml_in_def_item[xml_definition_level] = 1;
1212a1acfa9bSespie         }
1213f8dd34f6Sespie     }
1214f8dd34f6Sespie 
1215f8dd34f6Sespie   if (xml_just_after_element && !xml_in_para && !inhibit_paragraph_indentation)
1216f8dd34f6Sespie     {
1217f8dd34f6Sespie       if (character == '\r' || character == '\n' || character == '\t' || character == ' ')
1218f8dd34f6Sespie         return;
1219f8dd34f6Sespie       xml_just_after_element = 0;
1220f8dd34f6Sespie     }
1221f8dd34f6Sespie 
1222f8dd34f6Sespie   if (xml_element_list[xml_current_element()].contains_para
1223a1acfa9bSespie       && !xml_in_para && !only_macro_expansion && !xml_no_para
1224a1acfa9bSespie       && !cr_or_whitespace (character) && !in_fixed_width_font)
1225a1acfa9bSespie     xml_start_para ();
1226f8dd34f6Sespie 
1227a1acfa9bSespie   if (xml_in_para && character == '\n' && xml_last_character == '\n'
1228a1acfa9bSespie       && !only_macro_expansion && !xml_no_para
1229f8dd34f6Sespie       && xml_element_list[xml_current_element()].contains_para )
1230f8dd34f6Sespie     {
1231a1acfa9bSespie       xml_end_para ();
1232f8dd34f6Sespie       xml_just_after_element = 1;
1233a1acfa9bSespie       return;
1234a1acfa9bSespie     }
1235a1acfa9bSespie 
1236a1acfa9bSespie   if (xml_in_menu_entry_comment && character == '\n' && xml_last_character == '\n')
1237f8dd34f6Sespie     {
1238f8dd34f6Sespie       xml_insert_element (MENUCOMMENT, END);
1239f8dd34f6Sespie       xml_in_menu_entry_comment = 0;
1240f8dd34f6Sespie       xml_insert_element (MENUENTRY, END);
1241f8dd34f6Sespie       xml_in_menu_entry = 0;
1242f8dd34f6Sespie     }
1243a1acfa9bSespie 
1244a1acfa9bSespie   if (xml_in_menu_entry_comment && whitespace(character)
1245a1acfa9bSespie       && cr_or_whitespace(xml_last_character))
1246a1acfa9bSespie     return;
1247f8dd34f6Sespie 
1248f8dd34f6Sespie   if (character == '\n' && !xml_in_para && !inhibit_paragraph_indentation)
1249f8dd34f6Sespie     return;
1250f8dd34f6Sespie 
1251f8dd34f6Sespie   xml_last_character = character;
1252f8dd34f6Sespie 
1253f8dd34f6Sespie   if (character == '&' && escape_html)
1254f8dd34f6Sespie       insert_string ("&amp;");
1255f8dd34f6Sespie   else if (character == '<' && escape_html)
1256f8dd34f6Sespie       insert_string ("&lt;");
1257a1acfa9bSespie   else if (character == '\n' && !xml_keep_space)
1258a1acfa9bSespie     {
1259a1acfa9bSespie       if (!xml_in_para && xml_just_after_element && !multitable_active)
1260a1acfa9bSespie 	return;
1261a1acfa9bSespie       else
1262a1acfa9bSespie 	insert (docbook ? '\n' : ' ');
1263a1acfa9bSespie     }
1264f8dd34f6Sespie   else
1265f8dd34f6Sespie     insert (character);
1266f8dd34f6Sespie 
1267f8dd34f6Sespie   return;
1268f8dd34f6Sespie }
1269f8dd34f6Sespie 
1270f8dd34f6Sespie void
1271a1acfa9bSespie xml_insert_footnote (char *note)
1272f8dd34f6Sespie {
1273a1acfa9bSespie   if (!xml_in_para)
1274a1acfa9bSespie     xml_start_para ();
1275a1acfa9bSespie 
1276a1acfa9bSespie   xml_in_footnote = 1;
1277f8dd34f6Sespie   xml_insert_element (FOOTNOTE, START);
1278f8dd34f6Sespie   insert_string ("<para>");
1279f8dd34f6Sespie   execute_string ("%s", note);
1280f8dd34f6Sespie   insert_string ("</para>");
1281f8dd34f6Sespie   xml_insert_element (FOOTNOTE, END);
1282a1acfa9bSespie   xml_in_footnote = 0;
1283f8dd34f6Sespie }
1284f8dd34f6Sespie 
1285a1acfa9bSespie /* We need to keep the quotation stack ourself, because insertion_stack
1286a1acfa9bSespie    loses item_function when we are closing the block, so we don't know
1287a1acfa9bSespie    what to close then.  */
1288a1acfa9bSespie typedef struct quotation_elt
1289a1acfa9bSespie {
1290a1acfa9bSespie   struct quotation_elt *next;
1291a1acfa9bSespie   char *type;
1292a1acfa9bSespie } QUOTATION_ELT;
1293a1acfa9bSespie 
1294a1acfa9bSespie static QUOTATION_ELT *quotation_stack = NULL;
1295a1acfa9bSespie 
1296a1acfa9bSespie void
1297a1acfa9bSespie xml_insert_quotation (char *type, int arg)
1298a1acfa9bSespie {
1299a1acfa9bSespie   int quotation_started = 0;
1300a1acfa9bSespie 
1301a1acfa9bSespie   if (arg == START)
1302a1acfa9bSespie     {
1303a1acfa9bSespie       QUOTATION_ELT *new = xmalloc (sizeof (QUOTATION_ELT));
1304a1acfa9bSespie       new->type = xstrdup (type);
1305a1acfa9bSespie       new->next = quotation_stack;
1306a1acfa9bSespie       quotation_stack = new;
1307a1acfa9bSespie     }
1308a1acfa9bSespie   else
1309a1acfa9bSespie     type = quotation_stack->type;
1310a1acfa9bSespie 
1311a1acfa9bSespie   /* Make use of special quotation styles of Docbook if we can.  */
1312a1acfa9bSespie   if (docbook && strlen(type))
1313a1acfa9bSespie     {
1314a1acfa9bSespie       /* Let's assume it started.  */
1315a1acfa9bSespie       quotation_started = 1;
1316a1acfa9bSespie 
1317a1acfa9bSespie       if (strcasecmp (type, "tip") == 0)
1318a1acfa9bSespie         xml_insert_element (TIP, arg);
1319a1acfa9bSespie       else if (strcasecmp (type, "note") == 0)
1320a1acfa9bSespie         xml_insert_element (NOTE, arg);
1321a1acfa9bSespie       else if (strcasecmp (type, "important") == 0)
1322a1acfa9bSespie         xml_insert_element (IMPORTANT, arg);
1323a1acfa9bSespie       else if (strcasecmp (type, "warning") == 0)
1324a1acfa9bSespie         xml_insert_element (WARNING, arg);
1325a1acfa9bSespie       else if (strcasecmp (type, "caution") == 0)
1326a1acfa9bSespie         xml_insert_element (CAUTION, arg);
1327a1acfa9bSespie       else
1328a1acfa9bSespie         /* Didn't find a known quotation type :\ */
1329a1acfa9bSespie         quotation_started = 0;
1330a1acfa9bSespie     }
1331a1acfa9bSespie 
1332a1acfa9bSespie   if (!quotation_started)
1333a1acfa9bSespie     {
1334a1acfa9bSespie       xml_insert_element (QUOTATION, arg);
1335a1acfa9bSespie       if (strlen(type) && arg == START)
1336a1acfa9bSespie         execute_string ("@b{%s:} ", type);
1337a1acfa9bSespie     }
1338a1acfa9bSespie 
1339a1acfa9bSespie   if (arg == END)
1340a1acfa9bSespie     {
1341a1acfa9bSespie       QUOTATION_ELT *temp = quotation_stack;
1342a1acfa9bSespie       if (temp == NULL)
1343a1acfa9bSespie         return;
1344a1acfa9bSespie       quotation_stack = quotation_stack->next;
1345a1acfa9bSespie       free(temp->type);
1346a1acfa9bSespie       free(temp);
1347a1acfa9bSespie     }
1348a1acfa9bSespie }
1349a1acfa9bSespie 
1350a1acfa9bSespie /* Starting generic docbook floats.  Just starts elt with correct label
1351a1acfa9bSespie    and id attributes, and inserts title.  */
1352a1acfa9bSespie void
1353a1acfa9bSespie xml_begin_docbook_float (int elt)
1354a1acfa9bSespie {
1355a1acfa9bSespie   if (current_float_used_title ())	/* in a nested float */
1356a1acfa9bSespie     {
1357a1acfa9bSespie       xml_insert_element (elt, START);	/* just insert the tag */
1358a1acfa9bSespie       return;
1359a1acfa9bSespie     }
1360a1acfa9bSespie 
1361a1acfa9bSespie 
1362a1acfa9bSespie   /* OK, need the title, tag, etc. */
1363a1acfa9bSespie   if (elt == CARTOUCHE)    /* no labels on <sidebar> */
1364a1acfa9bSespie     {
1365a1acfa9bSespie        if (strlen (current_float_id ()) == 0)
1366a1acfa9bSespie           xml_insert_element (elt, START);
1367a1acfa9bSespie        else
1368a1acfa9bSespie           xml_insert_element_with_attribute (elt, START,
1369a1acfa9bSespie               "id=\"%s\"", xml_id (current_float_id ()));
1370a1acfa9bSespie     }
1371a1acfa9bSespie   else if (strlen (current_float_id ()) == 0)
1372a1acfa9bSespie     xml_insert_element_with_attribute (elt, START, "label=\"\"");
1373a1acfa9bSespie   else
1374a1acfa9bSespie     xml_insert_element_with_attribute (elt, START,
1375a1acfa9bSespie         "id=\"%s\" label=\"%s\"", xml_id (current_float_id ()),
1376a1acfa9bSespie         current_float_number ());
1377a1acfa9bSespie 
1378a1acfa9bSespie   xml_insert_element (TITLE, START);
1379a1acfa9bSespie   execute_string ("%s", current_float_title ());
1380a1acfa9bSespie   xml_insert_element (TITLE, END);
1381a1acfa9bSespie 
1382a1acfa9bSespie   current_float_set_title_used ();	/* mark this title, tag, etc used */
1383a1acfa9bSespie }
1384f8dd34f6Sespie 
1385f8dd34f6Sespie /*
1386f8dd34f6Sespie  * Lists and Tables
1387f8dd34f6Sespie  */
1388f8dd34f6Sespie void
1389a1acfa9bSespie xml_begin_table (int type, char *item_function)
1390f8dd34f6Sespie {
1391f8dd34f6Sespie   switch (type)
1392f8dd34f6Sespie     {
1393f8dd34f6Sespie     case ftable:
1394f8dd34f6Sespie     case vtable:
1395f8dd34f6Sespie     case table:
1396f8dd34f6Sespie       /*if (docbook)*/ /* 05-08 */
1397f8dd34f6Sespie         {
1398f8dd34f6Sespie           xml_insert_element (TABLE, START);
1399f8dd34f6Sespie           xml_table_level ++;
1400a1acfa9bSespie           xml_in_tableitem[xml_table_level] = 0;
1401f8dd34f6Sespie           xml_in_item[xml_table_level] = 0;
1402a1acfa9bSespie           xml_after_table_term = 0;
1403f8dd34f6Sespie         }
1404f8dd34f6Sespie       break;
1405f8dd34f6Sespie     case itemize:
1406f8dd34f6Sespie       if (!docbook)
1407f8dd34f6Sespie         {
1408f8dd34f6Sespie           xml_insert_element (ITEMIZE, START);
1409f8dd34f6Sespie           xml_table_level ++;
1410f8dd34f6Sespie           xml_in_item[xml_table_level] = 0;
1411f8dd34f6Sespie           xml_insert_element (ITEMFUNCTION, START);
1412f8dd34f6Sespie           if (*item_function == COMMAND_PREFIX
1413f8dd34f6Sespie               && item_function[strlen (item_function) - 1] != '}'
1414f8dd34f6Sespie               && command_needs_braces (item_function + 1))
1415f8dd34f6Sespie             execute_string ("%s{}", item_function);
1416f8dd34f6Sespie           else
1417f8dd34f6Sespie             execute_string ("%s", item_function);
1418f8dd34f6Sespie           xml_insert_element (ITEMFUNCTION, END);
1419f8dd34f6Sespie         }
1420f8dd34f6Sespie       else
1421f8dd34f6Sespie         {
1422f8dd34f6Sespie           xml_insert_element_with_attribute (ITEMIZE, START,
1423f8dd34f6Sespie                                              "mark=\"%s\"",
1424f8dd34f6Sespie                                              (*item_function == COMMAND_PREFIX) ?
1425f8dd34f6Sespie                                              &item_function[1] : item_function);
1426f8dd34f6Sespie           xml_table_level ++;
1427f8dd34f6Sespie           xml_in_item[xml_table_level] = 0;
1428f8dd34f6Sespie         }
1429f8dd34f6Sespie       break;
1430f8dd34f6Sespie     }
1431f8dd34f6Sespie }
1432f8dd34f6Sespie 
1433f8dd34f6Sespie void
1434a1acfa9bSespie xml_end_table (int type)
1435f8dd34f6Sespie {
1436f8dd34f6Sespie   switch (type)
1437f8dd34f6Sespie     {
1438f8dd34f6Sespie     case ftable:
1439f8dd34f6Sespie     case vtable:
1440f8dd34f6Sespie     case table:
1441f8dd34f6Sespie       if (xml_in_item[xml_table_level])
1442f8dd34f6Sespie         {
1443f8dd34f6Sespie           xml_insert_element (ITEM, END);
1444f8dd34f6Sespie           xml_in_item[xml_table_level] = 0;
1445f8dd34f6Sespie         }
1446a1acfa9bSespie       if (xml_in_tableitem[xml_table_level])
1447a1acfa9bSespie         {
1448a1acfa9bSespie           xml_insert_element (TABLEITEM, END);
1449a1acfa9bSespie           xml_in_tableitem[xml_table_level] = 0;
1450f8dd34f6Sespie         }
1451a1acfa9bSespie       xml_insert_element (TABLE, END);
1452a1acfa9bSespie       xml_after_table_term = 0;
1453a1acfa9bSespie       xml_table_level --;
1454a1acfa9bSespie 
1455f8dd34f6Sespie       break;
1456f8dd34f6Sespie     case itemize:
1457f8dd34f6Sespie       if (xml_in_item[xml_table_level])
1458f8dd34f6Sespie         {
1459f8dd34f6Sespie           xml_insert_element (ITEM, END);
1460f8dd34f6Sespie           xml_in_item[xml_table_level] = 0;
1461f8dd34f6Sespie         }
1462a1acfa9bSespie       /* gnat-style manual contains an itemized list without items! */
1463a1acfa9bSespie       if (in_table_title)
1464a1acfa9bSespie 	{
1465a1acfa9bSespie 	  xml_insert_element (TITLE, END);
1466a1acfa9bSespie 	  in_table_title = 0;
1467a1acfa9bSespie 	}
1468f8dd34f6Sespie       xml_insert_element (ITEMIZE, END);
1469f8dd34f6Sespie       xml_table_level --;
1470f8dd34f6Sespie       break;
1471f8dd34f6Sespie     }
1472f8dd34f6Sespie }
1473f8dd34f6Sespie 
1474f8dd34f6Sespie void
1475a1acfa9bSespie xml_begin_item (void)
1476f8dd34f6Sespie {
1477f8dd34f6Sespie   if (xml_in_item[xml_table_level])
1478f8dd34f6Sespie     xml_insert_element (ITEM, END);
1479f8dd34f6Sespie 
1480f8dd34f6Sespie   xml_insert_element (ITEM, START);
1481f8dd34f6Sespie   xml_in_item[xml_table_level] = 1;
1482f8dd34f6Sespie }
1483f8dd34f6Sespie 
1484f8dd34f6Sespie void
1485a1acfa9bSespie xml_begin_table_item (void)
1486f8dd34f6Sespie {
1487f8dd34f6Sespie   if (!xml_after_table_term)
1488f8dd34f6Sespie     {
1489f8dd34f6Sespie       if (xml_in_item[xml_table_level])
1490f8dd34f6Sespie         xml_insert_element (ITEM, END);
1491a1acfa9bSespie       if (xml_in_tableitem[xml_table_level])
1492f8dd34f6Sespie         xml_insert_element (TABLEITEM, END);
1493a1acfa9bSespie 
1494a1acfa9bSespie       if (in_table_title)
1495a1acfa9bSespie 	{
1496a1acfa9bSespie 	  in_table_title = 0;
1497a1acfa9bSespie 	  xml_insert_element (TITLE, END);
1498f8dd34f6Sespie 	}
1499f8dd34f6Sespie       xml_insert_element (TABLEITEM, START);
1500f8dd34f6Sespie     }
1501f8dd34f6Sespie   xml_insert_element (TABLETERM, START);
1502a1acfa9bSespie   xml_in_tableitem[xml_table_level] = 1;
1503a1acfa9bSespie   xml_in_item[xml_table_level] = 0;
1504f8dd34f6Sespie   xml_after_table_term = 0;
1505f8dd34f6Sespie }
1506f8dd34f6Sespie 
1507f8dd34f6Sespie void
1508a1acfa9bSespie xml_continue_table_item (void)
1509f8dd34f6Sespie {
1510f8dd34f6Sespie   xml_insert_element (TABLETERM, END);
1511f8dd34f6Sespie   xml_after_table_term = 1;
1512a1acfa9bSespie   xml_in_item[xml_table_level] = 0;
1513f8dd34f6Sespie }
1514f8dd34f6Sespie 
1515f8dd34f6Sespie void
1516a1acfa9bSespie xml_begin_enumerate (char *enum_arg)
1517f8dd34f6Sespie {
1518f8dd34f6Sespie   if (!docbook)
1519f8dd34f6Sespie     xml_insert_element_with_attribute (ENUMERATE, START, "first=\"%s\"", enum_arg);
1520f8dd34f6Sespie   else
1521f8dd34f6Sespie     {
1522f8dd34f6Sespie       if (isdigit (*enum_arg))
1523f8dd34f6Sespie         {
1524a1acfa9bSespie           int enum_val = atoi (enum_arg);
1525a1acfa9bSespie 
1526a1acfa9bSespie           /* Have to check the value, not just the first digit.  */
1527a1acfa9bSespie           if (enum_val == 0)
1528f8dd34f6Sespie             xml_insert_element_with_attribute (ENUMERATE, START,
1529a1acfa9bSespie                 "numeration=\"arabic\" role=\"0\"", NULL);
1530a1acfa9bSespie           else if (enum_val == 1)
1531a1acfa9bSespie             xml_insert_element_with_attribute (ENUMERATE, START,
1532a1acfa9bSespie                 "numeration=\"arabic\"", NULL);
1533f8dd34f6Sespie           else
1534f8dd34f6Sespie             xml_insert_element_with_attribute (ENUMERATE, START,
1535a1acfa9bSespie                 "continuation=\"continues\" numeration=\"arabic\"", NULL);
1536f8dd34f6Sespie         }
1537f8dd34f6Sespie       else if (isupper (*enum_arg))
1538f8dd34f6Sespie         {
1539f8dd34f6Sespie           if (enum_arg[0] == 'A')
1540f8dd34f6Sespie             xml_insert_element_with_attribute (ENUMERATE, START,
1541a1acfa9bSespie                 "numeration=\"upperalpha\"", NULL);
1542f8dd34f6Sespie           else
1543f8dd34f6Sespie             xml_insert_element_with_attribute (ENUMERATE, START,
1544a1acfa9bSespie                 "continuation=\"continues\" numeration=\"upperalpha\"", NULL);
1545f8dd34f6Sespie         }
1546f8dd34f6Sespie       else
1547f8dd34f6Sespie         {
1548f8dd34f6Sespie           if (enum_arg[0] == 'a')
1549f8dd34f6Sespie             xml_insert_element_with_attribute (ENUMERATE, START,
1550a1acfa9bSespie                 "numeration=\"loweralpha\"", NULL);
1551f8dd34f6Sespie           else
1552f8dd34f6Sespie             xml_insert_element_with_attribute (ENUMERATE, START,
1553a1acfa9bSespie                 "continuation=\"continues\" numeration=\"loweralpha\"", NULL);
1554f8dd34f6Sespie         }
1555f8dd34f6Sespie     }
1556f8dd34f6Sespie   xml_table_level ++;
1557f8dd34f6Sespie   xml_in_item[xml_table_level] = 0;
1558f8dd34f6Sespie }
1559f8dd34f6Sespie 
1560f8dd34f6Sespie void
1561a1acfa9bSespie xml_end_enumerate (void)
1562f8dd34f6Sespie {
1563f8dd34f6Sespie   if (xml_in_item[xml_table_level])
1564f8dd34f6Sespie     {
1565f8dd34f6Sespie       xml_insert_element (ITEM, END);
1566f8dd34f6Sespie       xml_in_item[xml_table_level] = 0;
1567f8dd34f6Sespie     }
1568f8dd34f6Sespie   xml_insert_element (ENUMERATE, END);
1569f8dd34f6Sespie   xml_table_level --;
1570f8dd34f6Sespie }
1571f8dd34f6Sespie 
1572f8dd34f6Sespie static void
1573a1acfa9bSespie xml_insert_text_file (char *name_arg)
1574f8dd34f6Sespie {
1575f8dd34f6Sespie   char *fullname = xmalloc (strlen (name_arg) + 4 + 1);
1576f8dd34f6Sespie   FILE *image_file;
1577f8dd34f6Sespie   strcpy (fullname, name_arg);
1578f8dd34f6Sespie   strcat (fullname, ".txt");
1579f8dd34f6Sespie   image_file = fopen (fullname, "r");
1580f8dd34f6Sespie   if (image_file)
1581f8dd34f6Sespie     {
1582f8dd34f6Sespie       int ch;
1583f8dd34f6Sespie       int save_inhibit_indentation = inhibit_paragraph_indentation;
1584f8dd34f6Sespie       int save_filling_enabled = filling_enabled;
1585f8dd34f6Sespie 
1586f8dd34f6Sespie       xml_insert_element (TEXTOBJECT, START);
1587f8dd34f6Sespie       xml_insert_element (DISPLAY, START);
1588f8dd34f6Sespie 
1589f8dd34f6Sespie       inhibit_paragraph_indentation = 1;
1590f8dd34f6Sespie       filling_enabled = 0;
1591f8dd34f6Sespie       last_char_was_newline = 0;
1592f8dd34f6Sespie 
1593f8dd34f6Sespie       /* Maybe we need to remove the final newline if the image
1594f8dd34f6Sespie          file is only one line to allow in-line images.  On the
1595f8dd34f6Sespie          other hand, they could just make the file without a
1596f8dd34f6Sespie          final newline.  */
1597f8dd34f6Sespie       while ((ch = getc (image_file)) != EOF)
1598f8dd34f6Sespie         add_char (ch);
1599f8dd34f6Sespie 
1600f8dd34f6Sespie       inhibit_paragraph_indentation = save_inhibit_indentation;
1601f8dd34f6Sespie       filling_enabled = save_filling_enabled;
1602f8dd34f6Sespie 
1603f8dd34f6Sespie       xml_insert_element (DISPLAY, END);
1604f8dd34f6Sespie       xml_insert_element (TEXTOBJECT, END);
1605f8dd34f6Sespie 
1606f8dd34f6Sespie       if (fclose (image_file) != 0)
1607f8dd34f6Sespie         perror (fullname);
1608f8dd34f6Sespie     }
1609f8dd34f6Sespie   else
1610f8dd34f6Sespie     warning (_("@image file `%s' unreadable: %s"), fullname,
1611f8dd34f6Sespie              strerror (errno));
1612f8dd34f6Sespie 
1613f8dd34f6Sespie   free (fullname);
1614f8dd34f6Sespie }
1615f8dd34f6Sespie 
1616a1acfa9bSespie /* If NAME.EXT is accessible or FORCE is nonzero, insert a docbook
1617a1acfa9bSespie    imagedata element for FMT.  Return 1 if inserted something, 0 else.  */
1618a1acfa9bSespie 
1619a1acfa9bSespie static int
1620a1acfa9bSespie try_docbook_image (const char *name, const char *ext, const char *fmt,
1621a1acfa9bSespie                    int force)
1622f8dd34f6Sespie {
1623a1acfa9bSespie   int used = 0;
1624a1acfa9bSespie   char *fullname = xmalloc (strlen (name) + 1 + strlen (ext) + 1);
1625a1acfa9bSespie   sprintf (fullname, "%s.%s", name, ext);
1626a1acfa9bSespie 
1627a1acfa9bSespie   if (force || access (fullname, R_OK) == 0)
1628a1acfa9bSespie    {
1629a1acfa9bSespie      xml_insert_element (IMAGEOBJECT, START);
1630a1acfa9bSespie      xml_insert_element_with_attribute (IMAGEDATA, START,
1631a1acfa9bSespie        "fileref=\"%s\" format=\"%s\"", fullname, fmt);
1632a1acfa9bSespie      xml_insert_element (IMAGEDATA, END);
1633a1acfa9bSespie      xml_insert_element (IMAGEOBJECT, END);
1634a1acfa9bSespie      used = 1;
1635a1acfa9bSespie    }
1636a1acfa9bSespie 
1637a1acfa9bSespie  free (fullname);
1638a1acfa9bSespie  return used;
1639a1acfa9bSespie }
1640a1acfa9bSespie 
1641a1acfa9bSespie 
1642a1acfa9bSespie void
1643a1acfa9bSespie xml_insert_docbook_image (char *name_arg)
1644a1acfa9bSespie {
1645a1acfa9bSespie   int found = 0;
1646a1acfa9bSespie   int elt = xml_in_para ? INLINEIMAGE : MEDIAOBJECT;
1647a1acfa9bSespie 
1648a1acfa9bSespie   if (is_in_insertion_of_type (floatenv))
1649a1acfa9bSespie     xml_begin_docbook_float (INFORMALFIGURE);
1650a1acfa9bSespie   else if (!xml_in_para)
1651f8dd34f6Sespie     xml_insert_element (INFORMALFIGURE, START);
1652f8dd34f6Sespie 
1653a1acfa9bSespie   xml_no_para++;
1654f8dd34f6Sespie 
1655a1acfa9bSespie   xml_insert_element (elt, START);
1656a1acfa9bSespie 
1657a1acfa9bSespie   /* A selected few from http://docbook.org/tdg/en/html/imagedata.html.  */
1658a1acfa9bSespie   if (try_docbook_image (name_arg, "eps", "EPS", 0))
1659a1acfa9bSespie     found++;
1660a1acfa9bSespie   if (try_docbook_image (name_arg, "gif", "GIF", 0))
1661a1acfa9bSespie     found++;
1662a1acfa9bSespie   if (try_docbook_image (name_arg, "jpg", "JPG", 0))
1663a1acfa9bSespie     found++;
1664a1acfa9bSespie   if (try_docbook_image (name_arg, "jpeg", "JPEG", 0))
1665a1acfa9bSespie     found++;
1666a1acfa9bSespie   if (try_docbook_image (name_arg, "pdf", "PDF", 0))
1667a1acfa9bSespie     found++;
1668a1acfa9bSespie   if (try_docbook_image (name_arg, "png", "PNG", 0))
1669a1acfa9bSespie     found++;
1670a1acfa9bSespie   if (try_docbook_image (name_arg, "svg", "SVG", 0))
1671a1acfa9bSespie     found++;
1672a1acfa9bSespie 
1673a1acfa9bSespie   /* If no luck so far, just assume we'll eventually have a jpg.  */
1674a1acfa9bSespie   if (!found)
1675a1acfa9bSespie     try_docbook_image (name_arg, "jpg", "JPG", 1);
1676f8dd34f6Sespie 
1677f8dd34f6Sespie   xml_insert_text_file (name_arg);
1678a1acfa9bSespie   xml_insert_element (elt, END);
1679f8dd34f6Sespie 
1680a1acfa9bSespie   xml_no_para--;
1681a1acfa9bSespie 
1682a1acfa9bSespie   if (elt == MEDIAOBJECT)
1683f8dd34f6Sespie     xml_insert_element (INFORMALFIGURE, END);
1684f8dd34f6Sespie }
1685f8dd34f6Sespie 
1686f8dd34f6Sespie void
1687a1acfa9bSespie xml_asterisk (void)
1688f8dd34f6Sespie {
1689f8dd34f6Sespie }
1690f8dd34f6Sespie 
1691f8dd34f6Sespie 
1692f8dd34f6Sespie /*
1693f8dd34f6Sespie  *     INDEX
1694f8dd34f6Sespie  */
1695a1acfa9bSespie /* Used to separate primary and secondary entries in an index -- we need
1696a1acfa9bSespie    to have real multilivel indexing support, not just string analysis.  */
1697a1acfa9bSespie #define INDEX_SEP "@this string will never appear@" /* was , */
1698f8dd34f6Sespie 
1699a1acfa9bSespie typedef struct
1700f8dd34f6Sespie {
1701a1acfa9bSespie   char *from;
1702a1acfa9bSespie   char *to;
1703a1acfa9bSespie } XML_SYNONYM;
1704a1acfa9bSespie 
1705a1acfa9bSespie static XML_SYNONYM **xml_synonyms = NULL;
1706a1acfa9bSespie static int xml_synonyms_count = 0;
1707a1acfa9bSespie 
1708a1acfa9bSespie void
1709a1acfa9bSespie xml_insert_indexterm (char *indexterm, char *index)
1710a1acfa9bSespie {
1711a1acfa9bSespie   /* @index commands can appear between @item and @itemx, @deffn and @deffnx.  */
1712f8dd34f6Sespie   if (!docbook)
1713f8dd34f6Sespie     {
1714a1acfa9bSespie       /* Check to see if we need to do index redirection per @synindex.  */
1715a1acfa9bSespie       int i;
1716a1acfa9bSespie       for (i = 0; i < xml_synonyms_count; i++)
1717a1acfa9bSespie         {
1718a1acfa9bSespie           if (STREQ (xml_synonyms[i]->from, index))
1719a1acfa9bSespie             index = xstrdup (xml_synonyms[i]->to);
1720a1acfa9bSespie         }
1721a1acfa9bSespie 
1722a1acfa9bSespie       xml_dont_touch_items_defs++;
1723f8dd34f6Sespie       xml_insert_element_with_attribute (INDEXTERM, START, "index=\"%s\"", index);
1724a1acfa9bSespie       in_indexterm = 1;
1725f8dd34f6Sespie       execute_string ("%s", indexterm);
1726f8dd34f6Sespie       xml_insert_element (INDEXTERM, END);
1727a1acfa9bSespie       in_indexterm = 0;
1728a1acfa9bSespie       xml_dont_touch_items_defs--;
1729f8dd34f6Sespie     }
1730f8dd34f6Sespie   else
1731f8dd34f6Sespie     {
1732a1acfa9bSespie       char *primary = NULL, *secondary = NULL;
1733a1acfa9bSespie       if (strstr (indexterm+1, INDEX_SEP))
1734f8dd34f6Sespie         {
1735a1acfa9bSespie           primary = xmalloc (strlen (indexterm) + 1);
1736a1acfa9bSespie           strcpy (primary, indexterm);
1737f8dd34f6Sespie           secondary = strstr (primary+1, INDEX_SEP);
1738f8dd34f6Sespie           *secondary = '\0';
1739f8dd34f6Sespie           secondary += strlen (INDEX_SEP);
1740f8dd34f6Sespie         }
1741f8dd34f6Sespie       xml_insert_element_with_attribute (INDEXTERM, START, "role=\"%s\"", index);
1742a1acfa9bSespie       in_indexterm = 1;
1743f8dd34f6Sespie       xml_insert_element (PRIMARY, START);
1744f8dd34f6Sespie       if (primary)
1745a1acfa9bSespie         execute_string ("%s", primary);
1746f8dd34f6Sespie       else
1747a1acfa9bSespie         execute_string ("%s", indexterm);
1748f8dd34f6Sespie       xml_insert_element (PRIMARY, END);
1749f8dd34f6Sespie       if (primary)
1750f8dd34f6Sespie         {
1751f8dd34f6Sespie           xml_insert_element (SECONDARY, START);
1752a1acfa9bSespie           execute_string ("%s", secondary);
1753f8dd34f6Sespie           xml_insert_element (SECONDARY, END);
1754f8dd34f6Sespie         }
1755f8dd34f6Sespie       xml_insert_element (INDEXTERM, END);
1756a1acfa9bSespie       in_indexterm = 0;
1757f8dd34f6Sespie     }
1758f8dd34f6Sespie }
1759f8dd34f6Sespie 
1760f8dd34f6Sespie 
1761f8dd34f6Sespie int xml_last_section_output_position = 0;
1762f8dd34f6Sespie static char last_division_letter = ' ';
1763f8dd34f6Sespie static char index_primary[2000]; /** xx no fixed limit */
1764f8dd34f6Sespie static int indexdivempty = 0;
1765f8dd34f6Sespie 
1766f8dd34f6Sespie static void
1767a1acfa9bSespie xml_close_indexentry (void)
1768f8dd34f6Sespie {
1769f8dd34f6Sespie   if (!in_indexentry)
1770f8dd34f6Sespie     return;
1771f8dd34f6Sespie   if (in_secondary)
1772f8dd34f6Sespie     xml_insert_element (SECONDARYIE, END);
1773f8dd34f6Sespie   xml_insert_element (INDEXENTRY, END);
1774f8dd34f6Sespie   in_secondary = 0;
1775f8dd34f6Sespie   in_indexentry = 0;
1776f8dd34f6Sespie }
1777f8dd34f6Sespie 
1778f8dd34f6Sespie void
1779a1acfa9bSespie xml_begin_index (void)
1780f8dd34f6Sespie {
1781a1acfa9bSespie   typedef struct xml_index_title {
1782a1acfa9bSespie       struct xml_index_title *next;
1783a1acfa9bSespie       char *title;
1784a1acfa9bSespie   } XML_INDEX_TITLE;
1785f8dd34f6Sespie 
1786a1acfa9bSespie   static XML_INDEX_TITLE *xml_index_titles = NULL;
1787a1acfa9bSespie 
1788a1acfa9bSespie   if (!handling_delayed_writes)
1789a1acfa9bSespie     { /* We assume that we just opened a section, and so that the last output is
1790a1acfa9bSespie          <SECTION ID="node-name"><TITLE>Title</TITLE>
1791a1acfa9bSespie          where SECTION can be CHAPTER, ...  */
1792a1acfa9bSespie 
1793a1acfa9bSespie       XML_INDEX_TITLE *new = xmalloc (sizeof (XML_INDEX_TITLE));
1794f8dd34f6Sespie       xml_section *temp = last_section;
1795f8dd34f6Sespie 
1796f8dd34f6Sespie       int l = output_paragraph_offset-xml_last_section_output_position;
1797f8dd34f6Sespie       char *tmp = xmalloc (l+1);
1798f8dd34f6Sespie       char *p = tmp;
1799a1acfa9bSespie       strncpy (tmp, (char *) output_paragraph, l);
1800f8dd34f6Sespie 
1801f8dd34f6Sespie       /* We remove <SECTION */
1802f8dd34f6Sespie       tmp[l] = '\0';
1803f8dd34f6Sespie       while (*p != '<')
1804f8dd34f6Sespie         p++;
1805f8dd34f6Sespie       while (*p != ' ')
1806f8dd34f6Sespie         p++;
1807a1acfa9bSespie       /* ... and its label attribute.  */
1808a1acfa9bSespie       if (strncmp (p, " label=", 7) == 0)
1809a1acfa9bSespie         {
1810a1acfa9bSespie           p++;
1811a1acfa9bSespie           while (*p != ' ')
1812a1acfa9bSespie             p++;
1813a1acfa9bSespie         }
1814f8dd34f6Sespie 
1815f8dd34f6Sespie       output_paragraph_offset = xml_last_section_output_position;
1816f8dd34f6Sespie       xml_last_section_output_position = 0;
1817f8dd34f6Sespie 
1818f8dd34f6Sespie       xml_pop_current_element (); /* remove section element from elements stack */
1819f8dd34f6Sespie 
1820a1acfa9bSespie       if (last_section)
1821f8dd34f6Sespie         last_section = last_section->prev; /* remove section from sections stack */
1822a1acfa9bSespie       if (temp)
1823a1acfa9bSespie         {
1824f8dd34f6Sespie           free (temp->name);
1825f8dd34f6Sespie           free (temp);
1826a1acfa9bSespie         }
1827a1acfa9bSespie 
1828a1acfa9bSespie       new->title = xstrdup (p);
1829a1acfa9bSespie       new->next = xml_index_titles;
1830a1acfa9bSespie       xml_index_titles = new;
1831a1acfa9bSespie     }
1832a1acfa9bSespie   else
1833a1acfa9bSespie     {
1834a1acfa9bSespie       static int xml_index_titles_reversed = 0;
1835a1acfa9bSespie 
1836a1acfa9bSespie       if (!xml_index_titles_reversed)
1837a1acfa9bSespie         {
1838a1acfa9bSespie           xml_index_titles = (XML_INDEX_TITLE *) reverse_list
1839a1acfa9bSespie             ((GENERIC_LIST *) xml_index_titles);
1840a1acfa9bSespie           xml_index_titles_reversed = 1;
1841a1acfa9bSespie         }
1842f8dd34f6Sespie 
1843f8dd34f6Sespie       /* We put <INDEX> */
1844f8dd34f6Sespie       xml_insert_element (PRINTINDEX, START);
1845a1acfa9bSespie       if (xml_index_titles)
1846a1acfa9bSespie         {
1847f8dd34f6Sespie           /* Remove the final > */
18481f65d55cSotto           if (output_paragraph_offset)
1849f8dd34f6Sespie 	    output_paragraph_offset--;
1850f8dd34f6Sespie           /* and put  ID="node-name"><TITLE>Title</TITLE> */
1851a1acfa9bSespie           insert_string (xml_index_titles->title);
1852a1acfa9bSespie           free (xml_index_titles->title);
1853a1acfa9bSespie           xml_index_titles = xml_index_titles->next;
1854a1acfa9bSespie         }
1855f8dd34f6Sespie 
1856f8dd34f6Sespie       if (xml_index_divisions)
1857f8dd34f6Sespie         {
1858f8dd34f6Sespie           xml_insert_element (INDEXDIV, START);
1859f8dd34f6Sespie           indexdivempty = 1;
1860f8dd34f6Sespie         }
1861f8dd34f6Sespie     }
1862a1acfa9bSespie }
1863f8dd34f6Sespie 
1864f8dd34f6Sespie void
1865a1acfa9bSespie xml_end_index (void)
1866f8dd34f6Sespie {
1867f8dd34f6Sespie   xml_close_indexentry ();
1868f8dd34f6Sespie   if (xml_index_divisions)
1869f8dd34f6Sespie     xml_insert_element (INDEXDIV, END);
1870f8dd34f6Sespie   xml_insert_element (PRINTINDEX, END);
1871f8dd34f6Sespie }
1872f8dd34f6Sespie 
1873a1acfa9bSespie static void
1874a1acfa9bSespie xml_index_divide (char *entry)
1875f8dd34f6Sespie {
1876f8dd34f6Sespie   char c;
1877f8dd34f6Sespie   if (strlen (entry) > (strlen (xml_element_list[CODE].name) + 2) &&
1878f8dd34f6Sespie       strncmp (entry+1, xml_element_list[CODE].name, strlen (xml_element_list[CODE].name)) == 0)
1879f8dd34f6Sespie     c = entry[strlen (xml_element_list[CODE].name)+2];
1880f8dd34f6Sespie   else
1881f8dd34f6Sespie     c = entry[0];
1882f8dd34f6Sespie   if (tolower (c) != last_division_letter && isalpha (c))
1883f8dd34f6Sespie     {
1884f8dd34f6Sespie       last_division_letter = tolower (c);
1885f8dd34f6Sespie       xml_close_indexentry ();
1886f8dd34f6Sespie       if (!indexdivempty)
1887f8dd34f6Sespie         {
1888f8dd34f6Sespie           xml_insert_element (INDEXDIV, END);
1889f8dd34f6Sespie           xml_insert_element (INDEXDIV, START);
1890f8dd34f6Sespie         }
1891f8dd34f6Sespie       xml_insert_element (TITLE, START);
1892f8dd34f6Sespie       insert (toupper (c));
1893f8dd34f6Sespie       xml_insert_element (TITLE, END);
1894f8dd34f6Sespie     }
1895f8dd34f6Sespie }
1896f8dd34f6Sespie 
1897f8dd34f6Sespie void
1898a1acfa9bSespie xml_insert_indexentry (char *entry, char *node)
1899f8dd34f6Sespie {
1900f8dd34f6Sespie   char *primary = NULL, *secondary;
1901f8dd34f6Sespie   if (xml_index_divisions)
1902f8dd34f6Sespie     xml_index_divide (entry);
1903f8dd34f6Sespie 
1904f8dd34f6Sespie   indexdivempty = 0;
1905f8dd34f6Sespie   if (strstr (entry+1, INDEX_SEP))
1906f8dd34f6Sespie     {
1907f8dd34f6Sespie       primary = xmalloc (strlen (entry) + 1);
1908f8dd34f6Sespie       strcpy (primary, entry);
1909f8dd34f6Sespie       secondary = strstr (primary+1, INDEX_SEP);
1910f8dd34f6Sespie       *secondary = '\0';
1911f8dd34f6Sespie       secondary += strlen (INDEX_SEP);
1912f8dd34f6Sespie 
1913f8dd34f6Sespie       if (in_secondary && strcmp (primary, index_primary) == 0)
1914f8dd34f6Sespie         {
1915f8dd34f6Sespie           xml_insert_element (SECONDARYIE, END);
1916f8dd34f6Sespie           xml_insert_element (SECONDARYIE, START);
1917a1acfa9bSespie           execute_string ("%s", secondary);
1918f8dd34f6Sespie         }
1919f8dd34f6Sespie       else
1920f8dd34f6Sespie         {
1921f8dd34f6Sespie           xml_close_indexentry ();
1922f8dd34f6Sespie           xml_insert_element (INDEXENTRY, START);
1923f8dd34f6Sespie           in_indexentry = 1;
1924f8dd34f6Sespie           xml_insert_element (PRIMARYIE, START);
1925a1acfa9bSespie           execute_string ("%s", primary);
1926f8dd34f6Sespie           xml_insert_element (PRIMARYIE, END);
1927f8dd34f6Sespie           xml_insert_element (SECONDARYIE, START);
1928a1acfa9bSespie           execute_string ("%s", secondary);
1929f8dd34f6Sespie           in_secondary = 1;
1930f8dd34f6Sespie         }
1931f8dd34f6Sespie     }
1932f8dd34f6Sespie   else
1933f8dd34f6Sespie     {
1934f8dd34f6Sespie       xml_close_indexentry ();
1935f8dd34f6Sespie       xml_insert_element (INDEXENTRY, START);
1936f8dd34f6Sespie       in_indexentry = 1;
1937f8dd34f6Sespie       xml_insert_element (PRIMARYIE, START);
1938a1acfa9bSespie       execute_string ("%s", entry);
1939f8dd34f6Sespie     }
1940a1acfa9bSespie   add_word (", ");
1941a1acfa9bSespie 
1942a1acfa9bSespie   /* Don't link to @unnumbered sections directly.
1943a1acfa9bSespie      We are disabling warnings temporarily, otherwise these xrefs
1944a1acfa9bSespie      will cause bogus warnings about missing punctuation.  */
1945a1acfa9bSespie   {
1946a1acfa9bSespie     extern int print_warnings;
1947a1acfa9bSespie     int save_print_warnings = print_warnings;
1948a1acfa9bSespie     print_warnings = 0;
1949a1acfa9bSespie     execute_string ("%cxref{%s}", COMMAND_PREFIX, xstrdup (node));
1950a1acfa9bSespie     print_warnings = save_print_warnings;
1951a1acfa9bSespie   }
1952f8dd34f6Sespie 
1953f8dd34f6Sespie   if (primary)
1954f8dd34f6Sespie     {
1955f8dd34f6Sespie       strcpy (index_primary, primary);
1956f8dd34f6Sespie       /*      xml_insert_element (SECONDARYIE, END);*/
1957f8dd34f6Sespie       /*     *(secondary-1) = ',';*/ /* necessary ? */
1958f8dd34f6Sespie       free (primary);
1959f8dd34f6Sespie     }
1960f8dd34f6Sespie   else
1961f8dd34f6Sespie     xml_insert_element (PRIMARYIE, END);
1962f8dd34f6Sespie 
1963f8dd34f6Sespie   /*  xml_insert_element (INDEXENTRY, END); */
1964f8dd34f6Sespie }
1965f8dd34f6Sespie 
1966a1acfa9bSespie void
1967a1acfa9bSespie xml_synindex (char *from, char *to)
1968a1acfa9bSespie {
1969a1acfa9bSespie   int i, slot;
1970a1acfa9bSespie 
1971a1acfa9bSespie   slot = -1;
1972a1acfa9bSespie   for (i = 0; i < xml_synonyms_count; i++)
1973a1acfa9bSespie     if (!xml_synonyms[i])
1974a1acfa9bSespie       {
1975a1acfa9bSespie         slot = i;
1976a1acfa9bSespie         break;
1977a1acfa9bSespie       }
1978a1acfa9bSespie 
1979a1acfa9bSespie   if (slot < 0)
1980a1acfa9bSespie     {
1981a1acfa9bSespie       slot = xml_synonyms_count;
1982a1acfa9bSespie       xml_synonyms_count++;
1983a1acfa9bSespie 
1984a1acfa9bSespie       xml_synonyms = (XML_SYNONYM **) xrealloc (xml_synonyms,
1985a1acfa9bSespie           (xml_synonyms_count + 1) * sizeof (XML_SYNONYM *));
1986a1acfa9bSespie     }
1987a1acfa9bSespie 
1988a1acfa9bSespie   xml_synonyms[slot] = xmalloc (sizeof (XML_SYNONYM));
1989a1acfa9bSespie   xml_synonyms[slot]->from = xstrdup (from);
1990a1acfa9bSespie   xml_synonyms[slot]->to = xstrdup (to);
1991a1acfa9bSespie }
1992a1acfa9bSespie 
1993f8dd34f6Sespie /*
1994f8dd34f6Sespie  * MULTITABLE
1995f8dd34f6Sespie  */
1996a1acfa9bSespie 
1997a1acfa9bSespie static int multitable_columns_count;
1998a1acfa9bSespie static int *multitable_column_widths;
1999a1acfa9bSespie 
2000f8dd34f6Sespie void
2001a1acfa9bSespie xml_begin_multitable (int ncolumns, int *column_widths)
2002f8dd34f6Sespie {
2003f8dd34f6Sespie   int i;
2004f8dd34f6Sespie   if (docbook)
2005f8dd34f6Sespie     {
2006a1acfa9bSespie       if (is_in_insertion_of_type (floatenv))
2007a1acfa9bSespie         xml_begin_docbook_float (MULTITABLE);
2008a1acfa9bSespie       else
2009f8dd34f6Sespie         xml_insert_element (MULTITABLE, START);
2010a1acfa9bSespie 
2011a1acfa9bSespie       multitable_columns_count = ncolumns;
2012a1acfa9bSespie       multitable_column_widths = xmalloc (sizeof (int) * ncolumns);
2013a1acfa9bSespie       memcpy (multitable_column_widths, column_widths,
2014a1acfa9bSespie           sizeof (int) * ncolumns);
2015a1acfa9bSespie 
2016f8dd34f6Sespie       xml_no_para = 1;
2017f8dd34f6Sespie     }
2018f8dd34f6Sespie   else
2019f8dd34f6Sespie     {
2020f8dd34f6Sespie       xml_insert_element (MULTITABLE, START);
2021f8dd34f6Sespie       for (i=0; i<ncolumns; i++)
2022f8dd34f6Sespie         {
2023f8dd34f6Sespie           xml_insert_element (COLSPEC, START);
2024f8dd34f6Sespie           add_word_args ("%d", column_widths[i]);
2025f8dd34f6Sespie           xml_insert_element (COLSPEC, END);
2026f8dd34f6Sespie         }
2027f8dd34f6Sespie       xml_no_para = 1;
2028f8dd34f6Sespie     }
2029f8dd34f6Sespie }
2030f8dd34f6Sespie 
2031a1acfa9bSespie static void
2032a1acfa9bSespie xml_begin_multitable_group (void)
2033a1acfa9bSespie {
2034a1acfa9bSespie   int i;
2035a1acfa9bSespie 
2036a1acfa9bSespie   xml_insert_element_with_attribute (TGROUP, START, "cols=\"%d\"",
2037a1acfa9bSespie       multitable_columns_count);
2038a1acfa9bSespie 
2039a1acfa9bSespie   for (i=0; i < multitable_columns_count; i++)
2040a1acfa9bSespie     {
2041a1acfa9bSespie       xml_insert_element_with_attribute (COLSPEC, START,
2042a1acfa9bSespie           "colwidth=\"%d*\"", multitable_column_widths[i]);
2043a1acfa9bSespie       xml_insert_element (COLSPEC, END);
2044a1acfa9bSespie     }
2045a1acfa9bSespie }
2046a1acfa9bSespie 
2047f8dd34f6Sespie void
2048a1acfa9bSespie xml_end_multitable_row (int first_row)
2049f8dd34f6Sespie {
2050f8dd34f6Sespie   if (!first_row)
2051f8dd34f6Sespie     {
2052f8dd34f6Sespie       xml_insert_element (ENTRY, END);
2053f8dd34f6Sespie       xml_insert_element (ROW, END);
2054f8dd34f6Sespie     }
2055a1acfa9bSespie 
2056a1acfa9bSespie   if (headitem_flag)
2057a1acfa9bSespie     {
2058a1acfa9bSespie       if (!first_row)
2059a1acfa9bSespie         {
2060a1acfa9bSespie           if (after_headitem)
2061a1acfa9bSespie             xml_insert_element (THEAD, END);
2062a1acfa9bSespie           else
2063a1acfa9bSespie             xml_insert_element (TBODY, END);
2064a1acfa9bSespie           xml_insert_element (TGROUP, END);
2065a1acfa9bSespie         }
2066a1acfa9bSespie 
2067a1acfa9bSespie       xml_begin_multitable_group ();
2068a1acfa9bSespie       xml_insert_element (THEAD, START);
2069a1acfa9bSespie     }
2070a1acfa9bSespie   else if (first_row)
2071a1acfa9bSespie     {
2072a1acfa9bSespie       xml_begin_multitable_group ();
2073a1acfa9bSespie       xml_insert_element (TBODY, START);
2074a1acfa9bSespie     }
2075a1acfa9bSespie   else if (after_headitem)
2076a1acfa9bSespie     {
2077a1acfa9bSespie       xml_insert_element (THEAD, END);
2078a1acfa9bSespie       xml_insert_element (TBODY, START);
2079a1acfa9bSespie     }
2080a1acfa9bSespie   else if (first_row)
2081a1acfa9bSespie     xml_insert_element (TBODY, START);
2082a1acfa9bSespie 
2083f8dd34f6Sespie   xml_insert_element (ROW, START);
2084f8dd34f6Sespie   xml_insert_element (ENTRY, START);
2085f8dd34f6Sespie }
2086f8dd34f6Sespie 
2087f8dd34f6Sespie void
2088a1acfa9bSespie xml_end_multitable_column (void)
2089f8dd34f6Sespie {
2090f8dd34f6Sespie   xml_insert_element (ENTRY, END);
2091f8dd34f6Sespie   xml_insert_element (ENTRY, START);
2092f8dd34f6Sespie }
2093f8dd34f6Sespie 
2094f8dd34f6Sespie void
2095a1acfa9bSespie xml_end_multitable (void)
2096f8dd34f6Sespie {
2097f8dd34f6Sespie   xml_insert_element (ENTRY, END);
2098f8dd34f6Sespie   xml_insert_element (ROW, END);
2099a1acfa9bSespie 
2100a1acfa9bSespie   if (after_headitem)
2101a1acfa9bSespie     {
2102a1acfa9bSespie       if (docbook)
2103a1acfa9bSespie         warning (_("@headitem as the last item of @multitable produces invalid Docbook documents"));
2104a1acfa9bSespie       xml_insert_element (THEAD, END);
2105a1acfa9bSespie     }
2106a1acfa9bSespie   else
2107f8dd34f6Sespie     xml_insert_element (TBODY, END);
2108a1acfa9bSespie 
2109a1acfa9bSespie   if (docbook)
2110f8dd34f6Sespie     xml_insert_element (TGROUP, END);
2111a1acfa9bSespie 
2112f8dd34f6Sespie   xml_insert_element (MULTITABLE, END);
2113f8dd34f6Sespie   xml_no_para = 0;
2114f8dd34f6Sespie }
2115a1acfa9bSespie 
2116a1acfa9bSespie /*
2117a1acfa9bSespie  * Parameters in @def definitions
2118a1acfa9bSespie  */
2119a1acfa9bSespie 
2120a1acfa9bSespie #define DEFUN_SELF_DELIMITING(c) \
2121a1acfa9bSespie   ((c) == '(' || (c) == ')' || (c) == '[' || (c) == ']')
2122a1acfa9bSespie 
2123a1acfa9bSespie void
2124a1acfa9bSespie xml_process_defun_args (char **defun_args, int auto_var_p)
2125a1acfa9bSespie {
2126a1acfa9bSespie   int pending_space = 0;
2127a1acfa9bSespie   int just_after_paramtype = 0;
2128a1acfa9bSespie 
2129a1acfa9bSespie   for (;;)
2130a1acfa9bSespie     {
2131a1acfa9bSespie       char *defun_arg = *defun_args++;
2132a1acfa9bSespie 
2133a1acfa9bSespie       if (defun_arg == NULL)
2134a1acfa9bSespie         break;
2135a1acfa9bSespie 
2136a1acfa9bSespie       if (defun_arg[0] == ' ')
2137a1acfa9bSespie         {
2138a1acfa9bSespie           pending_space = 1;
2139a1acfa9bSespie           continue;
2140a1acfa9bSespie         }
2141a1acfa9bSespie 
2142a1acfa9bSespie       if (pending_space)
2143a1acfa9bSespie         {
2144a1acfa9bSespie           add_char (' ');
2145a1acfa9bSespie           pending_space = 0;
2146a1acfa9bSespie         }
2147a1acfa9bSespie 
2148a1acfa9bSespie       if (DEFUN_SELF_DELIMITING (defun_arg[0]))
2149a1acfa9bSespie         {
2150a1acfa9bSespie 	  xml_insert_element (DEFDELIMITER, START);
2151a1acfa9bSespie           add_char (defun_arg[0]);
2152a1acfa9bSespie 	  xml_insert_element (DEFDELIMITER, END);
2153a1acfa9bSespie 	  just_after_paramtype = 0;
2154a1acfa9bSespie         }
2155a1acfa9bSespie       else if (defun_arg[0] == '&')
2156a1acfa9bSespie 	{
2157a1acfa9bSespie 	  xml_insert_element (DEFPARAM, START);
2158a1acfa9bSespie 	  add_word (defun_arg);
2159a1acfa9bSespie 	  xml_insert_element (DEFPARAM, END);
2160a1acfa9bSespie 	  just_after_paramtype = 0;
2161a1acfa9bSespie 	}
2162a1acfa9bSespie       else if (defun_arg[0] == COMMAND_PREFIX || just_after_paramtype)
2163a1acfa9bSespie 	{
2164a1acfa9bSespie 	  xml_insert_element (DEFPARAM, START);
2165a1acfa9bSespie 	  execute_string ("%s", defun_arg);
2166a1acfa9bSespie 	  xml_insert_element (DEFPARAM, END);
2167a1acfa9bSespie 	  just_after_paramtype = 0;
2168a1acfa9bSespie 	}
2169a1acfa9bSespie       else if (defun_arg[0] == ',' || defun_arg[0] == ';')
2170a1acfa9bSespie 	{
2171a1acfa9bSespie 	  xml_insert_element (DEFDELIMITER, START);
2172a1acfa9bSespie 	  add_word (defun_arg);
2173a1acfa9bSespie 	  xml_insert_element (DEFDELIMITER, END);
2174a1acfa9bSespie 	  just_after_paramtype = 0;
2175a1acfa9bSespie 	}
2176a1acfa9bSespie       else if (auto_var_p)
2177a1acfa9bSespie 	{
2178a1acfa9bSespie 	  xml_insert_element (DEFPARAM, START);
2179a1acfa9bSespie 	  add_word (defun_arg);
2180a1acfa9bSespie 	  xml_insert_element (DEFPARAM, END);
2181a1acfa9bSespie 	  just_after_paramtype = 0;
2182a1acfa9bSespie 	}
2183f8dd34f6Sespie       else
2184f8dd34f6Sespie 	{
2185a1acfa9bSespie 	  xml_insert_element (DEFPARAMTYPE, START);
2186a1acfa9bSespie 	  add_word (defun_arg);
2187a1acfa9bSespie 	  xml_insert_element (DEFPARAMTYPE, END);
2188a1acfa9bSespie 	  just_after_paramtype = 1;
2189f8dd34f6Sespie 	}
2190f8dd34f6Sespie     }
2191a1acfa9bSespie }
2192a1acfa9bSespie 
2193a1acfa9bSespie void
2194a1acfa9bSespie xml_begin_definition (void)
2195a1acfa9bSespie {
2196a1acfa9bSespie   xml_insert_element (DEFINITION, START);
2197a1acfa9bSespie   xml_definition_level ++;
2198a1acfa9bSespie   xml_in_def_item[xml_definition_level] = 0;
2199a1acfa9bSespie }
2200a1acfa9bSespie 
2201a1acfa9bSespie void
2202a1acfa9bSespie xml_end_definition (void)
2203a1acfa9bSespie {
2204a1acfa9bSespie   if (xml_in_def_item[xml_definition_level])
2205a1acfa9bSespie     {
2206a1acfa9bSespie       xml_insert_element (DEFINITIONITEM, END);
2207a1acfa9bSespie       xml_in_def_item[xml_definition_level] = 0;
2208a1acfa9bSespie     }
2209a1acfa9bSespie   xml_after_def_term = 0;
2210a1acfa9bSespie   xml_insert_element (DEFINITION, END);
2211a1acfa9bSespie   xml_definition_level --;
2212a1acfa9bSespie }
2213a1acfa9bSespie 
2214a1acfa9bSespie void
2215a1acfa9bSespie xml_begin_def_term (int base_type, const char *category,
2216a1acfa9bSespie     char *defined_name, char *type_name, char *type_name2)
2217a1acfa9bSespie {
2218a1acfa9bSespie   xml_after_def_term = 0;
2219a1acfa9bSespie   xml_insert_element (DEFINITIONTERM, START);
2220a1acfa9bSespie 
2221a1acfa9bSespie   /* Index entry */
2222a1acfa9bSespie   switch (base_type)
2223a1acfa9bSespie     {
2224a1acfa9bSespie     case deffn:
2225a1acfa9bSespie     case deftypefn:
2226a1acfa9bSespie       execute_string ("@findex %s\n", defined_name);
2227a1acfa9bSespie       break;
2228a1acfa9bSespie     case defvr:
2229a1acfa9bSespie     case deftypevr:
2230a1acfa9bSespie     case defcv:
2231a1acfa9bSespie       execute_string ("@vindex %s\n", defined_name);
2232a1acfa9bSespie       break;
2233a1acfa9bSespie     case deftypecv:
2234a1acfa9bSespie     case deftypeivar:
2235a1acfa9bSespie       execute_string ("@vindex %s %s %s\n", defined_name, _("of"), type_name);
2236a1acfa9bSespie       break;
2237a1acfa9bSespie     case deftypemethod:
2238a1acfa9bSespie     case defop:
2239a1acfa9bSespie     case deftypeop:
2240a1acfa9bSespie       execute_string ("@findex %s %s %s\n", defined_name, _("on"), type_name);
2241a1acfa9bSespie       break;
2242a1acfa9bSespie     case deftp:
2243a1acfa9bSespie       execute_string ("@tindex %s\n", defined_name);
2244a1acfa9bSespie       break;
2245a1acfa9bSespie     }
2246a1acfa9bSespie 
2247a1acfa9bSespie   /* Start with category.  */
2248a1acfa9bSespie   xml_insert_element (DEFCATEGORY, START);
2249a1acfa9bSespie   execute_string (docbook ? "--- %s:" : "%s", category);
2250a1acfa9bSespie   xml_insert_element (DEFCATEGORY, END);
2251a1acfa9bSespie   add_char(' ');
2252a1acfa9bSespie 
2253a1acfa9bSespie   /* Output type name first for typed definitions.  */
2254a1acfa9bSespie   switch (base_type)
2255a1acfa9bSespie     {
2256a1acfa9bSespie     case deffn:
2257a1acfa9bSespie     case defvr:
2258a1acfa9bSespie     case deftp:
2259a1acfa9bSespie       break;
2260a1acfa9bSespie 
2261a1acfa9bSespie     case deftypefn:
2262a1acfa9bSespie     case deftypevr:
2263a1acfa9bSespie       xml_insert_element (DEFTYPE, START);
2264a1acfa9bSespie       execute_string ("%s", type_name);
2265a1acfa9bSespie       xml_insert_element (DEFTYPE, END);
2266a1acfa9bSespie       add_char (' ');
2267a1acfa9bSespie       break;
2268a1acfa9bSespie 
2269a1acfa9bSespie     case deftypecv:
2270a1acfa9bSespie     case deftypeivar:
2271a1acfa9bSespie     case deftypemethod:
2272a1acfa9bSespie     case deftypeop:
2273a1acfa9bSespie       xml_insert_element (DEFTYPE, START);
2274a1acfa9bSespie       execute_string ("%s", type_name2);
2275a1acfa9bSespie       xml_insert_element (DEFTYPE, END);
2276a1acfa9bSespie       add_char (' ');
2277a1acfa9bSespie       break;
2278a1acfa9bSespie 
2279a1acfa9bSespie     default:
2280a1acfa9bSespie       xml_insert_element (DEFCLASS, START);
2281a1acfa9bSespie       execute_string ("%s", type_name);
2282a1acfa9bSespie       xml_insert_element (DEFCLASS, END);
2283a1acfa9bSespie       add_char (' ');
2284a1acfa9bSespie       break;
2285a1acfa9bSespie     }
2286a1acfa9bSespie 
2287a1acfa9bSespie   /* Categorize rest of the definitions.  */
2288a1acfa9bSespie   switch (base_type)
2289a1acfa9bSespie     {
2290a1acfa9bSespie     case deffn:
2291a1acfa9bSespie     case deftypefn:
2292a1acfa9bSespie       xml_insert_element (DEFFUNCTION, START);
2293a1acfa9bSespie       execute_string ("%s", defined_name);
2294a1acfa9bSespie       xml_insert_element (DEFFUNCTION, END);
2295a1acfa9bSespie       break;
2296a1acfa9bSespie 
2297a1acfa9bSespie     case defvr:
2298a1acfa9bSespie     case deftypevr:
2299a1acfa9bSespie       xml_insert_element (DEFVARIABLE, START);
2300a1acfa9bSespie       execute_string ("%s", defined_name);
2301a1acfa9bSespie       xml_insert_element (DEFVARIABLE, END);
2302a1acfa9bSespie       break;
2303a1acfa9bSespie 
2304a1acfa9bSespie     case deftp:
2305a1acfa9bSespie       xml_insert_element (DEFDATATYPE, START);
2306a1acfa9bSespie       execute_string ("%s", defined_name);
2307a1acfa9bSespie       xml_insert_element (DEFDATATYPE, END);
2308a1acfa9bSespie       break;
2309a1acfa9bSespie 
2310a1acfa9bSespie     case defcv:
2311a1acfa9bSespie     case deftypecv:
2312a1acfa9bSespie     case deftypeivar:
2313a1acfa9bSespie       xml_insert_element (DEFCLASSVAR, START);
2314a1acfa9bSespie       execute_string ("%s", defined_name);
2315a1acfa9bSespie       xml_insert_element (DEFCLASSVAR, END);
2316a1acfa9bSespie       break;
2317a1acfa9bSespie 
2318a1acfa9bSespie     case defop:
2319a1acfa9bSespie     case deftypeop:
2320a1acfa9bSespie     case deftypemethod:
2321a1acfa9bSespie       /* Operation / Method */
2322a1acfa9bSespie       xml_insert_element (DEFOPERATION, START);
2323a1acfa9bSespie       execute_string ("%s", defined_name);
2324a1acfa9bSespie       xml_insert_element (DEFOPERATION, END);
2325a1acfa9bSespie       break;
2326a1acfa9bSespie     }
2327a1acfa9bSespie }
2328a1acfa9bSespie 
2329a1acfa9bSespie void
2330a1acfa9bSespie xml_end_def_term (void)
2331a1acfa9bSespie {
2332a1acfa9bSespie   xml_insert_element (DEFINITIONTERM, END);
2333a1acfa9bSespie   xml_after_def_term = 1;
2334a1acfa9bSespie }
2335