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