source: trunk/essentials/sys-apps/texinfo/makeinfo/xml.c

Last change on this file was 2617, checked in by bird, 19 years ago

GNU Texinfo 4.8

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