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