1 /* $NetBSD: xml.c,v 1.2 2016/01/14 00:34:53 christos Exp $ */
2
3 /* xml.c -- xml output.
4 Id: xml.c,v 1.52 2004/12/19 17:02:23 karl Exp
5
6 Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22 Originally written by Philippe Martin <feloy@free.fr>. */
23
24 #include "system.h"
25 #include "makeinfo.h"
26 #include "insertion.h"
27 #include "files.h"
28 #include "float.h"
29 #include "macro.h"
30 #include "cmds.h"
31 #include "lang.h"
32
33 #include "xml.h"
34
35 /* Options */
36 int xml_index_divisions = 1;
37
38 typedef struct _element
39 {
40 char name[32];
41 int contains_para;
42 int contained_in_para;
43 int keep_space;
44 } element;
45
46 element texinfoml_element_list [] = {
47 { "texinfo", 1, 0, 0 },
48 { "setfilename", 0, 0, 0 },
49 { "titlefont", 0, 0, 0 },
50 { "settitle", 0, 0, 0 },
51 { "documentdescription", 1, 0, 0 },
52
53 { "node", 1, 0, 0 },
54 { "nodenext", 0, 0, 0 },
55 { "nodeprev", 0, 0, 0 },
56 { "nodeup", 0, 0, 0 },
57
58 { "chapter", 1, 0, 0 },
59 { "section", 1, 0, 0 },
60 { "subsection", 1, 0, 0 },
61 { "subsubsection", 1, 0, 0 },
62
63 { "top", 1, 0, 0 },
64 { "unnumbered", 1, 0, 0 },
65 { "unnumberedsec", 1, 0, 0 },
66 { "unnumberedsubsec", 1, 0, 0 },
67 { "unnumberedsubsubsec", 1, 0, 0 },
68
69 { "appendix", 1, 0, 0 },
70 { "appendixsec", 1, 0, 0 },
71 { "appendixsubsec", 1, 0, 0 },
72 { "appendixsubsubsec", 1, 0, 0 },
73
74 { "majorheading", 0, 0, 0 },
75 { "chapheading", 0, 0, 0 },
76 { "heading", 0, 0, 0 },
77 { "subheading", 0, 0, 0 },
78 { "subsubheading", 0, 0, 0 },
79
80 { "titlepage", 1, 0, 0 },
81 { "author", 0, 0, 0 },
82 { "booktitle", 0, 0, 0 },
83 { "booksubtitle", 0, 0, 0 },
84
85 { "menu", 1, 0, 0 },
86 { "detailmenu", 1, 0, 0 },
87 { "menuentry", 0, 0, 0 },
88 { "menutitle", 0, 0, 0 },
89 { "menucomment", 0, 0, 0 },
90 { "menunode", 0, 0, 0 },
91 { "nodename", 0, 0, 0 },
92
93 { "acronym", 0, 1, 0 },
94 { "acronymword", 0, 1, 0 },
95 { "acronymdesc", 0, 1, 0 },
96
97 { "abbrev", 0, 1, 0 },
98 { "abbrevword", 0, 1, 0 },
99 { "abbrevdesc", 0, 1, 0 },
100
101 { "tt", 0, 1, 0 },
102 { "code", 0, 1, 0 },
103 { "command", 0, 1, 0 },
104 { "env", 0, 1, 0 },
105 { "file", 0, 1, 0 },
106 { "option", 0, 1, 0 },
107 { "samp", 0, 1, 0 },
108 { "kbd", 0, 1, 0 },
109 { "url", 0, 1, 0 },
110 { "key", 0, 1, 0 },
111 { "var", 0, 1, 0 },
112 { "sc", 0, 1, 0 },
113 { "dfn", 0, 1, 0 },
114 { "emph", 0, 1, 0 },
115 { "strong", 0, 1, 0 },
116 { "cite", 0, 1, 0 },
117 { "notfixedwidth", 0, 1, 0 },
118 { "i", 0, 1, 0 },
119 { "b", 0, 1, 0 },
120 { "r", 0, 1, 0 },
121 { "slanted", 0, 1, 0 },
122 { "sansserif", 0, 1, 0 },
123
124 { "exdent", 0, 0, 0 },
125
126 { "title", 0, 0, 0 },
127 { "ifinfo", 1, 0, 0 },
128 { "sp", 0, 0, 0 },
129 { "center", 1, 0, 0 },
130 { "dircategory", 0, 0, 0 },
131 { "quotation", 1, 0, 0 },
132 { "example", 0, 0, 1 },
133 { "smallexample", 0, 0, 1 },
134 { "lisp", 0, 0, 1 },
135 { "smalllisp", 0, 0, 1 },
136 { "cartouche", 1, 0, 0 },
137 { "copying", 1, 0, 0 },
138 { "format", 0, 0, 1 },
139 { "smallformat", 0, 0, 1 },
140 { "display", 0, 0, 1 },
141 { "smalldisplay", 0, 0, 1 },
142 { "verbatim", 0, 0, 1 },
143 { "footnote", 0, 1, 0 },
144 { "", 0, 1, 0 }, /* LINEANNOTATION (docbook) */
145
146 { "", 1, 0, 0 }, /* TIP (docbook) */
147 { "", 1, 0, 0 }, /* NOTE (docbook) */
148 { "", 1, 0, 0 }, /* IMPORTANT (docbook) */
149 { "", 1, 0, 0 }, /* WARNING (docbook) */
150 { "", 1, 0, 0 }, /* CAUTION (docbook) */
151
152 { "itemize", 0, 0, 0 },
153 { "itemfunction", 0, 0, 0 },
154 { "item", 1, 0, 0 },
155 { "enumerate", 0, 0, 0 },
156 { "table", 0, 0, 0 },
157 { "tableitem", 0, 0, 0 },
158 { "tableterm", 0, 0, 0 },
159
160 { "indexterm", 0, 1, 0 },
161
162 { "math", 0, 1, 0 },
163
164 { "dmn", 0, 1, 0 },
165
166 { "xref", 0, 1, 0 },
167 { "xrefnodename", 0, 1, 0 },
168 { "xrefinfoname", 0, 1, 0 },
169 { "xrefprinteddesc", 0, 1, 0 },
170 { "xrefinfofile", 0, 1, 0 },
171 { "xrefprintedname", 0, 1, 0 },
172
173 { "inforef", 0, 1, 0 },
174 { "inforefnodename", 0, 1, 0 },
175 { "inforefrefname", 0, 1, 0 },
176 { "inforefinfoname", 0, 1, 0 },
177
178 { "uref", 0, 1, 0 },
179 { "urefurl", 0, 1, 0 },
180 { "urefdesc", 0, 1, 0 },
181 { "urefreplacement", 0, 1, 0 },
182
183 { "email", 0, 1, 0 },
184 { "emailaddress", 0, 1, 0 },
185 { "emailname", 0, 1, 0 },
186
187 { "group", 0, 0, 0 },
188 { "float", 1, 0, 0 },
189 { "floattype", 0, 0, 0 },
190 { "floatpos", 0, 0, 0 },
191 { "caption", 0, 0, 0 },
192 { "shortcaption", 0, 0, 0 },
193
194 { "", 0, 0, 0 }, /* TABLE (docbook) */
195 { "", 0, 0, 0 }, /* FIGURE (docbook) */
196 { "", 0, 0, 0 }, /* EXAMPLE (docbook) */
197 { "", 1, 0, 0 }, /* SIDEBAR (docbook) */
198
199 { "printindex", 0, 0, 0 },
200 { "listoffloats", 0, 0, 0 },
201 { "anchor", 0, 1, 0 },
202
203 { "image", 0, 0, 0 },
204 { "inlineimage", 0, 1, 0 },
205 { "alttext", 0, 1, 0 },
206
207 { "", 0, 1, 0 }, /* PRIMARY (docbook) */
208 { "", 0, 1, 0 }, /* SECONDARY (docbook) */
209 { "", 0, 0, 0 }, /* INFORMALFIGURE (docbook) */
210 { "", 0, 0, 0 }, /* MEDIAOBJECT (docbook) */
211 { "", 0, 0, 0 }, /* IMAGEOBJECT (docbook) */
212 { "", 0, 0, 0 }, /* IMAGEDATA (docbook) */
213 { "", 0, 0, 0 }, /* TEXTOBJECT (docbook) */
214 { "", 0, 0, 0 }, /* INDEXENTRY (docbook) */
215 { "", 0, 0, 0 }, /* PRIMARYIE (docbook) */
216 { "", 0, 0, 0 }, /* SECONDARYIE (docbook) */
217 { "", 0, 0, 0 }, /* INDEXDIV (docbook) */
218 { "multitable", 0, 0, 0 },
219 { "", 0, 0, 0 }, /* TGROUP (docbook) */
220 { "columnfraction", 0, 0, 0 },
221 { "thead", 0, 0, 0 },
222 { "tbody", 0, 0, 0 },
223 { "entry", 0, 0, 0 },
224 { "row", 0, 0, 0 },
225 { "", 0, 0, 0 }, /* BOOKINFO (docbook) */
226 { "", 0, 0, 0 }, /* ABSTRACT (docbook) */
227 { "", 0, 0, 0 }, /* REPLACEABLE (docbook) */
228 { "", 0, 0, 0 }, /* ENVAR (docbook) */
229 { "", 0, 0, 0 }, /* COMMENT (docbook) */
230 { "", 0, 0, 0 }, /* FUNCTION (docbook) */
231 { "", 0, 0, 0 }, /* LEGALNOTICE (docbook) */
232
233 { "contents", 0, 0, 0 },
234 { "shortcontents", 0, 0, 0 },
235 { "documentlanguage", 0, 0, 0 },
236
237 { "setvalue", 0, 0, 0 },
238 { "clearvalue", 0, 0, 0 },
239
240 { "definition", 0, 0, 0 },
241 { "definitionterm", 0, 0, 0 },
242 { "definitionitem", 1, 0, 0 },
243 { "defcategory", 0, 0, 0 },
244 { "deffunction", 0, 0, 0 },
245 { "defvariable", 0, 0, 0 },
246 { "defparam", 0, 0, 0 },
247 { "defdelimiter", 0, 0, 0 },
248 { "deftype", 0, 0, 0 },
249 { "defparamtype", 0, 0, 0 },
250 { "defdatatype", 0, 0, 0 },
251 { "defclass", 0, 0, 0 },
252 { "defclassvar", 0, 0, 0 },
253 { "defoperation", 0, 0, 0 },
254
255 { "para", 0, 0, 0 } /* Must be last */
256 /* name / contains para / contained in para / preserve space */
257 };
258
259 element docbook_element_list [] = {
260 { "book", 0, 0, 0 }, /* TEXINFO */
261 { "", 0, 0, 0 }, /* SETFILENAME */
262 { "", 0, 0, 0 }, /* TITLEINFO */
263 { "title", 0, 0, 0 }, /* SETTITLE */
264 { "", 1, 0, 0 }, /* DOCUMENTDESCRIPTION (?) */
265
266 { "", 1, 0, 0 }, /* NODE */
267 { "", 0, 0, 0 }, /* NODENEXT */
268 { "", 0, 0, 0 }, /* NODEPREV */
269 { "", 0, 0, 0 }, /* NODEUP */
270
271 { "chapter", 1, 0, 0 },
272 { "sect1", 1, 0, 0 }, /* SECTION */
273 { "sect2", 1, 0, 0 }, /* SUBSECTION */
274 { "sect3", 1, 0, 0 }, /* SUBSUBSECTION */
275
276 { "chapter", 1, 0, 0 }, /* TOP */
277 { "chapter", 1, 0, 0 }, /* UNNUMBERED */
278 { "sect1", 1, 0, 0 }, /* UNNUMBEREDSEC */
279 { "sect2", 1, 0, 0 }, /* UNNUMBEREDSUBSEC */
280 { "sect3", 1, 0, 0 }, /* UNNUMBEREDSUBSUBSEC */
281
282 { "appendix", 1, 0, 0 },
283 { "sect1", 1, 0, 0 }, /* APPENDIXSEC */
284 { "sect2", 1, 0, 0 }, /* APPENDIXSUBSEC */
285 { "sect3", 1, 0, 0 }, /* APPENDIXSUBSUBSEC */
286
287 { "bridgehead", 0, 0, 0 }, /* MAJORHEADING */
288 { "bridgehead", 0, 0, 0 }, /* CHAPHEADING */
289 { "bridgehead", 0, 0, 0 }, /* HEADING */
290 { "bridgehead", 0, 0, 0 }, /* SUBHEADING */
291 { "bridgehead", 0, 0, 0 }, /* SUBSUBHEADING */
292
293 { "", 0, 0, 0 }, /* TITLEPAGE */
294 { "", 0, 0, 0 }, /* AUTHOR */
295 { "", 0, 0, 0 }, /* BOOKTITLE */
296 { "", 0, 0, 0 }, /* BOOKSUBTITLE */
297
298 { "", 1, 0, 0 }, /* MENU */
299 { "", 1, 0, 0 }, /* DETAILMENU */
300 { "", 1, 0, 0 }, /* MENUENTRY */
301 { "", 0, 0, 0 }, /* MENUTITLE */
302 { "", 1, 0, 0 }, /* MENUCOMMENT */
303 { "", 0, 0, 0 }, /* MENUNODE */
304 { "anchor", 0, 0, 0 }, /* NODENAME */
305
306 { "acronym", 0, 1, 0 },
307 { "", 0, 1, 0 }, /* ACRONYMWORD */
308 { "", 0, 1, 0 }, /* ACRONYMDESC */
309
310 { "abbrev", 0, 1, 0 },
311 { "", 0, 1, 0 }, /* ABBREVWORD */
312 { "", 0, 1, 0 }, /* ABBREVDESC */
313
314 { "literal", 0, 1, 0 }, /* TT */
315 { "literal", 0, 1, 0 }, /* CODE */
316 { "command", 0, 1, 0 }, /* COMMAND */
317 { "envar", 0, 1, 0 }, /* ENV */
318 { "filename", 0, 1, 0 }, /* FILE */
319 { "option", 0, 1, 0 }, /* OPTION */
320 { "literal", 0, 1, 0 }, /* SAMP */
321 { "userinput", 0, 1, 0 }, /* KBD */
322 { "wordasword", 0, 1, 0 }, /* URL */
323 { "keycap", 0, 1, 0 }, /* KEY */
324 { "replaceable", 0, 1, 0 }, /* VAR */
325 { "", 0, 1, 0 }, /* SC */
326 { "firstterm", 0, 1, 0 }, /* DFN */
327 { "emphasis", 0, 1, 0 }, /* EMPH */
328 { "emphasis", 0, 1, 0 }, /* STRONG */
329 { "citetitle", 0, 1, 0 }, /* CITE */
330 { "", 0, 1, 0 }, /* NOTFIXEDWIDTH */
331 { "wordasword", 0, 1, 0 }, /* I */
332 { "emphasis", 0, 1, 0 }, /* B */
333 { "", 0, 1, 0 }, /* R */
334
335 { "", 0, 0, 0 }, /* EXDENT */
336
337 { "title", 0, 0, 0 },
338 { "", 1, 0, 0 }, /* IFINFO */
339 { "", 0, 0, 0 }, /* SP */
340 { "", 1, 0, 0 }, /* CENTER */
341 { "", 0, 0, 0 }, /* DIRCATEGORY */
342 { "blockquote", 1, 0, 0 }, /* QUOTATION */
343 { "screen", 0, 0, 1 }, /* EXAMPLE */
344 { "screen", 0, 0, 1 }, /* SMALLEXAMPLE */
345 { "programlisting", 0, 0, 1 }, /* LISP */
346 { "programlisting", 0, 0, 1 }, /* SMALLLISP */
347 { "", 1, 0, 0 }, /* CARTOUCHE */
348 { "", 1, 0, 0 }, /* COPYING */
349 { "screen", 0, 1, 1 }, /* FORMAT */
350 { "screen", 0, 1, 1 }, /* SMALLFORMAT */
351 { "literallayout", 0, 1, 1 }, /* DISPLAY */
352 { "literallayout", 0, 1, 1 }, /* SMALLDISPLAY */
353 { "screen", 0, 0, 1 }, /* VERBATIM */
354 { "footnote", 0, 1, 0 },
355 { "lineannotation", 0, 1, 0 },
356
357 { "tip", 1, 0, 0 },
358 { "note", 1, 0, 0 },
359 { "important", 1, 0, 0 },
360 { "warning", 1, 0, 0 },
361 { "caution", 1, 0, 0 },
362
363 { "itemizedlist", 0, 0, 0 }, /* ITEMIZE */
364 { "", 0, 0, 0 }, /* ITEMFUNCTION */
365 { "listitem", 1, 0, 0 }, /* ITEM */
366 { "orderedlist", 0, 0, 0 }, /* ENUMERATE */
367 { "variablelist", 0, 0, 0 }, /* TABLE */
368 { "varlistentry", 0, 0, 0 }, /* TABLEITEM */
369 { "term", 0, 0, 0 }, /* TABLETERM */
370
371 { "indexterm", 0, 1, 0 }, /* INDEXTERM */
372
373 { "", 0, 1, 0 }, /* MATH */
374
375 { "", 0, 1, 0 }, /* DIMENSION */
376
377 { "xref", 0, 1, 0 }, /* XREF */
378 { "link", 0, 1, 0 }, /* XREFNODENAME */
379 { "", 0, 1, 0 }, /* XREFINFONAME */
380 { "", 0, 1, 0 }, /* XREFPRINTEDDESC */
381 { "", 0, 1, 0 }, /* XREFINFOFILE */
382 { "", 0, 1, 0 }, /* XREFPRINTEDNAME */
383
384 { "", 0, 1, 0 }, /* INFOREF */
385 { "", 0, 1, 0 }, /* INFOREFNODENAME */
386 { "", 0, 1, 0 }, /* INFOREFREFNAME */
387 { "", 0, 1, 0 }, /* INFOREFINFONAME */
388
389 { "ulink", 0, 1, 0 }, /* UREF */
390 { "", 0, 1, 0 }, /* UREFURL */
391 { "", 0, 1, 0 }, /* UREFDESC */
392 { "", 0, 1, 0 }, /* UREFREPLACEMENT */
393
394 { "ulink", 0, 1, 0 }, /* EMAIL */
395 { "", 0, 1, 0 }, /* EMAILADDRESS */
396 { "", 0, 1, 0 }, /* EMAILNAME */
397
398 { "", 0, 0, 0 }, /* GROUP */
399 { "", 1, 0, 0 }, /* FLOAT */
400 { "", 0, 0, 0 }, /* FLOATTYPE */
401 { "", 0, 0, 0 }, /* FLOATPOS */
402 { "", 0, 0, 0 }, /* CAPTION */
403 { "", 0, 0, 0 }, /* SHORTCAPTION */
404
405 { "table", 0, 1, 0 },
406 { "figure", 0, 1, 0 },
407 { "example", 1, 1, 0 },
408 { "sidebar", 1, 0, 0 },
409
410 { "index", 0, 1, 0 }, /* PRINTINDEX */
411 { "", 0, 1, 0 }, /* LISTOFFLOATS */
412 { "", 0, 1, 0 }, /* ANCHOR */
413
414 { "", 0, 0, 0 }, /* IMAGE */
415 { "inlinemediaobject", 0, 1, 0 }, /* INLINEIMAGE */
416 { "", 0, 0, 0 }, /* IMAGEALTTEXT */
417
418 { "primary", 0, 1, 0 }, /* PRIMARY */
419 { "secondary", 0, 1, 0 },
420 { "informalfigure", 0, 0, 0 },
421 { "mediaobject", 0, 0, 0 },
422 { "imageobject", 0, 1, 0 },
423 { "imagedata", 0, 1, 0 },
424 { "textobject", 0, 1, 0 },
425 { "indexentry", 0, 0, 0 },
426 { "primaryie", 0, 0, 0 },
427 { "secondaryie", 0, 0, 0 },
428 { "indexdiv", 0, 0, 0 },
429 { "informaltable", 0, 0, 0 },
430 { "tgroup", 0, 0, 0 },
431 { "colspec", 0, 0, 0 },
432 { "thead", 0, 0, 0 },
433 { "tbody", 0, 0, 0 },
434 { "entry", 0, 0, 0 },
435 { "row", 0, 0, 0 },
436 { "bookinfo", 0, 0, 0 },
437 { "abstract", 1, 0, 0 },
438 { "replaceable", 0, 0, 0 },
439 { "envar", 0, 1, 0 },
440 { "comment", 0, 0, 0 },
441 { "function", 0, 1, 0 },
442 { "legalnotice", 1, 0, 0 },
443
444 { "", 0, 0, 0 }, /* CONTENTS (xml) */
445 { "", 0, 0, 0 }, /* SHORTCONTENTS (xml) */
446 { "", 0, 0, 0 }, /* DOCUMENT LANGUAGE (xml) */
447
448 { "", 0, 0, 0 }, /* SETVALUE (xml) */
449 { "", 0, 0, 0 }, /* CLEARVALUE (xml) */
450
451 { "blockquote", 1, 0, 0 }, /* DEFINITION */
452 { "screen", 0, 0, 1 }, /* DEFINITIONTERM */
453 { "", 0, 0, 0 }, /* DEFINITIONITEM (xml) */
454 { "", 0, 0, 0 }, /* DEFCATEGORY (xml) */
455 { "function", 0, 0, 0 }, /* DEFFUNCTION */
456 { "varname", 0, 0, 0 }, /* DEFVARIABLE */
457 { "varname", 0, 0, 0 }, /* DEFPARAM */
458 { "", 0, 0, 0 }, /* DEFDELIMITER (xml) */
459 { "returnvalue", 0, 0, 0 }, /* DEFTYPE */
460 { "type", 0, 0, 0 }, /* DEFPARAMTYPE */
461 { "structname", 0, 0, 0 }, /* DEFDATATYPE */
462 { "classname", 0, 0, 0 }, /* DEFCLASS */
463 { "property", 0, 0, 0 }, /* DEFCLASSVAR */
464 { "methodname", 0, 0, 0 }, /* DEFOPERATION */
465
466 { "para", 0, 0, 0 } /* Must be last */
467 /* name / contains para / contained in para / preserve space */
468 };
469
470 element *xml_element_list = NULL;
471
472
473 typedef struct _replace_element
474 {
475 int element_to_replace;
476 int element_containing;
477 int element_replacing;
478 } replace_element;
479
480 /* Elements to replace - Docbook only
481 -------------------
482 if `element_to_replace' have to be inserted
483 as a child of `element_containing,'
484 use `element_replacing' instead.
485
486 A value of `-1' for element_replacing means `do not use any element.'
487 */
488
489 replace_element replace_elements [] = {
490 { I, TABLETERM, EMPH },
491 { B, TABLETERM, EMPH },
492 { TT, CODE, -1 },
493 { EXAMPLE, DISPLAY, -1 },
494 { CODE, DFN, -1 },
495 { CODE, VAR, -1 },
496 { EMPH, CODE, REPLACEABLE },
497 { VAR, VAR, -1},
498 { VAR, B, EMPH},
499 { B, CODE, ENVAR},
500 { CODE, I, EMPH},
501 { SAMP, VAR, -1 },
502 { FORMAT, BOOKINFO, ABSTRACT },
503 { QUOTATION, ABSTRACT, -1},
504 { LINEANNOTATION, LINEANNOTATION, -1 },
505 { LEGALNOTICE, ABSTRACT, -1 },
506 { QUOTATION, QUOTATION, -1 },
507 /* Formal versions of table and image elements. */
508 { MULTITABLE, FLOAT, FLOATTABLE },
509 { INFORMALFIGURE, FLOAT, FLOATFIGURE },
510 { CARTOUCHE, FLOAT, FLOATCARTOUCHE },
511 /* Unnecessary markup in @defun blocks. */
512 { VAR, DEFPARAM, -1 },
513 { CODE, DEFTYPE, -1 },
514 /* Add your elements to replace here */
515 {-1, 0, 0}
516 };
517
518 int xml_in_menu_entry = 0;
519 int xml_in_menu_entry_comment = 0;
520 int xml_node_open = 0;
521 int xml_node_level = -1;
522 int xml_in_para = 0;
523 int xml_just_after_element = 0;
524 int xml_keep_space = 0;
525
526 int xml_no_indent = 0;
527
528 int xml_no_para = 0;
529 char *xml_node_id = NULL;
530 int xml_sort_index = 0;
531
532 int xml_in_xref_token = 0;
533 int xml_in_bookinfo = 0;
534 int xml_in_book_title = 0;
535 int xml_in_abstract = 0;
536
537 /* Non-zero if we are handling an element that can appear between
538 @item and @itemx, @deffn and @deffnx. */
539 int xml_dont_touch_items_defs = 0;
540
541 /* We need to keep footnote state, because elements inside footnote may try
542 to close the previous parent para. */
543 static int xml_in_footnote = 0;
544
545 static int xml_after_table_term = 0;
546 static int book_started = 0;
547 static int first_section_opened = 0;
548
549 static int xml_in_tableitem[256];
550 static int xml_in_item[256];
551 static int xml_table_level = 0;
552
553 static int xml_in_def_item[256];
554 static int xml_definition_level = 0;
555 int xml_after_def_term = 0;
556
557 static int in_table_title = 0;
558
559 static int in_indexentry = 0;
560 static int in_secondary = 0;
561 static int in_indexterm = 0;
562
563 char *
xml_id(char * id)564 xml_id (char *id)
565 {
566 char *tem = xmalloc (strlen (id) + 1);
567 char *p = tem;
568 strcpy (tem, id);
569 while (*p)
570 { /* Check if a character is allowed in ID attributes. This list differs
571 slightly from XML specs that it doesn't contain underscores.
572 See http://xml.coverpages.org/sgmlsyn/sgmlsyn.htm, ``9.3 Name'' */
573 if (!strchr ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.", *p))
574 *p = '-';
575 p++;
576 }
577 p = tem;
578 /* First character can only be a letter. */
579 if (!strchr ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", *p))
580 *p = 'i';
581 return tem;
582 }
583
584 int
xml_element(char * name)585 xml_element (char *name)
586 {
587 int i;
588 for (i=0; i<=PARA; i++)
589 {
590 if (strcasecmp (name, texinfoml_element_list[i].name) == 0)
591 return i;
592 }
593 printf ("Error xml_element\n");
594 return -1;
595 }
596
597 void
xml_begin_document(char * output_filename)598 xml_begin_document (char *output_filename)
599 {
600 if (book_started)
601 return;
602
603 book_started = 1;
604
605 /* Make sure this is the very first string of the output document. */
606 output_paragraph_offset = 0;
607
608 insert_string ("<?xml version=\"1.0\"");
609
610 /* At this point, we register a delayed writing for document encoding,
611 so in the end, proper encoding attribute will be inserted here.
612 Since the user is unaware that we are implicitly executing this
613 command, we should disable warnings temporarily, in order to avoid
614 possible confusion. (ie. if the output is not seekable,
615 register_delayed_write issues a warning.) */
616 {
617 extern int print_warnings;
618 int save_print_warnings = print_warnings;
619 print_warnings = 0;
620 register_delayed_write ("@documentencoding");
621 print_warnings = save_print_warnings;
622 }
623
624 insert_string ("?>\n");
625
626 if (docbook)
627 {
628 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]>");
629 xml_element_list = docbook_element_list;
630 }
631 else
632 {
633 insert_string ("<!DOCTYPE texinfo PUBLIC \"-//GNU//DTD TexinfoML V");
634 insert_string (VERSION);
635 insert_string ("//EN\" \"http://www.gnu.org/software/texinfo/dtd/");
636 insert_string (VERSION);
637 insert_string ("/texinfo.dtd\">");
638 xml_element_list = texinfoml_element_list;
639 }
640 if (language_code != last_language_code)
641 {
642 if (docbook)
643 xml_insert_element_with_attribute (TEXINFO, START, "lang=\"%s\"", language_table[language_code].abbrev);
644 else
645 xml_insert_element_with_attribute (TEXINFO, START, "xml:lang=\"%s\"", language_table[language_code].abbrev);
646 }
647 if (!docbook)
648 {
649 xml_insert_element (SETFILENAME, START);
650 insert_string (output_filename);
651 xml_insert_element (SETFILENAME, END);
652 }
653 }
654
655 /* */
656 static int element_stack[256];
657 static int element_stack_index = 0;
658
659 static int
xml_current_element(void)660 xml_current_element (void)
661 {
662 return element_stack[element_stack_index-1];
663 }
664
665 static void
xml_push_current_element(int elt)666 xml_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
675 static void
xml_pop_current_element(void)676 xml_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
685 int
xml_current_stack_index(void)686 xml_current_stack_index (void)
687 {
688 return element_stack_index;
689 }
690
691 void
xml_end_current_element(void)692 xml_end_current_element (void)
693 {
694 xml_insert_element (xml_current_element (), END);
695 }
696
697 static void
xml_indent(void)698 xml_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
710 void
xml_start_para(void)711 xml_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
729 void
xml_end_para(void)730 xml_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
744 void
xml_end_document(void)745 xml_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\
763 Local variables:\n\
764 mode: sgml\n\
765 sgml-indent-step:1\n\
766 sgml-indent-data:nil\n\
767 End:\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 */
774 static 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. */
780 void
781 #if defined (VA_FPRINTF) && __STDC__
xml_insert_element_with_attribute(int elt,int arg,char * format,...)782 xml_insert_element_with_attribute (int elt, int arg, char *format, ...)
783 #else
784 xml_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 (!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. */
989 void
xml_insert_element(int elt,int arg)990 xml_insert_element (int elt, int arg)
991 {
992 xml_insert_element_with_attribute (elt, arg, NULL);
993 }
994
995 void
xml_insert_entity(char * entity_name)996 xml_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
1017 typedef struct _xml_section xml_section;
1018 struct _xml_section {
1019 int level;
1020 char *name;
1021 xml_section *prev;
1022 };
1023
1024 xml_section *last_section = NULL;
1025
1026 void
xml_begin_node(void)1027 xml_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
1053 void
xml_close_sections(int level)1054 xml_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
1082 void
xml_open_section(int level,char * name)1083 xml_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
1097 void
xml_start_menu_entry(char * tem)1098 xml_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
1148 void
xml_end_menu(void)1149 xml_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
1164 static int xml_last_character;
1165
1166 void
xml_add_char(int character)1167 xml_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 ("&");
1252 else if (character == '<' && escape_html)
1253 insert_string ("<");
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
1267 void
xml_insert_footnote(char * note)1268 xml_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. */
1285 typedef struct quotation_elt
1286 {
1287 struct quotation_elt *next;
1288 char *type;
1289 } QUOTATION_ELT;
1290
1291 static QUOTATION_ELT *quotation_stack = NULL;
1292
1293 void
xml_insert_quotation(char * type,int arg)1294 xml_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. */
1349 void
xml_begin_docbook_float(int elt)1350 xml_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 */
1385 void
xml_begin_table(int type,char * item_function)1386 xml_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
1430 void
xml_end_table(int type)1431 xml_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
1471 void
xml_begin_item(void)1472 xml_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
1481 void
xml_begin_table_item(void)1482 xml_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
1504 void
xml_continue_table_item(void)1505 xml_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
1512 void
xml_begin_enumerate(char * enum_arg)1513 xml_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
1557 void
xml_end_enumerate(void)1558 xml_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
1569 static void
xml_insert_text_file(char * name_arg)1570 xml_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
1616 static int
try_docbook_image(const char * name,const char * ext,const char * fmt,int force)1617 try_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
1639 void
xml_insert_docbook_image(char * name_arg)1640 xml_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
1683 void
xml_asterisk(void)1684 xml_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
1696 typedef struct
1697 {
1698 char *from;
1699 char *to;
1700 } XML_SYNONYM;
1701
1702 static XML_SYNONYM **xml_synonyms = NULL;
1703 static int xml_synonyms_count = 0;
1704
1705 void
xml_insert_indexterm(char * indexterm,char * index)1706 xml_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
1758 int xml_last_section_output_position = 0;
1759 static char last_division_letter = ' ';
1760 static char index_primary[2000]; /** xx no fixed limit */
1761 static int indexdivempty = 0;
1762
1763 static void
xml_close_indexentry(void)1764 xml_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
1775 void
xml_begin_index(void)1776 xml_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
1860 void
xml_end_index(void)1861 xml_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
1869 static void
xml_index_divide(char * entry)1870 xml_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
1893 void
xml_insert_indexentry(char * entry,char * node)1894 xml_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
1962 void
xml_synindex(char * from,char * to)1963 xml_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
1993 static int multitable_columns_count;
1994 static int *multitable_column_widths;
1995
1996 void
xml_begin_multitable(int ncolumns,int * column_widths)1997 xml_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
2027 static void
xml_begin_multitable_group(void)2028 xml_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
2043 void
xml_end_multitable_row(int first_row)2044 xml_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
2083 void
xml_end_multitable_column(void)2084 xml_end_multitable_column (void)
2085 {
2086 xml_insert_element (ENTRY, END);
2087 xml_insert_element (ENTRY, START);
2088 }
2089
2090 void
xml_end_multitable(void)2091 xml_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
2119 void
xml_process_defun_args(char ** defun_args,int auto_var_p)2120 xml_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
2189 void
xml_begin_definition(void)2190 xml_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
2197 void
xml_end_definition(void)2198 xml_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
2210 void
xml_begin_def_term(int base_type,const char * category,char * defined_name,char * type_name,char * type_name2)2211 xml_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
2325 void
xml_end_def_term(void)2326 xml_end_def_term (void)
2327 {
2328 xml_insert_element (DEFINITIONTERM, END);
2329 xml_after_def_term = 1;
2330 }
2331