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