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