1 /* xml.c -- xml output.
2 $Id: xml.c,v 1.52 2004/12/19 17:02:23 karl Exp $
4 Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
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)
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.
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.
20 Originally written by Philippe Martin <feloy@free.fr>. */
24 #include "insertion.h"
34 int xml_index_divisions
= 1;
36 typedef struct _element
40 int contained_in_para
;
44 element 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 },
52 { "nodenext", 0, 0, 0 },
53 { "nodeprev", 0, 0, 0 },
54 { "nodeup", 0, 0, 0 },
56 { "chapter", 1, 0, 0 },
57 { "section", 1, 0, 0 },
58 { "subsection", 1, 0, 0 },
59 { "subsubsection", 1, 0, 0 },
62 { "unnumbered", 1, 0, 0 },
63 { "unnumberedsec", 1, 0, 0 },
64 { "unnumberedsubsec", 1, 0, 0 },
65 { "unnumberedsubsubsec", 1, 0, 0 },
67 { "appendix", 1, 0, 0 },
68 { "appendixsec", 1, 0, 0 },
69 { "appendixsubsec", 1, 0, 0 },
70 { "appendixsubsubsec", 1, 0, 0 },
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 },
78 { "titlepage", 1, 0, 0 },
79 { "author", 0, 0, 0 },
80 { "booktitle", 0, 0, 0 },
81 { "booksubtitle", 0, 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 },
91 { "acronym", 0, 1, 0 },
92 { "acronymword", 0, 1, 0 },
93 { "acronymdesc", 0, 1, 0 },
95 { "abbrev", 0, 1, 0 },
96 { "abbrevword", 0, 1, 0 },
97 { "abbrevdesc", 0, 1, 0 },
101 { "command", 0, 1, 0 },
104 { "option", 0, 1, 0 },
113 { "strong", 0, 1, 0 },
115 { "notfixedwidth", 0, 1, 0 },
119 { "slanted", 0, 1, 0 },
120 { "sansserif", 0, 1, 0 },
122 { "exdent", 0, 0, 0 },
124 { "title", 0, 0, 0 },
125 { "ifinfo", 1, 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 },
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) */
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) */
150 { "itemize", 0, 0, 0 },
151 { "itemfunction", 0, 0, 0 },
153 { "enumerate", 0, 0, 0 },
154 { "table", 0, 0, 0 },
155 { "tableitem", 0, 0, 0 },
156 { "tableterm", 0, 0, 0 },
158 { "indexterm", 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 },
171 { "inforef", 0, 1, 0 },
172 { "inforefnodename", 0, 1, 0 },
173 { "inforefrefname", 0, 1, 0 },
174 { "inforefinfoname", 0, 1, 0 },
177 { "urefurl", 0, 1, 0 },
178 { "urefdesc", 0, 1, 0 },
179 { "urefreplacement", 0, 1, 0 },
181 { "email", 0, 1, 0 },
182 { "emailaddress", 0, 1, 0 },
183 { "emailname", 0, 1, 0 },
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 },
192 { "", 0, 0, 0 }, /* TABLE (docbook) */
193 { "", 0, 0, 0 }, /* FIGURE (docbook) */
194 { "", 0, 0, 0 }, /* EXAMPLE (docbook) */
195 { "", 1, 0, 0 }, /* SIDEBAR (docbook) */
197 { "printindex", 0, 0, 0 },
198 { "listoffloats", 0, 0, 0 },
199 { "anchor", 0, 1, 0 },
201 { "image", 0, 0, 0 },
202 { "inlineimage", 0, 1, 0 },
203 { "alttext", 0, 1, 0 },
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 },
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) */
231 { "contents", 0, 0, 0 },
232 { "shortcontents", 0, 0, 0 },
233 { "documentlanguage", 0, 0, 0 },
235 { "setvalue", 0, 0, 0 },
236 { "clearvalue", 0, 0, 0 },
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 },
253 { "para", 0, 0, 0 } /* Must be last */
254 /* name / contains para / contained in para / preserve space */
257 element 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 (?) */
264 { "", 1, 0, 0 }, /* NODE */
265 { "", 0, 0, 0 }, /* NODENEXT */
266 { "", 0, 0, 0 }, /* NODEPREV */
267 { "", 0, 0, 0 }, /* NODEUP */
269 { "chapter", 1, 0, 0 },
270 { "sect1", 1, 0, 0 }, /* SECTION */
271 { "sect2", 1, 0, 0 }, /* SUBSECTION */
272 { "sect3", 1, 0, 0 }, /* SUBSUBSECTION */
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 */
280 { "appendix", 1, 0, 0 },
281 { "sect1", 1, 0, 0 }, /* APPENDIXSEC */
282 { "sect2", 1, 0, 0 }, /* APPENDIXSUBSEC */
283 { "sect3", 1, 0, 0 }, /* APPENDIXSUBSUBSEC */
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 */
291 { "", 0, 0, 0 }, /* TITLEPAGE */
292 { "", 0, 0, 0 }, /* AUTHOR */
293 { "", 0, 0, 0 }, /* BOOKTITLE */
294 { "", 0, 0, 0 }, /* BOOKSUBTITLE */
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 */
304 { "acronym", 0, 1, 0 },
305 { "", 0, 1, 0 }, /* ACRONYMWORD */
306 { "", 0, 1, 0 }, /* ACRONYMDESC */
308 { "abbrev", 0, 1, 0 },
309 { "", 0, 1, 0 }, /* ABBREVWORD */
310 { "", 0, 1, 0 }, /* ABBREVDESC */
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 */
333 { "", 0, 0, 0 }, /* EXDENT */
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 },
357 { "important", 1, 0, 0 },
358 { "warning", 1, 0, 0 },
359 { "caution", 1, 0, 0 },
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 */
369 { "indexterm", 0, 1, 0 }, /* INDEXTERM */
371 { "", 0, 1, 0 }, /* MATH */
373 { "", 0, 1, 0 }, /* DIMENSION */
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 */
382 { "", 0, 1, 0 }, /* INFOREF */
383 { "", 0, 1, 0 }, /* INFOREFNODENAME */
384 { "", 0, 1, 0 }, /* INFOREFREFNAME */
385 { "", 0, 1, 0 }, /* INFOREFINFONAME */
387 { "ulink", 0, 1, 0 }, /* UREF */
388 { "", 0, 1, 0 }, /* UREFURL */
389 { "", 0, 1, 0 }, /* UREFDESC */
390 { "", 0, 1, 0 }, /* UREFREPLACEMENT */
392 { "ulink", 0, 1, 0 }, /* EMAIL */
393 { "", 0, 1, 0 }, /* EMAILADDRESS */
394 { "", 0, 1, 0 }, /* EMAILNAME */
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 */
403 { "table", 0, 1, 0 },
404 { "figure", 0, 1, 0 },
405 { "example", 1, 1, 0 },
406 { "sidebar", 1, 0, 0 },
408 { "index", 0, 1, 0 }, /* PRINTINDEX */
409 { "", 0, 1, 0 }, /* LISTOFFLOATS */
410 { "", 0, 1, 0 }, /* ANCHOR */
412 { "", 0, 0, 0 }, /* IMAGE */
413 { "inlinemediaobject", 0, 1, 0 }, /* INLINEIMAGE */
414 { "", 0, 0, 0 }, /* IMAGEALTTEXT */
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 },
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 },
442 { "", 0, 0, 0 }, /* CONTENTS (xml) */
443 { "", 0, 0, 0 }, /* SHORTCONTENTS (xml) */
444 { "", 0, 0, 0 }, /* DOCUMENT LANGUAGE (xml) */
446 { "", 0, 0, 0 }, /* SETVALUE (xml) */
447 { "", 0, 0, 0 }, /* CLEARVALUE (xml) */
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 */
464 { "para", 0, 0, 0 } /* Must be last */
465 /* name / contains para / contained in para / preserve space */
468 element
*xml_element_list
= NULL
;
471 typedef struct _replace_element
473 int element_to_replace
;
474 int element_containing
;
475 int element_replacing
;
478 /* Elements to replace - Docbook only
480 if `element_to_replace' have to be inserted
481 as a child of `element_containing,'
482 use `element_replacing' instead.
484 A value of `-1' for element_replacing means `do not use any element.'
487 replace_element replace_elements
[] = {
488 { I
, TABLETERM
, EMPH
},
489 { B
, TABLETERM
, EMPH
},
491 { EXAMPLE
, DISPLAY
, -1 },
494 { EMPH
, CODE
, REPLACEABLE
},
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 */
516 int xml_in_menu_entry
= 0;
517 int xml_in_menu_entry_comment
= 0;
518 int xml_node_open
= 0;
519 int xml_node_level
= -1;
521 int xml_just_after_element
= 0;
522 int xml_keep_space
= 0;
524 int xml_no_indent
= 0;
527 char *xml_node_id
= NULL
;
528 int xml_sort_index
= 0;
530 int xml_in_xref_token
= 0;
531 int xml_in_bookinfo
= 0;
532 int xml_in_book_title
= 0;
533 int xml_in_abstract
= 0;
535 /* Non-zero if we are handling an element that can appear between
536 @item and @itemx, @deffn and @deffnx. */
537 int xml_dont_touch_items_defs
= 0;
539 /* We need to keep footnote state, because elements inside footnote may try
540 to close the previous parent para. */
541 static int xml_in_footnote
= 0;
543 static int xml_after_table_term
= 0;
544 static int book_started
= 0;
545 static int first_section_opened
= 0;
547 static int xml_in_tableitem
[256];
548 static int xml_in_item
[256];
549 static int xml_table_level
= 0;
551 static int xml_in_def_item
[256];
552 static int xml_definition_level
= 0;
553 int xml_after_def_term
= 0;
555 static int in_table_title
= 0;
557 static int in_indexentry
= 0;
558 static int in_secondary
= 0;
559 static int in_indexterm
= 0;
564 char *tem
= xmalloc (strlen (id
) + 1);
568 { /* Check if a character is allowed in ID attributes. This list differs
569 slightly from XML specs that it doesn't contain underscores.
570 See http://xml.coverpages.org/sgmlsyn/sgmlsyn.htm, ``9.3 Name'' */
571 if (!strchr ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.", *p
))
576 /* First character can only be a letter. */
577 if (!strchr ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", *p
))
583 xml_element (char *name
)
586 for (i
=0; i
<=PARA
; i
++)
588 if (strcasecmp (name
, texinfoml_element_list
[i
].name
) == 0)
591 printf ("Error xml_element\n");
596 xml_begin_document (char *output_filename
)
603 /* Make sure this is the very first string of the output document. */
604 output_paragraph_offset
= 0;
606 insert_string ("<?xml version=\"1.0\"");
608 /* At this point, we register a delayed writing for document encoding,
609 so in the end, proper encoding attribute will be inserted here.
610 Since the user is unaware that we are implicitly executing this
611 command, we should disable warnings temporarily, in order to avoid
612 possible confusion. (ie. if the output is not seekable,
613 register_delayed_write issues a warning.) */
615 extern int print_warnings
;
616 int save_print_warnings
= print_warnings
;
618 register_delayed_write ("@documentencoding");
619 print_warnings
= save_print_warnings
;
622 insert_string ("?>\n");
626 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]>");
627 xml_element_list
= docbook_element_list
;
631 insert_string ("<!DOCTYPE texinfo PUBLIC \"-//GNU//DTD TexinfoML V");
632 insert_string (VERSION
);
633 insert_string ("//EN\" \"http://www.gnu.org/software/texinfo/dtd/");
634 insert_string (VERSION
);
635 insert_string ("/texinfo.dtd\">");
636 xml_element_list
= texinfoml_element_list
;
638 if (language_code
!= last_language_code
)
641 xml_insert_element_with_attribute (TEXINFO
, START
, "lang=\"%s\"", language_table
[language_code
].abbrev
);
643 xml_insert_element_with_attribute (TEXINFO
, START
, "xml:lang=\"%s\"", language_table
[language_code
].abbrev
);
647 xml_insert_element (SETFILENAME
, START
);
648 insert_string (output_filename
);
649 xml_insert_element (SETFILENAME
, END
);
654 static int element_stack
[256];
655 static int element_stack_index
= 0;
658 xml_current_element (void)
660 return element_stack
[element_stack_index
-1];
664 xml_push_current_element (int elt
)
666 element_stack
[element_stack_index
++] = elt
;
667 if (element_stack_index
> 200)
668 printf ("*** stack overflow (%d - %s) ***\n",
670 xml_element_list
[elt
].name
);
674 xml_pop_current_element (void)
676 element_stack_index
--;
677 if (element_stack_index
< 0)
678 printf ("*** stack underflow (%d - %d) ***\n",
680 xml_current_element());
684 xml_current_stack_index (void)
686 return element_stack_index
;
690 xml_end_current_element (void)
692 xml_insert_element (xml_current_element (), END
);
698 if (xml_indentation_increment
> 0)
701 if (output_paragraph
[output_paragraph_offset
-1] != '\n')
703 for (i
= 0; i
< element_stack_index
* xml_indentation_increment
; i
++)
709 xml_start_para (void)
711 if (xml_in_para
|| xml_in_footnote
712 || !xml_element_list
[xml_current_element()].contains_para
)
715 while (output_paragraph
[output_paragraph_offset
-1] == '\n')
716 output_paragraph_offset
--;
719 insert_string ("<para");
721 insert_string (" role=\"continues\"");
730 if (!xml_in_para
|| xml_in_footnote
)
733 while (cr_or_whitespace(output_paragraph
[output_paragraph_offset
-1]))
734 output_paragraph_offset
--;
736 insert_string ("</para>");
737 if (xml_indentation_increment
> 0)
743 xml_end_document (void)
747 if (xml_node_level
!= -1)
749 xml_close_sections (xml_node_level
);
752 xml_insert_element (NODE
, END
);
755 xml_close_sections (xml_node_level
);
757 xml_insert_element (TEXINFO
, END
);
758 if (xml_indentation_increment
== 0)
760 insert_string ("<!-- Keep this comment at the end of the file\n\
763 sgml-indent-step:1\n\
764 sgml-indent-data:nil\n\
767 if (element_stack_index
!= 0)
768 error ("Element stack index : %d\n", element_stack_index
);
771 /* MUST be 0 or 1, not true or false values */
772 static int start_element_inserted
= 1;
774 /* NOTE: We use `elt' rather than `element' in the argument list of
775 the next function, since otherwise the Solaris SUNWspro compiler
776 barfs because `element' is a typedef declared near the beginning of
779 #if defined (VA_FPRINTF) && __STDC__
780 xml_insert_element_with_attribute (int elt
, int arg
, char *format
, ...)
782 xml_insert_element_with_attribute (elt
, arg
, format
, va_alist
)
789 /* Look at the replace_elements table to see if we have to change the element */
794 replace_element
*element_list
= replace_elements
;
795 while (element_list
->element_to_replace
>= 0)
797 if ( ( (arg
== START
) &&
798 (element_list
->element_containing
== xml_current_element ()) &&
799 (element_list
->element_to_replace
== elt
) ) ||
801 (element_list
->element_containing
== element_stack
[element_stack_index
-1-start_element_inserted
]) &&
802 (element_list
->element_to_replace
== elt
) ) )
804 elt
= element_list
->element_replacing
;
810 /* Forget the element */
814 start_element_inserted
= 0;
816 /* Replace the default value, for the next time */
817 start_element_inserted
= 1;
825 if (!xml_dont_touch_items_defs
&& arg
== START
)
827 if (xml_after_table_term
&& elt
!= TABLETERM
&& xml_table_level
828 && !xml_in_item
[xml_table_level
])
830 xml_after_table_term
= 0;
831 xml_insert_element (ITEM
, START
);
832 xml_in_item
[xml_table_level
] = 1;
834 else if (xml_after_def_term
&& elt
!= DEFINITIONTERM
)
836 xml_after_def_term
= 0;
837 xml_insert_element (DEFINITIONITEM
, START
);
838 xml_in_def_item
[xml_definition_level
] = 1;
842 if (docbook
&& !only_macro_expansion
&& (in_menu
|| in_detailmenu
))
845 if (executing_string
&& arg
== END
)
849 xml_in_tableitem
[xml_table_level
] = 0;
852 xml_in_item
[xml_table_level
] = 0;
855 xml_in_def_item
[xml_definition_level
] = 0;
859 /* We are special-casing FIGURE element for docbook. It does appear in
860 the tag stack, but not in the output. This is to make element replacement
862 if (docbook
&& elt
== FLOAT
)
865 xml_push_current_element (elt
);
867 xml_pop_current_element ();
871 if (!xml_element_list
[elt
].name
|| !strlen (xml_element_list
[elt
].name
))
873 /*printf ("Warning: Inserting empty element %d\n", elt);*/
877 if (arg
== START
&& !xml_in_para
&& !xml_no_para
878 && xml_element_list
[elt
].contained_in_para
)
881 if (arg
== START
&& xml_in_para
&& !xml_element_list
[elt
].contained_in_para
)
884 if (arg
== END
&& xml_in_para
&& !xml_element_list
[elt
].contained_in_para
)
887 if (docbook
&& xml_table_level
&& !in_table_title
888 && !xml_in_tableitem
[xml_table_level
] && !xml_in_item
[xml_table_level
]
889 && arg
== START
&& elt
!= TABLEITEM
&& elt
!= TABLETERM
890 && !in_indexterm
&& xml_current_element() == TABLE
)
893 xml_insert_element (TITLE
, START
);
896 if (arg
== START
&& !xml_in_para
&& !xml_keep_space
897 && !xml_element_list
[elt
].contained_in_para
)
901 xml_push_current_element (elt
);
903 xml_pop_current_element ();
905 /* Eat one newline before </example> and the like. */
906 if (!docbook
&& arg
== END
907 && (xml_element_list
[elt
].keep_space
|| elt
== GROUP
)
908 && output_paragraph
[output_paragraph_offset
-1] == '\n')
909 output_paragraph_offset
--;
911 /* And eat whitespace before </entry> in @multitables. */
912 if (arg
== END
&& elt
== ENTRY
)
913 while (cr_or_whitespace(output_paragraph
[output_paragraph_offset
-1]))
914 output_paragraph_offset
--;
916 /* Indent elements that can contain <para>. */
917 if (arg
== END
&& !xml_in_para
&& !xml_keep_space
918 && xml_element_list
[elt
].contains_para
)
921 /* Here are the elements we want indented. These do not contain <para>
923 if (arg
== END
&& (elt
== MENUENTRY
|| elt
== ITEMIZE
|| elt
== ENUMERATE
924 || elt
== TABLEITEM
|| elt
== TABLE
925 || elt
== MULTITABLE
|| elt
== TGROUP
|| elt
== THEAD
|| elt
== TBODY
926 || elt
== ROW
|| elt
== INFORMALFIGURE
927 || (!docbook
&& (elt
== DEFINITION
|| elt
== DEFINITIONTERM
))))
933 insert_string (xml_element_list
[elt
].name
);
935 /* printf ("%s ", xml_element_list[elt].name);*/
939 char temp_string
[2000]; /* xx no fixed limits */
944 VA_START (ap
, format
);
946 VA_SPRINTF (temp_string
, format
, ap
);
948 sprintf (temp_string
, format
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
);
951 insert_string (temp_string
);
955 if (arg
== START
&& xml_node_id
&& elt
!= NODENAME
)
957 insert_string (" id=\"");
958 insert_string (xml_node_id
);
964 if (xml_element_list
[elt
].keep_space
)
969 insert_string (" xml:space=\"preserve\"");
978 if (!xml_in_para
&& !xml_element_list
[elt
].contained_in_para
979 && xml_element_list
[elt
].contains_para
&& xml_indentation_increment
> 0)
982 xml_just_after_element
= 1;
985 /* See the NOTE before xml_insert_element_with_attribute, for why we
986 use `elt' rather than `element' here. */
988 xml_insert_element (int elt
, int arg
)
990 xml_insert_element_with_attribute (elt
, arg
, NULL
);
994 xml_insert_entity (char *entity_name
)
996 int saved_escape_html
= escape_html
;
1000 if (docbook
&& !only_macro_expansion
&& (in_menu
|| in_detailmenu
))
1003 if (!xml_in_para
&& !xml_no_para
&& !only_macro_expansion
1004 && xml_element_list
[xml_current_element ()].contains_para
1005 && !in_fixed_width_font
)
1010 escape_html
= saved_escape_html
;
1011 insert_string (entity_name
);
1015 typedef struct _xml_section xml_section
;
1016 struct _xml_section
{
1022 xml_section
*last_section
= NULL
;
1025 xml_begin_node (void)
1027 first_section_opened
= 1;
1028 if (xml_in_abstract
)
1030 xml_insert_element (ABSTRACT
, END
);
1031 xml_in_abstract
= 0;
1033 if (xml_in_bookinfo
)
1035 xml_insert_element (BOOKINFO
, END
);
1036 xml_in_bookinfo
= 0;
1038 if (xml_node_open
&& ! docbook
)
1040 if (xml_node_level
!= -1)
1042 xml_close_sections (xml_node_level
);
1043 xml_node_level
= -1;
1045 xml_insert_element (NODE
, END
);
1047 xml_insert_element (NODE
, START
);
1052 xml_close_sections (int level
)
1054 if (!first_section_opened
)
1056 if (xml_in_abstract
)
1058 xml_insert_element (ABSTRACT
, END
);
1059 xml_in_abstract
= 0;
1061 if (xml_in_bookinfo
)
1063 xml_insert_element (BOOKINFO
, END
);
1064 xml_in_bookinfo
= 0;
1066 first_section_opened
= 1;
1069 while (last_section
&& last_section
->level
>= level
)
1071 xml_section
*temp
= last_section
;
1072 xml_insert_element (xml_element(last_section
->name
), END
);
1073 temp
= last_section
;
1074 last_section
= last_section
->prev
;
1081 xml_open_section (int level
, char *name
)
1083 xml_section
*sect
= (xml_section
*) xmalloc (sizeof (xml_section
));
1085 sect
->level
= level
;
1086 sect
->name
= xmalloc (1 + strlen (name
));
1087 strcpy (sect
->name
, name
);
1088 sect
->prev
= last_section
;
1089 last_section
= sect
;
1091 if (xml_node_open
&& xml_node_level
== -1)
1092 xml_node_level
= level
;
1096 xml_start_menu_entry (char *tem
)
1099 discard_until ("* ");
1101 /* The line number was already incremented in reader_loop when we
1102 saw the newline, and discard_until has now incremented again. */
1105 if (xml_in_menu_entry
)
1107 if (xml_in_menu_entry_comment
)
1109 xml_insert_element (MENUCOMMENT
, END
);
1110 xml_in_menu_entry_comment
=0;
1112 xml_insert_element (MENUENTRY
, END
);
1113 xml_in_menu_entry
=0;
1115 xml_insert_element (MENUENTRY
, START
);
1116 xml_in_menu_entry
=1;
1118 xml_insert_element (MENUNODE
, START
);
1119 string
= expansion (tem
, 0);
1121 xml_insert_element (MENUNODE
, END
);
1124 /* The menu item may use macros, so expand them now. */
1125 xml_insert_element (MENUTITLE
, START
);
1126 only_macro_expansion
++;
1127 get_until_in_line (1, ":", &string
);
1128 only_macro_expansion
--;
1129 execute_string ("%s", string
); /* get escaping done */
1130 xml_insert_element (MENUTITLE
, END
);
1133 if (looking_at ("::"))
1134 discard_until (":");
1136 { /* discard the node name */
1137 get_until_in_line (0, ".", &string
);
1140 input_text_offset
++; /* discard the second colon or the period */
1141 skip_whitespace_and_newlines();
1142 xml_insert_element (MENUCOMMENT
, START
);
1143 xml_in_menu_entry_comment
++;
1149 if (xml_in_menu_entry
)
1151 if (xml_in_menu_entry_comment
)
1153 xml_insert_element (MENUCOMMENT
, END
);
1154 xml_in_menu_entry_comment
--;
1156 xml_insert_element (MENUENTRY
, END
);
1157 xml_in_menu_entry
--;
1159 xml_insert_element (MENU
, END
);
1162 static int xml_last_character
;
1165 xml_add_char (int character
)
1169 if (docbook
&& !only_macro_expansion
&& (in_menu
|| in_detailmenu
))
1172 if (docbook
&& xml_table_level
&& !in_table_title
1173 && !xml_in_item
[xml_table_level
] && !xml_in_tableitem
[xml_table_level
]
1174 && !cr_or_whitespace (character
) && !in_indexterm
)
1177 xml_insert_element (TITLE
, START
);
1180 if (!first_section_opened
&& !xml_in_abstract
&& !xml_in_book_title
1181 && !xml_no_para
&& character
!= '\r' && character
!= '\n'
1182 && character
!= ' ' && !is_in_insertion_of_type (copying
))
1184 if (!xml_in_bookinfo
)
1186 xml_insert_element (BOOKINFO
, START
);
1187 xml_in_bookinfo
= 1;
1189 xml_insert_element (ABSTRACT
, START
);
1190 xml_in_abstract
= 1;
1193 if (!xml_sort_index
&& !xml_in_xref_token
&& !xml_dont_touch_items_defs
)
1195 if (xml_after_table_term
&& xml_table_level
1196 && !xml_in_item
[xml_table_level
])
1198 xml_after_table_term
= 0;
1199 xml_insert_element (ITEM
, START
);
1200 xml_in_item
[xml_table_level
] = 1;
1202 else if (xml_after_def_term
)
1204 xml_after_def_term
= 0;
1205 xml_insert_element (DEFINITIONITEM
, START
);
1206 xml_in_def_item
[xml_definition_level
] = 1;
1210 if (xml_just_after_element
&& !xml_in_para
&& !inhibit_paragraph_indentation
)
1212 if (character
== '\r' || character
== '\n' || character
== '\t' || character
== ' ')
1214 xml_just_after_element
= 0;
1217 if (xml_element_list
[xml_current_element()].contains_para
1218 && !xml_in_para
&& !only_macro_expansion
&& !xml_no_para
1219 && !cr_or_whitespace (character
) && !in_fixed_width_font
)
1222 if (xml_in_para
&& character
== '\n' && xml_last_character
== '\n'
1223 && !only_macro_expansion
&& !xml_no_para
1224 && xml_element_list
[xml_current_element()].contains_para
)
1227 xml_just_after_element
= 1;
1231 if (xml_in_menu_entry_comment
&& character
== '\n' && xml_last_character
== '\n')
1233 xml_insert_element (MENUCOMMENT
, END
);
1234 xml_in_menu_entry_comment
= 0;
1235 xml_insert_element (MENUENTRY
, END
);
1236 xml_in_menu_entry
= 0;
1239 if (xml_in_menu_entry_comment
&& whitespace(character
)
1240 && cr_or_whitespace(xml_last_character
))
1243 if (character
== '\n' && !xml_in_para
&& !inhibit_paragraph_indentation
)
1246 xml_last_character
= character
;
1248 if (character
== '&' && escape_html
)
1249 insert_string ("&");
1250 else if (character
== '<' && escape_html
)
1251 insert_string ("<");
1252 else if (character
== '\n' && !xml_keep_space
)
1254 if (!xml_in_para
&& xml_just_after_element
&& !multitable_active
)
1257 insert (docbook
? '\n' : ' ');
1266 xml_insert_footnote (char *note
)
1271 xml_in_footnote
= 1;
1272 xml_insert_element (FOOTNOTE
, START
);
1273 insert_string ("<para>");
1274 execute_string ("%s", note
);
1275 insert_string ("</para>");
1276 xml_insert_element (FOOTNOTE
, END
);
1277 xml_in_footnote
= 0;
1280 /* We need to keep the quotation stack ourself, because insertion_stack
1281 loses item_function when we are closing the block, so we don't know
1282 what to close then. */
1283 typedef struct quotation_elt
1285 struct quotation_elt
*next
;
1289 static QUOTATION_ELT
*quotation_stack
= NULL
;
1292 xml_insert_quotation (char *type
, int arg
)
1294 int quotation_started
= 0;
1298 QUOTATION_ELT
*new = xmalloc (sizeof (QUOTATION_ELT
));
1299 new->type
= xstrdup (type
);
1300 new->next
= quotation_stack
;
1301 quotation_stack
= new;
1304 type
= quotation_stack
->type
;
1306 /* Make use of special quotation styles of Docbook if we can. */
1307 if (docbook
&& strlen(type
))
1309 /* Let's assume it started. */
1310 quotation_started
= 1;
1312 if (strcasecmp (type
, "tip") == 0)
1313 xml_insert_element (TIP
, arg
);
1314 else if (strcasecmp (type
, "note") == 0)
1315 xml_insert_element (NOTE
, arg
);
1316 else if (strcasecmp (type
, "important") == 0)
1317 xml_insert_element (IMPORTANT
, arg
);
1318 else if (strcasecmp (type
, "warning") == 0)
1319 xml_insert_element (WARNING
, arg
);
1320 else if (strcasecmp (type
, "caution") == 0)
1321 xml_insert_element (CAUTION
, arg
);
1323 /* Didn't find a known quotation type :\ */
1324 quotation_started
= 0;
1327 if (!quotation_started
)
1329 xml_insert_element (QUOTATION
, arg
);
1330 if (strlen(type
) && arg
== START
)
1331 execute_string ("@b{%s:} ", type
);
1336 QUOTATION_ELT
*temp
= quotation_stack
;
1339 quotation_stack
= quotation_stack
->next
;
1345 /* Starting generic docbook floats. Just starts elt with correct label
1346 and id attributes, and inserts title. */
1348 xml_begin_docbook_float (int elt
)
1350 if (current_float_used_title ()) /* in a nested float */
1352 xml_insert_element (elt
, START
); /* just insert the tag */
1357 /* OK, need the title, tag, etc. */
1358 if (elt
== CARTOUCHE
) /* no labels on <sidebar> */
1360 if (strlen (current_float_id ()) == 0)
1361 xml_insert_element (elt
, START
);
1363 xml_insert_element_with_attribute (elt
, START
,
1364 "id=\"%s\"", xml_id (current_float_id ()));
1366 else if (strlen (current_float_id ()) == 0)
1367 xml_insert_element_with_attribute (elt
, START
, "label=\"\"");
1369 xml_insert_element_with_attribute (elt
, START
,
1370 "id=\"%s\" label=\"%s\"", xml_id (current_float_id ()),
1371 current_float_number ());
1373 xml_insert_element (TITLE
, START
);
1374 execute_string ("%s", current_float_title ());
1375 xml_insert_element (TITLE
, END
);
1377 current_float_set_title_used (); /* mark this title, tag, etc used */
1384 xml_begin_table (int type
, char *item_function
)
1391 /*if (docbook)*/ /* 05-08 */
1393 xml_insert_element (TABLE
, START
);
1395 xml_in_tableitem
[xml_table_level
] = 0;
1396 xml_in_item
[xml_table_level
] = 0;
1397 xml_after_table_term
= 0;
1403 xml_insert_element (ITEMIZE
, START
);
1405 xml_in_item
[xml_table_level
] = 0;
1406 xml_insert_element (ITEMFUNCTION
, START
);
1407 if (*item_function
== COMMAND_PREFIX
1408 && item_function
[strlen (item_function
) - 1] != '}'
1409 && command_needs_braces (item_function
+ 1))
1410 execute_string ("%s{}", item_function
);
1412 execute_string ("%s", item_function
);
1413 xml_insert_element (ITEMFUNCTION
, END
);
1417 xml_insert_element_with_attribute (ITEMIZE
, START
,
1419 (*item_function
== COMMAND_PREFIX
) ?
1420 &item_function
[1] : item_function
);
1422 xml_in_item
[xml_table_level
] = 0;
1429 xml_end_table (int type
)
1436 if (xml_in_item
[xml_table_level
])
1438 xml_insert_element (ITEM
, END
);
1439 xml_in_item
[xml_table_level
] = 0;
1441 if (xml_in_tableitem
[xml_table_level
])
1443 xml_insert_element (TABLEITEM
, END
);
1444 xml_in_tableitem
[xml_table_level
] = 0;
1446 xml_insert_element (TABLE
, END
);
1447 xml_after_table_term
= 0;
1452 if (xml_in_item
[xml_table_level
])
1454 xml_insert_element (ITEM
, END
);
1455 xml_in_item
[xml_table_level
] = 0;
1457 /* gnat-style manual contains an itemized list without items! */
1460 xml_insert_element (TITLE
, END
);
1463 xml_insert_element (ITEMIZE
, END
);
1470 xml_begin_item (void)
1472 if (xml_in_item
[xml_table_level
])
1473 xml_insert_element (ITEM
, END
);
1475 xml_insert_element (ITEM
, START
);
1476 xml_in_item
[xml_table_level
] = 1;
1480 xml_begin_table_item (void)
1482 if (!xml_after_table_term
)
1484 if (xml_in_item
[xml_table_level
])
1485 xml_insert_element (ITEM
, END
);
1486 if (xml_in_tableitem
[xml_table_level
])
1487 xml_insert_element (TABLEITEM
, END
);
1492 xml_insert_element (TITLE
, END
);
1494 xml_insert_element (TABLEITEM
, START
);
1496 xml_insert_element (TABLETERM
, START
);
1497 xml_in_tableitem
[xml_table_level
] = 1;
1498 xml_in_item
[xml_table_level
] = 0;
1499 xml_after_table_term
= 0;
1503 xml_continue_table_item (void)
1505 xml_insert_element (TABLETERM
, END
);
1506 xml_after_table_term
= 1;
1507 xml_in_item
[xml_table_level
] = 0;
1511 xml_begin_enumerate (char *enum_arg
)
1514 xml_insert_element_with_attribute (ENUMERATE
, START
, "first=\"%s\"", enum_arg
);
1517 if (isdigit (*enum_arg
))
1519 int enum_val
= atoi (enum_arg
);
1521 /* Have to check the value, not just the first digit. */
1523 xml_insert_element_with_attribute (ENUMERATE
, START
,
1524 "numeration=\"arabic\" role=\"0\"", NULL
);
1525 else if (enum_val
== 1)
1526 xml_insert_element_with_attribute (ENUMERATE
, START
,
1527 "numeration=\"arabic\"", NULL
);
1529 xml_insert_element_with_attribute (ENUMERATE
, START
,
1530 "continuation=\"continues\" numeration=\"arabic\"", NULL
);
1532 else if (isupper (*enum_arg
))
1534 if (enum_arg
[0] == 'A')
1535 xml_insert_element_with_attribute (ENUMERATE
, START
,
1536 "numeration=\"upperalpha\"", NULL
);
1538 xml_insert_element_with_attribute (ENUMERATE
, START
,
1539 "continuation=\"continues\" numeration=\"upperalpha\"", NULL
);
1543 if (enum_arg
[0] == 'a')
1544 xml_insert_element_with_attribute (ENUMERATE
, START
,
1545 "numeration=\"loweralpha\"", NULL
);
1547 xml_insert_element_with_attribute (ENUMERATE
, START
,
1548 "continuation=\"continues\" numeration=\"loweralpha\"", NULL
);
1552 xml_in_item
[xml_table_level
] = 0;
1556 xml_end_enumerate (void)
1558 if (xml_in_item
[xml_table_level
])
1560 xml_insert_element (ITEM
, END
);
1561 xml_in_item
[xml_table_level
] = 0;
1563 xml_insert_element (ENUMERATE
, END
);
1568 xml_insert_text_file (char *name_arg
)
1570 char *fullname
= xmalloc (strlen (name_arg
) + 4 + 1);
1572 strcpy (fullname
, name_arg
);
1573 strcat (fullname
, ".txt");
1574 image_file
= fopen (fullname
, "r");
1578 int save_inhibit_indentation
= inhibit_paragraph_indentation
;
1579 int save_filling_enabled
= filling_enabled
;
1581 xml_insert_element (TEXTOBJECT
, START
);
1582 xml_insert_element (DISPLAY
, START
);
1584 inhibit_paragraph_indentation
= 1;
1585 filling_enabled
= 0;
1586 last_char_was_newline
= 0;
1588 /* Maybe we need to remove the final newline if the image
1589 file is only one line to allow in-line images. On the
1590 other hand, they could just make the file without a
1592 while ((ch
= getc (image_file
)) != EOF
)
1595 inhibit_paragraph_indentation
= save_inhibit_indentation
;
1596 filling_enabled
= save_filling_enabled
;
1598 xml_insert_element (DISPLAY
, END
);
1599 xml_insert_element (TEXTOBJECT
, END
);
1601 if (fclose (image_file
) != 0)
1605 warning (_("@image file `%s' unreadable: %s"), fullname
,
1611 /* If NAME.EXT is accessible or FORCE is nonzero, insert a docbook
1612 imagedata element for FMT. Return 1 if inserted something, 0 else. */
1615 try_docbook_image (const char *name
, const char *ext
, const char *fmt
,
1619 char *fullname
= xmalloc (strlen (name
) + 1 + strlen (ext
) + 1);
1620 sprintf (fullname
, "%s.%s", name
, ext
);
1622 if (force
|| access (fullname
, R_OK
) == 0)
1624 xml_insert_element (IMAGEOBJECT
, START
);
1625 xml_insert_element_with_attribute (IMAGEDATA
, START
,
1626 "fileref=\"%s\" format=\"%s\"", fullname
, fmt
);
1627 xml_insert_element (IMAGEDATA
, END
);
1628 xml_insert_element (IMAGEOBJECT
, END
);
1638 xml_insert_docbook_image (char *name_arg
)
1641 int elt
= xml_in_para
? INLINEIMAGE
: MEDIAOBJECT
;
1643 if (is_in_insertion_of_type (floatenv
))
1644 xml_begin_docbook_float (INFORMALFIGURE
);
1645 else if (!xml_in_para
)
1646 xml_insert_element (INFORMALFIGURE
, START
);
1650 xml_insert_element (elt
, START
);
1652 /* A selected few from http://docbook.org/tdg/en/html/imagedata.html. */
1653 if (try_docbook_image (name_arg
, "eps", "EPS", 0))
1655 if (try_docbook_image (name_arg
, "gif", "GIF", 0))
1657 if (try_docbook_image (name_arg
, "jpg", "JPG", 0))
1659 if (try_docbook_image (name_arg
, "jpeg", "JPEG", 0))
1661 if (try_docbook_image (name_arg
, "pdf", "PDF", 0))
1663 if (try_docbook_image (name_arg
, "png", "PNG", 0))
1665 if (try_docbook_image (name_arg
, "svg", "SVG", 0))
1668 /* If no luck so far, just assume we'll eventually have a jpg. */
1670 try_docbook_image (name_arg
, "jpg", "JPG", 1);
1672 xml_insert_text_file (name_arg
);
1673 xml_insert_element (elt
, END
);
1677 if (elt
== MEDIAOBJECT
)
1678 xml_insert_element (INFORMALFIGURE
, END
);
1690 /* Used to separate primary and secondary entries in an index -- we need
1691 to have real multilivel indexing support, not just string analysis. */
1692 #define INDEX_SEP "@this string will never appear@" /* was , */
1700 static XML_SYNONYM
**xml_synonyms
= NULL
;
1701 static int xml_synonyms_count
= 0;
1704 xml_insert_indexterm (char *indexterm
, char *index
)
1706 /* @index commands can appear between @item and @itemx, @deffn and @deffnx. */
1709 /* Check to see if we need to do index redirection per @synindex. */
1711 for (i
= 0; i
< xml_synonyms_count
; i
++)
1713 if (STREQ (xml_synonyms
[i
]->from
, index
))
1714 index
= xstrdup (xml_synonyms
[i
]->to
);
1717 xml_dont_touch_items_defs
++;
1718 xml_insert_element_with_attribute (INDEXTERM
, START
, "index=\"%s\"", index
);
1720 execute_string ("%s", indexterm
);
1721 xml_insert_element (INDEXTERM
, END
);
1723 xml_dont_touch_items_defs
--;
1727 char *primary
= NULL
, *secondary
= NULL
;
1728 if (strstr (indexterm
+1, INDEX_SEP
))
1730 primary
= xmalloc (strlen (indexterm
) + 1);
1731 strcpy (primary
, indexterm
);
1732 secondary
= strstr (primary
+1, INDEX_SEP
);
1734 secondary
+= strlen (INDEX_SEP
);
1736 xml_insert_element_with_attribute (INDEXTERM
, START
, "role=\"%s\"", index
);
1738 xml_insert_element (PRIMARY
, START
);
1740 execute_string ("%s", primary
);
1742 execute_string ("%s", indexterm
);
1743 xml_insert_element (PRIMARY
, END
);
1746 xml_insert_element (SECONDARY
, START
);
1747 execute_string ("%s", secondary
);
1748 xml_insert_element (SECONDARY
, END
);
1750 xml_insert_element (INDEXTERM
, END
);
1756 int xml_last_section_output_position
= 0;
1757 static char last_division_letter
= ' ';
1758 static char index_primary
[2000]; /** xx no fixed limit */
1759 static int indexdivempty
= 0;
1762 xml_close_indexentry (void)
1767 xml_insert_element (SECONDARYIE
, END
);
1768 xml_insert_element (INDEXENTRY
, END
);
1774 xml_begin_index (void)
1776 typedef struct xml_index_title
{
1777 struct xml_index_title
*next
;
1781 static XML_INDEX_TITLE
*xml_index_titles
= NULL
;
1783 if (!handling_delayed_writes
)
1784 { /* We assume that we just opened a section, and so that the last output is
1785 <SECTION ID="node-name"><TITLE>Title</TITLE>
1786 where SECTION can be CHAPTER, ... */
1788 XML_INDEX_TITLE
*new = xmalloc (sizeof (XML_INDEX_TITLE
));
1789 xml_section
*temp
= last_section
;
1791 int l
= output_paragraph_offset
-xml_last_section_output_position
;
1792 char *tmp
= xmalloc (l
+1);
1794 strncpy (tmp
, (char *) output_paragraph
, l
);
1796 /* We remove <SECTION */
1802 /* ... and its label attribute. */
1803 if (strncmp (p
, " label=", 7) == 0)
1810 output_paragraph_offset
= xml_last_section_output_position
;
1811 xml_last_section_output_position
= 0;
1813 xml_pop_current_element (); /* remove section element from elements stack */
1816 last_section
= last_section
->prev
; /* remove section from sections stack */
1823 new->title
= xstrdup (p
);
1824 new->next
= xml_index_titles
;
1825 xml_index_titles
= new;
1829 static int xml_index_titles_reversed
= 0;
1831 if (!xml_index_titles_reversed
)
1833 xml_index_titles
= (XML_INDEX_TITLE
*) reverse_list
1834 ((GENERIC_LIST
*) xml_index_titles
);
1835 xml_index_titles_reversed
= 1;
1838 /* We put <INDEX> */
1839 xml_insert_element (PRINTINDEX
, START
);
1840 if (xml_index_titles
)
1842 /* Remove the final > */
1843 output_paragraph_offset
--;
1844 /* and put ID="node-name"><TITLE>Title</TITLE> */
1845 insert_string (xml_index_titles
->title
);
1846 free (xml_index_titles
->title
);
1847 xml_index_titles
= xml_index_titles
->next
;
1850 if (xml_index_divisions
)
1852 xml_insert_element (INDEXDIV
, START
);
1859 xml_end_index (void)
1861 xml_close_indexentry ();
1862 if (xml_index_divisions
)
1863 xml_insert_element (INDEXDIV
, END
);
1864 xml_insert_element (PRINTINDEX
, END
);
1868 xml_index_divide (char *entry
)
1871 if (strlen (entry
) > (strlen (xml_element_list
[CODE
].name
) + 2) &&
1872 strncmp (entry
+1, xml_element_list
[CODE
].name
, strlen (xml_element_list
[CODE
].name
)) == 0)
1873 c
= entry
[strlen (xml_element_list
[CODE
].name
)+2];
1876 if (tolower (c
) != last_division_letter
&& isalpha (c
))
1878 last_division_letter
= tolower (c
);
1879 xml_close_indexentry ();
1882 xml_insert_element (INDEXDIV
, END
);
1883 xml_insert_element (INDEXDIV
, START
);
1885 xml_insert_element (TITLE
, START
);
1886 insert (toupper (c
));
1887 xml_insert_element (TITLE
, END
);
1892 xml_insert_indexentry (char *entry
, char *node
)
1894 char *primary
= NULL
, *secondary
;
1895 if (xml_index_divisions
)
1896 xml_index_divide (entry
);
1899 if (strstr (entry
+1, INDEX_SEP
))
1901 primary
= xmalloc (strlen (entry
) + 1);
1902 strcpy (primary
, entry
);
1903 secondary
= strstr (primary
+1, INDEX_SEP
);
1905 secondary
+= strlen (INDEX_SEP
);
1907 if (in_secondary
&& strcmp (primary
, index_primary
) == 0)
1909 xml_insert_element (SECONDARYIE
, END
);
1910 xml_insert_element (SECONDARYIE
, START
);
1911 execute_string ("%s", secondary
);
1915 xml_close_indexentry ();
1916 xml_insert_element (INDEXENTRY
, START
);
1918 xml_insert_element (PRIMARYIE
, START
);
1919 execute_string ("%s", primary
);
1920 xml_insert_element (PRIMARYIE
, END
);
1921 xml_insert_element (SECONDARYIE
, START
);
1922 execute_string ("%s", secondary
);
1928 xml_close_indexentry ();
1929 xml_insert_element (INDEXENTRY
, START
);
1931 xml_insert_element (PRIMARYIE
, START
);
1932 execute_string ("%s", entry
);
1936 /* Don't link to @unnumbered sections directly.
1937 We are disabling warnings temporarily, otherwise these xrefs
1938 will cause bogus warnings about missing punctuation. */
1940 extern int print_warnings
;
1941 int save_print_warnings
= print_warnings
;
1943 execute_string ("%cxref{%s}", COMMAND_PREFIX
, xstrdup (node
));
1944 print_warnings
= save_print_warnings
;
1949 strcpy (index_primary
, primary
);
1950 /* xml_insert_element (SECONDARYIE, END);*/
1951 /* *(secondary-1) = ',';*/ /* necessary ? */
1955 xml_insert_element (PRIMARYIE
, END
);
1957 /* xml_insert_element (INDEXENTRY, END); */
1961 xml_synindex (char *from
, char *to
)
1966 for (i
= 0; i
< xml_synonyms_count
; i
++)
1967 if (!xml_synonyms
[i
])
1975 slot
= xml_synonyms_count
;
1976 xml_synonyms_count
++;
1978 xml_synonyms
= (XML_SYNONYM
**) xrealloc (xml_synonyms
,
1979 (xml_synonyms_count
+ 1) * sizeof (XML_SYNONYM
*));
1982 xml_synonyms
[slot
] = xmalloc (sizeof (XML_SYNONYM
));
1983 xml_synonyms
[slot
]->from
= xstrdup (from
);
1984 xml_synonyms
[slot
]->to
= xstrdup (to
);
1991 static int multitable_columns_count
;
1992 static int *multitable_column_widths
;
1995 xml_begin_multitable (int ncolumns
, int *column_widths
)
2000 if (is_in_insertion_of_type (floatenv
))
2001 xml_begin_docbook_float (MULTITABLE
);
2003 xml_insert_element (MULTITABLE
, START
);
2005 multitable_columns_count
= ncolumns
;
2006 multitable_column_widths
= xmalloc (sizeof (int) * ncolumns
);
2007 memcpy (multitable_column_widths
, column_widths
,
2008 sizeof (int) * ncolumns
);
2014 xml_insert_element (MULTITABLE
, START
);
2015 for (i
=0; i
<ncolumns
; i
++)
2017 xml_insert_element (COLSPEC
, START
);
2018 add_word_args ("%d", column_widths
[i
]);
2019 xml_insert_element (COLSPEC
, END
);
2026 xml_begin_multitable_group (void)
2030 xml_insert_element_with_attribute (TGROUP
, START
, "cols=\"%d\"",
2031 multitable_columns_count
);
2033 for (i
=0; i
< multitable_columns_count
; i
++)
2035 xml_insert_element_with_attribute (COLSPEC
, START
,
2036 "colwidth=\"%d*\"", multitable_column_widths
[i
]);
2037 xml_insert_element (COLSPEC
, END
);
2042 xml_end_multitable_row (int first_row
)
2046 xml_insert_element (ENTRY
, END
);
2047 xml_insert_element (ROW
, END
);
2055 xml_insert_element (THEAD
, END
);
2057 xml_insert_element (TBODY
, END
);
2058 xml_insert_element (TGROUP
, END
);
2061 xml_begin_multitable_group ();
2062 xml_insert_element (THEAD
, START
);
2066 xml_begin_multitable_group ();
2067 xml_insert_element (TBODY
, START
);
2069 else if (after_headitem
)
2071 xml_insert_element (THEAD
, END
);
2072 xml_insert_element (TBODY
, START
);
2075 xml_insert_element (TBODY
, START
);
2077 xml_insert_element (ROW
, START
);
2078 xml_insert_element (ENTRY
, START
);
2082 xml_end_multitable_column (void)
2084 xml_insert_element (ENTRY
, END
);
2085 xml_insert_element (ENTRY
, START
);
2089 xml_end_multitable (void)
2091 xml_insert_element (ENTRY
, END
);
2092 xml_insert_element (ROW
, END
);
2097 warning (_("@headitem as the last item of @multitable produces invalid Docbook documents"));
2098 xml_insert_element (THEAD
, END
);
2101 xml_insert_element (TBODY
, END
);
2104 xml_insert_element (TGROUP
, END
);
2106 xml_insert_element (MULTITABLE
, END
);
2111 * Parameters in @def definitions
2114 #define DEFUN_SELF_DELIMITING(c) \
2115 ((c) == '(' || (c) == ')' || (c) == '[' || (c) == ']')
2118 xml_process_defun_args (char **defun_args
, int auto_var_p
)
2120 int pending_space
= 0;
2121 int just_after_paramtype
= 0;
2125 char *defun_arg
= *defun_args
++;
2127 if (defun_arg
== NULL
)
2130 if (defun_arg
[0] == ' ')
2142 if (DEFUN_SELF_DELIMITING (defun_arg
[0]))
2144 xml_insert_element (DEFDELIMITER
, START
);
2145 add_char (defun_arg
[0]);
2146 xml_insert_element (DEFDELIMITER
, END
);
2147 just_after_paramtype
= 0;
2149 else if (defun_arg
[0] == '&')
2151 xml_insert_element (DEFPARAM
, START
);
2152 add_word (defun_arg
);
2153 xml_insert_element (DEFPARAM
, END
);
2154 just_after_paramtype
= 0;
2156 else if (defun_arg
[0] == COMMAND_PREFIX
|| just_after_paramtype
)
2158 xml_insert_element (DEFPARAM
, START
);
2159 execute_string ("%s", defun_arg
);
2160 xml_insert_element (DEFPARAM
, END
);
2161 just_after_paramtype
= 0;
2163 else if (defun_arg
[0] == ',' || defun_arg
[0] == ';')
2165 xml_insert_element (DEFDELIMITER
, START
);
2166 add_word (defun_arg
);
2167 xml_insert_element (DEFDELIMITER
, END
);
2168 just_after_paramtype
= 0;
2170 else if (auto_var_p
)
2172 xml_insert_element (DEFPARAM
, START
);
2173 add_word (defun_arg
);
2174 xml_insert_element (DEFPARAM
, END
);
2175 just_after_paramtype
= 0;
2179 xml_insert_element (DEFPARAMTYPE
, START
);
2180 add_word (defun_arg
);
2181 xml_insert_element (DEFPARAMTYPE
, END
);
2182 just_after_paramtype
= 1;
2188 xml_begin_definition (void)
2190 xml_insert_element (DEFINITION
, START
);
2191 xml_definition_level
++;
2192 xml_in_def_item
[xml_definition_level
] = 0;
2196 xml_end_definition (void)
2198 if (xml_in_def_item
[xml_definition_level
])
2200 xml_insert_element (DEFINITIONITEM
, END
);
2201 xml_in_def_item
[xml_definition_level
] = 0;
2203 xml_after_def_term
= 0;
2204 xml_insert_element (DEFINITION
, END
);
2205 xml_definition_level
--;
2209 xml_begin_def_term (int base_type
, const char *category
,
2210 char *defined_name
, char *type_name
, char *type_name2
)
2212 xml_after_def_term
= 0;
2213 xml_insert_element (DEFINITIONTERM
, START
);
2220 execute_string ("@findex %s\n", defined_name
);
2225 execute_string ("@vindex %s\n", defined_name
);
2229 execute_string ("@vindex %s %s %s\n", defined_name
, _("of"), type_name
);
2234 execute_string ("@findex %s %s %s\n", defined_name
, _("on"), type_name
);
2237 execute_string ("@tindex %s\n", defined_name
);
2241 /* Start with category. */
2242 xml_insert_element (DEFCATEGORY
, START
);
2243 execute_string (docbook
? "--- %s:" : "%s", category
);
2244 xml_insert_element (DEFCATEGORY
, END
);
2247 /* Output type name first for typed definitions. */
2257 xml_insert_element (DEFTYPE
, START
);
2258 execute_string ("%s", type_name
);
2259 xml_insert_element (DEFTYPE
, END
);
2267 xml_insert_element (DEFTYPE
, START
);
2268 execute_string ("%s", type_name2
);
2269 xml_insert_element (DEFTYPE
, END
);
2274 xml_insert_element (DEFCLASS
, START
);
2275 execute_string ("%s", type_name
);
2276 xml_insert_element (DEFCLASS
, END
);
2281 /* Categorize rest of the definitions. */
2286 xml_insert_element (DEFFUNCTION
, START
);
2287 execute_string ("%s", defined_name
);
2288 xml_insert_element (DEFFUNCTION
, END
);
2293 xml_insert_element (DEFVARIABLE
, START
);
2294 execute_string ("%s", defined_name
);
2295 xml_insert_element (DEFVARIABLE
, END
);
2299 xml_insert_element (DEFDATATYPE
, START
);
2300 execute_string ("%s", defined_name
);
2301 xml_insert_element (DEFDATATYPE
, END
);
2307 xml_insert_element (DEFCLASSVAR
, START
);
2308 execute_string ("%s", defined_name
);
2309 xml_insert_element (DEFCLASSVAR
, END
);
2315 /* Operation / Method */
2316 xml_insert_element (DEFOPERATION
, START
);
2317 execute_string ("%s", defined_name
);
2318 xml_insert_element (DEFOPERATION
, END
);
2324 xml_end_def_term (void)
2326 xml_insert_element (DEFINITIONTERM
, END
);
2327 xml_after_def_term
= 1;