3 /* xml.c -- xml output.
4 Id: xml.c,v 1.52 2004/12/19 17:02:23 karl Exp
6 Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
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)
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.
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.
22 Originally written by Philippe Martin <feloy@free.fr>. */
26 #include "insertion.h"
36 int xml_index_divisions
= 1;
38 typedef struct _element
42 int contained_in_para
;
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 },
54 { "nodenext", 0, 0, 0 },
55 { "nodeprev", 0, 0, 0 },
56 { "nodeup", 0, 0, 0 },
58 { "chapter", 1, 0, 0 },
59 { "section", 1, 0, 0 },
60 { "subsection", 1, 0, 0 },
61 { "subsubsection", 1, 0, 0 },
64 { "unnumbered", 1, 0, 0 },
65 { "unnumberedsec", 1, 0, 0 },
66 { "unnumberedsubsec", 1, 0, 0 },
67 { "unnumberedsubsubsec", 1, 0, 0 },
69 { "appendix", 1, 0, 0 },
70 { "appendixsec", 1, 0, 0 },
71 { "appendixsubsec", 1, 0, 0 },
72 { "appendixsubsubsec", 1, 0, 0 },
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 },
80 { "titlepage", 1, 0, 0 },
81 { "author", 0, 0, 0 },
82 { "booktitle", 0, 0, 0 },
83 { "booksubtitle", 0, 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 },
93 { "acronym", 0, 1, 0 },
94 { "acronymword", 0, 1, 0 },
95 { "acronymdesc", 0, 1, 0 },
97 { "abbrev", 0, 1, 0 },
98 { "abbrevword", 0, 1, 0 },
99 { "abbrevdesc", 0, 1, 0 },
103 { "command", 0, 1, 0 },
106 { "option", 0, 1, 0 },
115 { "strong", 0, 1, 0 },
117 { "notfixedwidth", 0, 1, 0 },
121 { "slanted", 0, 1, 0 },
122 { "sansserif", 0, 1, 0 },
124 { "exdent", 0, 0, 0 },
126 { "title", 0, 0, 0 },
127 { "ifinfo", 1, 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 },
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) */
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) */
152 { "itemize", 0, 0, 0 },
153 { "itemfunction", 0, 0, 0 },
155 { "enumerate", 0, 0, 0 },
156 { "table", 0, 0, 0 },
157 { "tableitem", 0, 0, 0 },
158 { "tableterm", 0, 0, 0 },
160 { "indexterm", 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 },
173 { "inforef", 0, 1, 0 },
174 { "inforefnodename", 0, 1, 0 },
175 { "inforefrefname", 0, 1, 0 },
176 { "inforefinfoname", 0, 1, 0 },
179 { "urefurl", 0, 1, 0 },
180 { "urefdesc", 0, 1, 0 },
181 { "urefreplacement", 0, 1, 0 },
183 { "email", 0, 1, 0 },
184 { "emailaddress", 0, 1, 0 },
185 { "emailname", 0, 1, 0 },
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 },
194 { "", 0, 0, 0 }, /* TABLE (docbook) */
195 { "", 0, 0, 0 }, /* FIGURE (docbook) */
196 { "", 0, 0, 0 }, /* EXAMPLE (docbook) */
197 { "", 1, 0, 0 }, /* SIDEBAR (docbook) */
199 { "printindex", 0, 0, 0 },
200 { "listoffloats", 0, 0, 0 },
201 { "anchor", 0, 1, 0 },
203 { "image", 0, 0, 0 },
204 { "inlineimage", 0, 1, 0 },
205 { "alttext", 0, 1, 0 },
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 },
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) */
233 { "contents", 0, 0, 0 },
234 { "shortcontents", 0, 0, 0 },
235 { "documentlanguage", 0, 0, 0 },
237 { "setvalue", 0, 0, 0 },
238 { "clearvalue", 0, 0, 0 },
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 },
255 { "para", 0, 0, 0 } /* Must be last */
256 /* name / contains para / contained in para / preserve space */
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 (?) */
266 { "", 1, 0, 0 }, /* NODE */
267 { "", 0, 0, 0 }, /* NODENEXT */
268 { "", 0, 0, 0 }, /* NODEPREV */
269 { "", 0, 0, 0 }, /* NODEUP */
271 { "chapter", 1, 0, 0 },
272 { "sect1", 1, 0, 0 }, /* SECTION */
273 { "sect2", 1, 0, 0 }, /* SUBSECTION */
274 { "sect3", 1, 0, 0 }, /* SUBSUBSECTION */
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 */
282 { "appendix", 1, 0, 0 },
283 { "sect1", 1, 0, 0 }, /* APPENDIXSEC */
284 { "sect2", 1, 0, 0 }, /* APPENDIXSUBSEC */
285 { "sect3", 1, 0, 0 }, /* APPENDIXSUBSUBSEC */
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 */
293 { "", 0, 0, 0 }, /* TITLEPAGE */
294 { "", 0, 0, 0 }, /* AUTHOR */
295 { "", 0, 0, 0 }, /* BOOKTITLE */
296 { "", 0, 0, 0 }, /* BOOKSUBTITLE */
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 */
306 { "acronym", 0, 1, 0 },
307 { "", 0, 1, 0 }, /* ACRONYMWORD */
308 { "", 0, 1, 0 }, /* ACRONYMDESC */
310 { "abbrev", 0, 1, 0 },
311 { "", 0, 1, 0 }, /* ABBREVWORD */
312 { "", 0, 1, 0 }, /* ABBREVDESC */
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 */
335 { "", 0, 0, 0 }, /* EXDENT */
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 },
359 { "important", 1, 0, 0 },
360 { "warning", 1, 0, 0 },
361 { "caution", 1, 0, 0 },
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 */
371 { "indexterm", 0, 1, 0 }, /* INDEXTERM */
373 { "", 0, 1, 0 }, /* MATH */
375 { "", 0, 1, 0 }, /* DIMENSION */
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 */
384 { "", 0, 1, 0 }, /* INFOREF */
385 { "", 0, 1, 0 }, /* INFOREFNODENAME */
386 { "", 0, 1, 0 }, /* INFOREFREFNAME */
387 { "", 0, 1, 0 }, /* INFOREFINFONAME */
389 { "ulink", 0, 1, 0 }, /* UREF */
390 { "", 0, 1, 0 }, /* UREFURL */
391 { "", 0, 1, 0 }, /* UREFDESC */
392 { "", 0, 1, 0 }, /* UREFREPLACEMENT */
394 { "ulink", 0, 1, 0 }, /* EMAIL */
395 { "", 0, 1, 0 }, /* EMAILADDRESS */
396 { "", 0, 1, 0 }, /* EMAILNAME */
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 */
405 { "table", 0, 1, 0 },
406 { "figure", 0, 1, 0 },
407 { "example", 1, 1, 0 },
408 { "sidebar", 1, 0, 0 },
410 { "index", 0, 1, 0 }, /* PRINTINDEX */
411 { "", 0, 1, 0 }, /* LISTOFFLOATS */
412 { "", 0, 1, 0 }, /* ANCHOR */
414 { "", 0, 0, 0 }, /* IMAGE */
415 { "inlinemediaobject", 0, 1, 0 }, /* INLINEIMAGE */
416 { "", 0, 0, 0 }, /* IMAGEALTTEXT */
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 },
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 },
444 { "", 0, 0, 0 }, /* CONTENTS (xml) */
445 { "", 0, 0, 0 }, /* SHORTCONTENTS (xml) */
446 { "", 0, 0, 0 }, /* DOCUMENT LANGUAGE (xml) */
448 { "", 0, 0, 0 }, /* SETVALUE (xml) */
449 { "", 0, 0, 0 }, /* CLEARVALUE (xml) */
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 */
466 { "para", 0, 0, 0 } /* Must be last */
467 /* name / contains para / contained in para / preserve space */
470 element
*xml_element_list
= NULL
;
473 typedef struct _replace_element
475 int element_to_replace
;
476 int element_containing
;
477 int element_replacing
;
480 /* Elements to replace - Docbook only
482 if `element_to_replace' have to be inserted
483 as a child of `element_containing,'
484 use `element_replacing' instead.
486 A value of `-1' for element_replacing means `do not use any element.'
489 replace_element replace_elements
[] = {
490 { I
, TABLETERM
, EMPH
},
491 { B
, TABLETERM
, EMPH
},
493 { EXAMPLE
, DISPLAY
, -1 },
496 { EMPH
, CODE
, REPLACEABLE
},
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 */
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;
523 int xml_just_after_element
= 0;
524 int xml_keep_space
= 0;
526 int xml_no_indent
= 0;
529 char *xml_node_id
= NULL
;
530 int xml_sort_index
= 0;
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;
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;
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;
545 static int xml_after_table_term
= 0;
546 static int book_started
= 0;
547 static int first_section_opened
= 0;
549 static int xml_in_tableitem
[256];
550 static int xml_in_item
[256];
551 static int xml_table_level
= 0;
553 static int xml_in_def_item
[256];
554 static int xml_definition_level
= 0;
555 int xml_after_def_term
= 0;
557 static int in_table_title
= 0;
559 static int in_indexentry
= 0;
560 static int in_secondary
= 0;
561 static int in_indexterm
= 0;
566 char *tem
= xmalloc (strlen (id
) + 1);
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
))
578 /* First character can only be a letter. */
579 if (!strchr ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", *p
))
585 xml_element (char *name
)
588 for (i
=0; i
<=PARA
; i
++)
590 if (strcasecmp (name
, texinfoml_element_list
[i
].name
) == 0)
593 printf ("Error xml_element\n");
598 xml_begin_document (char *output_filename
)
605 /* Make sure this is the very first string of the output document. */
606 output_paragraph_offset
= 0;
608 insert_string ("<?xml version=\"1.0\"");
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.) */
617 extern int print_warnings
;
618 int save_print_warnings
= print_warnings
;
620 register_delayed_write ("@documentencoding");
621 print_warnings
= save_print_warnings
;
624 insert_string ("?>\n");
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
;
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
;
640 if (language_code
!= last_language_code
)
643 xml_insert_element_with_attribute (TEXINFO
, START
, "lang=\"%s\"", language_table
[language_code
].abbrev
);
645 xml_insert_element_with_attribute (TEXINFO
, START
, "xml:lang=\"%s\"", language_table
[language_code
].abbrev
);
649 xml_insert_element (SETFILENAME
, START
);
650 insert_string (output_filename
);
651 xml_insert_element (SETFILENAME
, END
);
656 static int element_stack
[256];
657 static int element_stack_index
= 0;
660 xml_current_element (void)
662 return element_stack
[element_stack_index
-1];
666 xml_push_current_element (int elt
)
668 element_stack
[element_stack_index
++] = elt
;
669 if (element_stack_index
> 200)
670 printf ("*** stack overflow (%d - %s) ***\n",
672 xml_element_list
[elt
].name
);
676 xml_pop_current_element (void)
678 element_stack_index
--;
679 if (element_stack_index
< 0)
680 printf ("*** stack underflow (%d - %d) ***\n",
682 xml_current_element());
686 xml_current_stack_index (void)
688 return element_stack_index
;
692 xml_end_current_element (void)
694 xml_insert_element (xml_current_element (), END
);
700 if (xml_indentation_increment
> 0)
703 if (output_paragraph
[output_paragraph_offset
-1] != '\n')
705 for (i
= 0; i
< element_stack_index
* xml_indentation_increment
; i
++)
711 xml_start_para (void)
713 if (xml_in_para
|| xml_in_footnote
714 || !xml_element_list
[xml_current_element()].contains_para
)
717 while (output_paragraph
[output_paragraph_offset
-1] == '\n')
718 output_paragraph_offset
--;
721 insert_string ("<para");
723 insert_string (" role=\"continues\"");
732 if (!xml_in_para
|| xml_in_footnote
)
735 while (cr_or_whitespace(output_paragraph
[output_paragraph_offset
-1]))
736 output_paragraph_offset
--;
738 insert_string ("</para>");
739 if (xml_indentation_increment
> 0)
745 xml_end_document (void)
749 if (xml_node_level
!= -1)
751 xml_close_sections (xml_node_level
);
754 xml_insert_element (NODE
, END
);
757 xml_close_sections (xml_node_level
);
759 xml_insert_element (TEXINFO
, END
);
760 if (xml_indentation_increment
== 0)
762 insert_string ("<!-- Keep this comment at the end of the file\n\
765 sgml-indent-step:1\n\
766 sgml-indent-data:nil\n\
769 if (element_stack_index
!= 0)
770 error ("Element stack index : %d\n", element_stack_index
);
773 /* MUST be 0 or 1, not true or false values */
774 static int start_element_inserted
= 1;
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
781 #if defined (VA_FPRINTF) && __STDC__
782 xml_insert_element_with_attribute (int elt
, int arg
, char *format
, ...)
784 xml_insert_element_with_attribute (elt
, arg
, format
, va_alist
)
791 /* Look at the replace_elements table to see if we have to change the element */
796 replace_element
*element_list
= replace_elements
;
797 while (element_list
->element_to_replace
>= 0)
799 if ( ( (arg
== START
) &&
800 (element_list
->element_containing
== xml_current_element ()) &&
801 (element_list
->element_to_replace
== elt
) ) ||
803 (element_list
->element_containing
== element_stack
[element_stack_index
-1-start_element_inserted
]) &&
804 (element_list
->element_to_replace
== elt
) ) )
806 elt
= element_list
->element_replacing
;
812 /* Forget the element */
816 start_element_inserted
= 0;
818 /* Replace the default value, for the next time */
819 start_element_inserted
= 1;
827 if (!xml_dont_touch_items_defs
&& arg
== START
)
829 if (xml_after_table_term
&& elt
!= TABLETERM
&& xml_table_level
830 && !xml_in_item
[xml_table_level
])
832 xml_after_table_term
= 0;
833 xml_insert_element (ITEM
, START
);
834 xml_in_item
[xml_table_level
] = 1;
836 else if (xml_after_def_term
&& elt
!= DEFINITIONTERM
)
838 xml_after_def_term
= 0;
839 xml_insert_element (DEFINITIONITEM
, START
);
840 xml_in_def_item
[xml_definition_level
] = 1;
844 if (docbook
&& !only_macro_expansion
&& (in_menu
|| in_detailmenu
))
847 if (executing_string
&& arg
== END
)
851 xml_in_tableitem
[xml_table_level
] = 0;
854 xml_in_item
[xml_table_level
] = 0;
857 xml_in_def_item
[xml_definition_level
] = 0;
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
864 if (docbook
&& elt
== FLOAT
)
867 xml_push_current_element (elt
);
869 xml_pop_current_element ();
873 if (!xml_element_list
[elt
].name
|| !strlen (xml_element_list
[elt
].name
))
875 /*printf ("Warning: Inserting empty element %d\n", elt);*/
879 if (arg
== START
&& !xml_in_para
&& !xml_no_para
880 && xml_element_list
[elt
].contained_in_para
)
883 if (arg
== START
&& xml_in_para
&& !xml_element_list
[elt
].contained_in_para
)
886 if (arg
== END
&& xml_in_para
&& !xml_element_list
[elt
].contained_in_para
)
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
)
895 xml_insert_element (TITLE
, START
);
898 if (arg
== START
&& !xml_in_para
&& !xml_keep_space
899 && !xml_element_list
[elt
].contained_in_para
)
903 xml_push_current_element (elt
);
905 xml_pop_current_element ();
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
--;
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
--;
918 /* Indent elements that can contain <para>. */
919 if (arg
== END
&& !xml_in_para
&& !xml_keep_space
920 && xml_element_list
[elt
].contains_para
)
923 /* Here are the elements we want indented. These do not contain <para>
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
))))
935 insert_string (xml_element_list
[elt
].name
);
937 /* printf ("%s ", xml_element_list[elt].name);*/
941 char temp_string
[2000]; /* xx no fixed limits */
946 VA_START (ap
, format
);
948 VA_SPRINTF (temp_string
, format
, ap
);
950 sprintf (temp_string
, format
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
);
953 insert_string (temp_string
);
957 if (arg
== START
&& xml_node_id
&& elt
!= NODENAME
)
959 insert_string (" id=\"");
960 insert_string (xml_node_id
);
966 if (xml_element_list
[elt
].keep_space
)
971 insert_string (" xml:space=\"preserve\"");
980 if (!xml_in_para
&& !xml_element_list
[elt
].contained_in_para
981 && xml_element_list
[elt
].contains_para
&& xml_indentation_increment
> 0)
984 xml_just_after_element
= 1;
987 /* See the NOTE before xml_insert_element_with_attribute, for why we
988 use `elt' rather than `element' here. */
990 xml_insert_element (int elt
, int arg
)
992 xml_insert_element_with_attribute (elt
, arg
, NULL
);
996 xml_insert_entity (char *entity_name
)
998 int saved_escape_html
= escape_html
;
1002 if (docbook
&& !only_macro_expansion
&& (in_menu
|| in_detailmenu
))
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
)
1012 escape_html
= saved_escape_html
;
1013 insert_string (entity_name
);
1017 typedef struct _xml_section xml_section
;
1018 struct _xml_section
{
1024 xml_section
*last_section
= NULL
;
1027 xml_begin_node (void)
1029 first_section_opened
= 1;
1030 if (xml_in_abstract
)
1032 xml_insert_element (ABSTRACT
, END
);
1033 xml_in_abstract
= 0;
1035 if (xml_in_bookinfo
)
1037 xml_insert_element (BOOKINFO
, END
);
1038 xml_in_bookinfo
= 0;
1040 if (xml_node_open
&& ! docbook
)
1042 if (xml_node_level
!= -1)
1044 xml_close_sections (xml_node_level
);
1045 xml_node_level
= -1;
1047 xml_insert_element (NODE
, END
);
1049 xml_insert_element (NODE
, START
);
1054 xml_close_sections (int level
)
1056 if (!first_section_opened
)
1058 if (xml_in_abstract
)
1060 xml_insert_element (ABSTRACT
, END
);
1061 xml_in_abstract
= 0;
1063 if (xml_in_bookinfo
)
1065 xml_insert_element (BOOKINFO
, END
);
1066 xml_in_bookinfo
= 0;
1068 first_section_opened
= 1;
1071 while (last_section
&& last_section
->level
>= level
)
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
;
1083 xml_open_section (int level
, char *name
)
1085 xml_section
*sect
= (xml_section
*) xmalloc (sizeof (xml_section
));
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
;
1093 if (xml_node_open
&& xml_node_level
== -1)
1094 xml_node_level
= level
;
1098 xml_start_menu_entry (char *tem
)
1101 discard_until ("* ");
1103 /* The line number was already incremented in reader_loop when we
1104 saw the newline, and discard_until has now incremented again. */
1107 if (xml_in_menu_entry
)
1109 if (xml_in_menu_entry_comment
)
1111 xml_insert_element (MENUCOMMENT
, END
);
1112 xml_in_menu_entry_comment
=0;
1114 xml_insert_element (MENUENTRY
, END
);
1115 xml_in_menu_entry
=0;
1117 xml_insert_element (MENUENTRY
, START
);
1118 xml_in_menu_entry
=1;
1120 xml_insert_element (MENUNODE
, START
);
1121 string
= expansion (tem
, 0);
1123 xml_insert_element (MENUNODE
, END
);
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
);
1135 if (looking_at ("::"))
1136 discard_until (":");
1138 { /* discard the node name */
1139 get_until_in_line (0, ".", &string
);
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
++;
1151 if (xml_in_menu_entry
)
1153 if (xml_in_menu_entry_comment
)
1155 xml_insert_element (MENUCOMMENT
, END
);
1156 xml_in_menu_entry_comment
--;
1158 xml_insert_element (MENUENTRY
, END
);
1159 xml_in_menu_entry
--;
1161 xml_insert_element (MENU
, END
);
1164 static int xml_last_character
;
1167 xml_add_char (int character
)
1171 if (docbook
&& !only_macro_expansion
&& (in_menu
|| in_detailmenu
))
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
)
1179 xml_insert_element (TITLE
, START
);
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
))
1186 if (!xml_in_bookinfo
)
1188 xml_insert_element (BOOKINFO
, START
);
1189 xml_in_bookinfo
= 1;
1191 xml_insert_element (ABSTRACT
, START
);
1192 xml_in_abstract
= 1;
1195 if (!xml_sort_index
&& !xml_in_xref_token
&& !xml_dont_touch_items_defs
)
1197 if (xml_after_table_term
&& xml_table_level
1198 && !xml_in_item
[xml_table_level
])
1200 xml_after_table_term
= 0;
1201 xml_insert_element (ITEM
, START
);
1202 xml_in_item
[xml_table_level
] = 1;
1204 else if (xml_after_def_term
)
1206 xml_after_def_term
= 0;
1207 xml_insert_element (DEFINITIONITEM
, START
);
1208 xml_in_def_item
[xml_definition_level
] = 1;
1212 if (xml_just_after_element
&& !xml_in_para
&& !inhibit_paragraph_indentation
)
1214 if (character
== '\r' || character
== '\n' || character
== '\t' || character
== ' ')
1216 xml_just_after_element
= 0;
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
)
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
)
1229 xml_just_after_element
= 1;
1233 if (xml_in_menu_entry_comment
&& character
== '\n' && xml_last_character
== '\n')
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;
1241 if (xml_in_menu_entry_comment
&& whitespace(character
)
1242 && cr_or_whitespace(xml_last_character
))
1245 if (character
== '\n' && !xml_in_para
&& !inhibit_paragraph_indentation
)
1248 xml_last_character
= character
;
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
)
1256 if (!xml_in_para
&& xml_just_after_element
&& !multitable_active
)
1259 insert (docbook
? '\n' : ' ');
1268 xml_insert_footnote (char *note
)
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;
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
1287 struct quotation_elt
*next
;
1291 static QUOTATION_ELT
*quotation_stack
= NULL
;
1294 xml_insert_quotation (char *type
, int arg
)
1296 int quotation_started
= 0;
1300 QUOTATION_ELT
*new = xmalloc (sizeof (QUOTATION_ELT
));
1301 new->type
= xstrdup (type
);
1302 new->next
= quotation_stack
;
1303 quotation_stack
= new;
1306 type
= quotation_stack
->type
;
1308 /* Make use of special quotation styles of Docbook if we can. */
1309 if (docbook
&& strlen(type
))
1311 /* Let's assume it started. */
1312 quotation_started
= 1;
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
);
1325 /* Didn't find a known quotation type :\ */
1326 quotation_started
= 0;
1329 if (!quotation_started
)
1331 xml_insert_element (QUOTATION
, arg
);
1332 if (strlen(type
) && arg
== START
)
1333 execute_string ("@b{%s:} ", type
);
1338 QUOTATION_ELT
*temp
= quotation_stack
;
1341 quotation_stack
= quotation_stack
->next
;
1347 /* Starting generic docbook floats. Just starts elt with correct label
1348 and id attributes, and inserts title. */
1350 xml_begin_docbook_float (int elt
)
1352 if (current_float_used_title ()) /* in a nested float */
1354 xml_insert_element (elt
, START
); /* just insert the tag */
1359 /* OK, need the title, tag, etc. */
1360 if (elt
== CARTOUCHE
) /* no labels on <sidebar> */
1362 if (strlen (current_float_id ()) == 0)
1363 xml_insert_element (elt
, START
);
1365 xml_insert_element_with_attribute (elt
, START
,
1366 "id=\"%s\"", xml_id (current_float_id ()));
1368 else if (strlen (current_float_id ()) == 0)
1369 xml_insert_element_with_attribute (elt
, START
, "label=\"\"");
1371 xml_insert_element_with_attribute (elt
, START
,
1372 "id=\"%s\" label=\"%s\"", xml_id (current_float_id ()),
1373 current_float_number ());
1375 xml_insert_element (TITLE
, START
);
1376 execute_string ("%s", current_float_title ());
1377 xml_insert_element (TITLE
, END
);
1379 current_float_set_title_used (); /* mark this title, tag, etc used */
1386 xml_begin_table (int type
, char *item_function
)
1393 /*if (docbook)*/ /* 05-08 */
1395 xml_insert_element (TABLE
, START
);
1397 xml_in_tableitem
[xml_table_level
] = 0;
1398 xml_in_item
[xml_table_level
] = 0;
1399 xml_after_table_term
= 0;
1405 xml_insert_element (ITEMIZE
, START
);
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
);
1414 execute_string ("%s", item_function
);
1415 xml_insert_element (ITEMFUNCTION
, END
);
1419 xml_insert_element_with_attribute (ITEMIZE
, START
,
1421 (*item_function
== COMMAND_PREFIX
) ?
1422 &item_function
[1] : item_function
);
1424 xml_in_item
[xml_table_level
] = 0;
1431 xml_end_table (int type
)
1438 if (xml_in_item
[xml_table_level
])
1440 xml_insert_element (ITEM
, END
);
1441 xml_in_item
[xml_table_level
] = 0;
1443 if (xml_in_tableitem
[xml_table_level
])
1445 xml_insert_element (TABLEITEM
, END
);
1446 xml_in_tableitem
[xml_table_level
] = 0;
1448 xml_insert_element (TABLE
, END
);
1449 xml_after_table_term
= 0;
1454 if (xml_in_item
[xml_table_level
])
1456 xml_insert_element (ITEM
, END
);
1457 xml_in_item
[xml_table_level
] = 0;
1459 /* gnat-style manual contains an itemized list without items! */
1462 xml_insert_element (TITLE
, END
);
1465 xml_insert_element (ITEMIZE
, END
);
1472 xml_begin_item (void)
1474 if (xml_in_item
[xml_table_level
])
1475 xml_insert_element (ITEM
, END
);
1477 xml_insert_element (ITEM
, START
);
1478 xml_in_item
[xml_table_level
] = 1;
1482 xml_begin_table_item (void)
1484 if (!xml_after_table_term
)
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
);
1494 xml_insert_element (TITLE
, END
);
1496 xml_insert_element (TABLEITEM
, START
);
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;
1505 xml_continue_table_item (void)
1507 xml_insert_element (TABLETERM
, END
);
1508 xml_after_table_term
= 1;
1509 xml_in_item
[xml_table_level
] = 0;
1513 xml_begin_enumerate (char *enum_arg
)
1516 xml_insert_element_with_attribute (ENUMERATE
, START
, "first=\"%s\"", enum_arg
);
1519 if (isdigit (*enum_arg
))
1521 int enum_val
= atoi (enum_arg
);
1523 /* Have to check the value, not just the first digit. */
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
);
1531 xml_insert_element_with_attribute (ENUMERATE
, START
,
1532 "continuation=\"continues\" numeration=\"arabic\"", NULL
);
1534 else if (isupper (*enum_arg
))
1536 if (enum_arg
[0] == 'A')
1537 xml_insert_element_with_attribute (ENUMERATE
, START
,
1538 "numeration=\"upperalpha\"", NULL
);
1540 xml_insert_element_with_attribute (ENUMERATE
, START
,
1541 "continuation=\"continues\" numeration=\"upperalpha\"", NULL
);
1545 if (enum_arg
[0] == 'a')
1546 xml_insert_element_with_attribute (ENUMERATE
, START
,
1547 "numeration=\"loweralpha\"", NULL
);
1549 xml_insert_element_with_attribute (ENUMERATE
, START
,
1550 "continuation=\"continues\" numeration=\"loweralpha\"", NULL
);
1554 xml_in_item
[xml_table_level
] = 0;
1558 xml_end_enumerate (void)
1560 if (xml_in_item
[xml_table_level
])
1562 xml_insert_element (ITEM
, END
);
1563 xml_in_item
[xml_table_level
] = 0;
1565 xml_insert_element (ENUMERATE
, END
);
1570 xml_insert_text_file (char *name_arg
)
1572 char *fullname
= xmalloc (strlen (name_arg
) + 4 + 1);
1574 strcpy (fullname
, name_arg
);
1575 strcat (fullname
, ".txt");
1576 image_file
= fopen (fullname
, "r");
1580 int save_inhibit_indentation
= inhibit_paragraph_indentation
;
1581 int save_filling_enabled
= filling_enabled
;
1583 xml_insert_element (TEXTOBJECT
, START
);
1584 xml_insert_element (DISPLAY
, START
);
1586 inhibit_paragraph_indentation
= 1;
1587 filling_enabled
= 0;
1588 last_char_was_newline
= 0;
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
1594 while ((ch
= getc (image_file
)) != EOF
)
1597 inhibit_paragraph_indentation
= save_inhibit_indentation
;
1598 filling_enabled
= save_filling_enabled
;
1600 xml_insert_element (DISPLAY
, END
);
1601 xml_insert_element (TEXTOBJECT
, END
);
1603 if (fclose (image_file
) != 0)
1607 warning (_("@image file `%s' unreadable: %s"), fullname
,
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. */
1617 try_docbook_image (const char *name
, const char *ext
, const char *fmt
,
1621 char *fullname
= xmalloc (strlen (name
) + 1 + strlen (ext
) + 1);
1622 sprintf (fullname
, "%s.%s", name
, ext
);
1624 if (force
|| access (fullname
, R_OK
) == 0)
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
);
1640 xml_insert_docbook_image (char *name_arg
)
1643 int elt
= xml_in_para
? INLINEIMAGE
: MEDIAOBJECT
;
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
);
1652 xml_insert_element (elt
, START
);
1654 /* A selected few from http://docbook.org/tdg/en/html/imagedata.html. */
1655 if (try_docbook_image (name_arg
, "eps", "EPS", 0))
1657 if (try_docbook_image (name_arg
, "gif", "GIF", 0))
1659 if (try_docbook_image (name_arg
, "jpg", "JPG", 0))
1661 if (try_docbook_image (name_arg
, "jpeg", "JPEG", 0))
1663 if (try_docbook_image (name_arg
, "pdf", "PDF", 0))
1665 if (try_docbook_image (name_arg
, "png", "PNG", 0))
1667 if (try_docbook_image (name_arg
, "svg", "SVG", 0))
1670 /* If no luck so far, just assume we'll eventually have a jpg. */
1672 try_docbook_image (name_arg
, "jpg", "JPG", 1);
1674 xml_insert_text_file (name_arg
);
1675 xml_insert_element (elt
, END
);
1679 if (elt
== MEDIAOBJECT
)
1680 xml_insert_element (INFORMALFIGURE
, END
);
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 , */
1702 static XML_SYNONYM
**xml_synonyms
= NULL
;
1703 static int xml_synonyms_count
= 0;
1706 xml_insert_indexterm (char *indexterm
, char *index
)
1708 /* @index commands can appear between @item and @itemx, @deffn and @deffnx. */
1711 /* Check to see if we need to do index redirection per @synindex. */
1713 for (i
= 0; i
< xml_synonyms_count
; i
++)
1715 if (STREQ (xml_synonyms
[i
]->from
, index
))
1716 index
= xstrdup (xml_synonyms
[i
]->to
);
1719 xml_dont_touch_items_defs
++;
1720 xml_insert_element_with_attribute (INDEXTERM
, START
, "index=\"%s\"", index
);
1722 execute_string ("%s", indexterm
);
1723 xml_insert_element (INDEXTERM
, END
);
1725 xml_dont_touch_items_defs
--;
1729 char *primary
= NULL
, *secondary
= NULL
;
1730 if (strstr (indexterm
+1, INDEX_SEP
))
1732 primary
= xmalloc (strlen (indexterm
) + 1);
1733 strcpy (primary
, indexterm
);
1734 secondary
= strstr (primary
+1, INDEX_SEP
);
1736 secondary
+= strlen (INDEX_SEP
);
1738 xml_insert_element_with_attribute (INDEXTERM
, START
, "role=\"%s\"", index
);
1740 xml_insert_element (PRIMARY
, START
);
1742 execute_string ("%s", primary
);
1744 execute_string ("%s", indexterm
);
1745 xml_insert_element (PRIMARY
, END
);
1748 xml_insert_element (SECONDARY
, START
);
1749 execute_string ("%s", secondary
);
1750 xml_insert_element (SECONDARY
, END
);
1752 xml_insert_element (INDEXTERM
, END
);
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;
1764 xml_close_indexentry (void)
1769 xml_insert_element (SECONDARYIE
, END
);
1770 xml_insert_element (INDEXENTRY
, END
);
1776 xml_begin_index (void)
1778 typedef struct xml_index_title
{
1779 struct xml_index_title
*next
;
1783 static XML_INDEX_TITLE
*xml_index_titles
= NULL
;
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, ... */
1790 XML_INDEX_TITLE
*new = xmalloc (sizeof (XML_INDEX_TITLE
));
1791 xml_section
*temp
= last_section
;
1793 int l
= output_paragraph_offset
-xml_last_section_output_position
;
1794 char *tmp
= xmalloc (l
+1);
1796 strncpy (tmp
, (char *) output_paragraph
, l
);
1798 /* We remove <SECTION */
1804 /* ... and its label attribute. */
1805 if (strncmp (p
, " label=", 7) == 0)
1812 output_paragraph_offset
= xml_last_section_output_position
;
1813 xml_last_section_output_position
= 0;
1815 xml_pop_current_element (); /* remove section element from elements stack */
1818 last_section
= last_section
->prev
; /* remove section from sections stack */
1825 new->title
= xstrdup (p
);
1826 new->next
= xml_index_titles
;
1827 xml_index_titles
= new;
1831 static int xml_index_titles_reversed
= 0;
1833 if (!xml_index_titles_reversed
)
1835 xml_index_titles
= (XML_INDEX_TITLE
*) reverse_list
1836 ((GENERIC_LIST
*) xml_index_titles
);
1837 xml_index_titles_reversed
= 1;
1840 /* We put <INDEX> */
1841 xml_insert_element (PRINTINDEX
, START
);
1842 if (xml_index_titles
)
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
;
1852 if (xml_index_divisions
)
1854 xml_insert_element (INDEXDIV
, START
);
1861 xml_end_index (void)
1863 xml_close_indexentry ();
1864 if (xml_index_divisions
)
1865 xml_insert_element (INDEXDIV
, END
);
1866 xml_insert_element (PRINTINDEX
, END
);
1870 xml_index_divide (char *entry
)
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];
1878 if (tolower (c
) != last_division_letter
&& isalpha (c
))
1880 last_division_letter
= tolower (c
);
1881 xml_close_indexentry ();
1884 xml_insert_element (INDEXDIV
, END
);
1885 xml_insert_element (INDEXDIV
, START
);
1887 xml_insert_element (TITLE
, START
);
1888 insert (toupper (c
));
1889 xml_insert_element (TITLE
, END
);
1894 xml_insert_indexentry (char *entry
, char *node
)
1896 char *primary
= NULL
, *secondary
;
1897 if (xml_index_divisions
)
1898 xml_index_divide (entry
);
1901 if (strstr (entry
+1, INDEX_SEP
))
1903 primary
= xmalloc (strlen (entry
) + 1);
1904 strcpy (primary
, entry
);
1905 secondary
= strstr (primary
+1, INDEX_SEP
);
1907 secondary
+= strlen (INDEX_SEP
);
1909 if (in_secondary
&& strcmp (primary
, index_primary
) == 0)
1911 xml_insert_element (SECONDARYIE
, END
);
1912 xml_insert_element (SECONDARYIE
, START
);
1913 execute_string ("%s", secondary
);
1917 xml_close_indexentry ();
1918 xml_insert_element (INDEXENTRY
, START
);
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
);
1930 xml_close_indexentry ();
1931 xml_insert_element (INDEXENTRY
, START
);
1933 xml_insert_element (PRIMARYIE
, START
);
1934 execute_string ("%s", entry
);
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. */
1942 extern int print_warnings
;
1943 int save_print_warnings
= print_warnings
;
1945 execute_string ("%cxref{%s}", COMMAND_PREFIX
, xstrdup (node
));
1946 print_warnings
= save_print_warnings
;
1951 strcpy (index_primary
, primary
);
1952 /* xml_insert_element (SECONDARYIE, END);*/
1953 /* *(secondary-1) = ',';*/ /* necessary ? */
1957 xml_insert_element (PRIMARYIE
, END
);
1959 /* xml_insert_element (INDEXENTRY, END); */
1963 xml_synindex (char *from
, char *to
)
1968 for (i
= 0; i
< xml_synonyms_count
; i
++)
1969 if (!xml_synonyms
[i
])
1977 slot
= xml_synonyms_count
;
1978 xml_synonyms_count
++;
1980 xml_synonyms
= (XML_SYNONYM
**) xrealloc (xml_synonyms
,
1981 (xml_synonyms_count
+ 1) * sizeof (XML_SYNONYM
*));
1984 xml_synonyms
[slot
] = xmalloc (sizeof (XML_SYNONYM
));
1985 xml_synonyms
[slot
]->from
= xstrdup (from
);
1986 xml_synonyms
[slot
]->to
= xstrdup (to
);
1993 static int multitable_columns_count
;
1994 static int *multitable_column_widths
;
1997 xml_begin_multitable (int ncolumns
, int *column_widths
)
2002 if (is_in_insertion_of_type (floatenv
))
2003 xml_begin_docbook_float (MULTITABLE
);
2005 xml_insert_element (MULTITABLE
, START
);
2007 multitable_columns_count
= ncolumns
;
2008 multitable_column_widths
= xmalloc (sizeof (int) * ncolumns
);
2009 memcpy (multitable_column_widths
, column_widths
,
2010 sizeof (int) * ncolumns
);
2016 xml_insert_element (MULTITABLE
, START
);
2017 for (i
=0; i
<ncolumns
; i
++)
2019 xml_insert_element (COLSPEC
, START
);
2020 add_word_args ("%d", column_widths
[i
]);
2021 xml_insert_element (COLSPEC
, END
);
2028 xml_begin_multitable_group (void)
2032 xml_insert_element_with_attribute (TGROUP
, START
, "cols=\"%d\"",
2033 multitable_columns_count
);
2035 for (i
=0; i
< multitable_columns_count
; i
++)
2037 xml_insert_element_with_attribute (COLSPEC
, START
,
2038 "colwidth=\"%d*\"", multitable_column_widths
[i
]);
2039 xml_insert_element (COLSPEC
, END
);
2044 xml_end_multitable_row (int first_row
)
2048 xml_insert_element (ENTRY
, END
);
2049 xml_insert_element (ROW
, END
);
2057 xml_insert_element (THEAD
, END
);
2059 xml_insert_element (TBODY
, END
);
2060 xml_insert_element (TGROUP
, END
);
2063 xml_begin_multitable_group ();
2064 xml_insert_element (THEAD
, START
);
2068 xml_begin_multitable_group ();
2069 xml_insert_element (TBODY
, START
);
2071 else if (after_headitem
)
2073 xml_insert_element (THEAD
, END
);
2074 xml_insert_element (TBODY
, START
);
2077 xml_insert_element (TBODY
, START
);
2079 xml_insert_element (ROW
, START
);
2080 xml_insert_element (ENTRY
, START
);
2084 xml_end_multitable_column (void)
2086 xml_insert_element (ENTRY
, END
);
2087 xml_insert_element (ENTRY
, START
);
2091 xml_end_multitable (void)
2093 xml_insert_element (ENTRY
, END
);
2094 xml_insert_element (ROW
, END
);
2099 warning (_("@headitem as the last item of @multitable produces invalid Docbook documents"));
2100 xml_insert_element (THEAD
, END
);
2103 xml_insert_element (TBODY
, END
);
2106 xml_insert_element (TGROUP
, END
);
2108 xml_insert_element (MULTITABLE
, END
);
2113 * Parameters in @def definitions
2116 #define DEFUN_SELF_DELIMITING(c) \
2117 ((c) == '(' || (c) == ')' || (c) == '[' || (c) == ']')
2120 xml_process_defun_args (char **defun_args
, int auto_var_p
)
2122 int pending_space
= 0;
2123 int just_after_paramtype
= 0;
2127 char *defun_arg
= *defun_args
++;
2129 if (defun_arg
== NULL
)
2132 if (defun_arg
[0] == ' ')
2144 if (DEFUN_SELF_DELIMITING (defun_arg
[0]))
2146 xml_insert_element (DEFDELIMITER
, START
);
2147 add_char (defun_arg
[0]);
2148 xml_insert_element (DEFDELIMITER
, END
);
2149 just_after_paramtype
= 0;
2151 else if (defun_arg
[0] == '&')
2153 xml_insert_element (DEFPARAM
, START
);
2154 add_word (defun_arg
);
2155 xml_insert_element (DEFPARAM
, END
);
2156 just_after_paramtype
= 0;
2158 else if (defun_arg
[0] == COMMAND_PREFIX
|| just_after_paramtype
)
2160 xml_insert_element (DEFPARAM
, START
);
2161 execute_string ("%s", defun_arg
);
2162 xml_insert_element (DEFPARAM
, END
);
2163 just_after_paramtype
= 0;
2165 else if (defun_arg
[0] == ',' || defun_arg
[0] == ';')
2167 xml_insert_element (DEFDELIMITER
, START
);
2168 add_word (defun_arg
);
2169 xml_insert_element (DEFDELIMITER
, END
);
2170 just_after_paramtype
= 0;
2172 else if (auto_var_p
)
2174 xml_insert_element (DEFPARAM
, START
);
2175 add_word (defun_arg
);
2176 xml_insert_element (DEFPARAM
, END
);
2177 just_after_paramtype
= 0;
2181 xml_insert_element (DEFPARAMTYPE
, START
);
2182 add_word (defun_arg
);
2183 xml_insert_element (DEFPARAMTYPE
, END
);
2184 just_after_paramtype
= 1;
2190 xml_begin_definition (void)
2192 xml_insert_element (DEFINITION
, START
);
2193 xml_definition_level
++;
2194 xml_in_def_item
[xml_definition_level
] = 0;
2198 xml_end_definition (void)
2200 if (xml_in_def_item
[xml_definition_level
])
2202 xml_insert_element (DEFINITIONITEM
, END
);
2203 xml_in_def_item
[xml_definition_level
] = 0;
2205 xml_after_def_term
= 0;
2206 xml_insert_element (DEFINITION
, END
);
2207 xml_definition_level
--;
2211 xml_begin_def_term (int base_type
, const char *category
,
2212 char *defined_name
, char *type_name
, char *type_name2
)
2214 xml_after_def_term
= 0;
2215 xml_insert_element (DEFINITIONTERM
, START
);
2222 execute_string ("@findex %s\n", defined_name
);
2227 execute_string ("@vindex %s\n", defined_name
);
2231 execute_string ("@vindex %s %s %s\n", defined_name
, _("of"), type_name
);
2236 execute_string ("@findex %s %s %s\n", defined_name
, _("on"), type_name
);
2239 execute_string ("@tindex %s\n", defined_name
);
2243 /* Start with category. */
2244 xml_insert_element (DEFCATEGORY
, START
);
2245 execute_string (docbook
? "--- %s:" : "%s", category
);
2246 xml_insert_element (DEFCATEGORY
, END
);
2249 /* Output type name first for typed definitions. */
2259 xml_insert_element (DEFTYPE
, START
);
2260 execute_string ("%s", type_name
);
2261 xml_insert_element (DEFTYPE
, END
);
2269 xml_insert_element (DEFTYPE
, START
);
2270 execute_string ("%s", type_name2
);
2271 xml_insert_element (DEFTYPE
, END
);
2276 xml_insert_element (DEFCLASS
, START
);
2277 execute_string ("%s", type_name
);
2278 xml_insert_element (DEFCLASS
, END
);
2283 /* Categorize rest of the definitions. */
2288 xml_insert_element (DEFFUNCTION
, START
);
2289 execute_string ("%s", defined_name
);
2290 xml_insert_element (DEFFUNCTION
, END
);
2295 xml_insert_element (DEFVARIABLE
, START
);
2296 execute_string ("%s", defined_name
);
2297 xml_insert_element (DEFVARIABLE
, END
);
2301 xml_insert_element (DEFDATATYPE
, START
);
2302 execute_string ("%s", defined_name
);
2303 xml_insert_element (DEFDATATYPE
, END
);
2309 xml_insert_element (DEFCLASSVAR
, START
);
2310 execute_string ("%s", defined_name
);
2311 xml_insert_element (DEFCLASSVAR
, END
);
2317 /* Operation / Method */
2318 xml_insert_element (DEFOPERATION
, START
);
2319 execute_string ("%s", defined_name
);
2320 xml_insert_element (DEFOPERATION
, END
);
2326 xml_end_def_term (void)
2328 xml_insert_element (DEFINITIONTERM
, END
);
2329 xml_after_def_term
= 1;