1104964Sjeff/* xml.c -- xml output. 2104964Sjeff $Id: xml.c,v 1.52 2004/12/19 17:02:23 karl Exp $ 3104964Sjeff 4104964Sjeff Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. 5104964Sjeff 6104964Sjeff This program is free software; you can redistribute it and/or modify 7104964Sjeff it under the terms of the GNU General Public License as published by 8104964Sjeff the Free Software Foundation; either version 2, or (at your option) 9104964Sjeff any later version. 10104964Sjeff 11104964Sjeff This program is distributed in the hope that it will be useful, 12104964Sjeff but WITHOUT ANY WARRANTY; without even the implied warranty of 13104964Sjeff MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14104964Sjeff GNU General Public License for more details. 15104964Sjeff 16104964Sjeff You should have received a copy of the GNU General Public License 17104964Sjeff along with this program; if not, write to the Free Software 18104964Sjeff Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19104964Sjeff 20104964Sjeff Originally written by Philippe Martin <feloy@free.fr>. */ 21104964Sjeff 22104964Sjeff#include "system.h" 23104964Sjeff#include "makeinfo.h" 24104964Sjeff#include "insertion.h" 25104964Sjeff#include "files.h" 26104964Sjeff#include "float.h" 27104964Sjeff#include "macro.h" 28104964Sjeff#include "cmds.h" 29104964Sjeff#include "lang.h" 30104964Sjeff 31104964Sjeff#include "xml.h" 32104964Sjeff 33104964Sjeff/* Options */ 34125287Sjeffint xml_index_divisions = 1; 35125287Sjeff 36125287Sjefftypedef struct _element 37125287Sjeff{ 38125287Sjeff char name[32]; 39125287Sjeff int contains_para; 40104964Sjeff int contained_in_para; 41125287Sjeff int keep_space; 42104964Sjeff} element; 43104964Sjeff 44104964Sjeffelement texinfoml_element_list [] = { 45113355Sjeff { "texinfo", 1, 0, 0 }, 46113355Sjeff { "setfilename", 0, 0, 0 }, 47113355Sjeff { "titlefont", 0, 0, 0 }, 48132372Sjulian { "settitle", 0, 0, 0 }, 49134791Sjulian { "documentdescription", 1, 0, 0 }, 50113355Sjeff 51104964Sjeff { "node", 1, 0, 0 }, 52104964Sjeff { "nodenext", 0, 0, 0 }, 53104964Sjeff { "nodeprev", 0, 0, 0 }, 54104964Sjeff { "nodeup", 0, 0, 0 }, 55113355Sjeff 56132372Sjulian { "chapter", 1, 0, 0 }, 57132372Sjulian { "section", 1, 0, 0 }, 58130551Sjulian { "subsection", 1, 0, 0 }, 59104964Sjeff { "subsubsection", 1, 0, 0 }, 60104964Sjeff 61122036Sjeff { "top", 1, 0, 0 }, 62122036Sjeff { "unnumbered", 1, 0, 0 }, 63104964Sjeff { "unnumberedsec", 1, 0, 0 }, 64113355Sjeff { "unnumberedsubsec", 1, 0, 0 }, 65113355Sjeff { "unnumberedsubsubsec", 1, 0, 0 }, 66122036Sjeff 67113355Sjeff { "appendix", 1, 0, 0 }, 68139453Sjhb { "appendixsec", 1, 0, 0 }, 69126326Sjhb { "appendixsubsec", 1, 0, 0 }, 70135051Sjulian { "appendixsubsubsec", 1, 0, 0 }, 71139453Sjhb 72113355Sjeff { "majorheading", 0, 0, 0 }, 73104964Sjeff { "chapheading", 0, 0, 0 }, 74104964Sjeff { "heading", 0, 0, 0 }, 75104964Sjeff { "subheading", 0, 0, 0 }, 76122036Sjeff { "subsubheading", 0, 0, 0 }, 77104964Sjeff 78134586Sjulian { "titlepage", 1, 0, 0 }, 79121127Sjeff { "author", 0, 0, 0 }, 80121127Sjeff { "booktitle", 0, 0, 0 }, 81159570Sdavidxu { "booksubtitle", 0, 0, 0 }, 82104964Sjeff 83107126Sjeff { "menu", 1, 0, 0 }, 84122036Sjeff { "detailmenu", 1, 0, 0 }, 85122036Sjeff { "menuentry", 0, 0, 0 }, 86107137Sjeff { "menutitle", 0, 0, 0 }, 87122036Sjeff { "menucomment", 0, 0, 0 }, 88135076Sscottl { "menunode", 0, 0, 0 }, 89122036Sjeff { "nodename", 0, 0, 0 }, 90135076Sscottl 91145256Sjkoshy { "acronym", 0, 1, 0 }, 92107137Sjeff { "acronymword", 0, 1, 0 }, 93122036Sjeff { "acronymdesc", 0, 1, 0 }, 94107126Sjeff 95107126Sjeff { "abbrev", 0, 1, 0 }, 96107126Sjeff { "abbrevword", 0, 1, 0 }, 97107126Sjeff { "abbrevdesc", 0, 1, 0 }, 98107126Sjeff 99107126Sjeff { "tt", 0, 1, 0 }, 100107126Sjeff { "code", 0, 1, 0 }, 101135076Sscottl { "command", 0, 1, 0 }, 102135076Sscottl { "env", 0, 1, 0 }, 103135076Sscottl { "file", 0, 1, 0 }, 104135076Sscottl { "option", 0, 1, 0 }, 105135076Sscottl { "samp", 0, 1, 0 }, 106135076Sscottl { "kbd", 0, 1, 0 }, 107135076Sscottl { "url", 0, 1, 0 }, 108135076Sscottl { "key", 0, 1, 0 }, 109135076Sscottl { "var", 0, 1, 0 }, 110135076Sscottl { "sc", 0, 1, 0 }, 111135076Sscottl { "dfn", 0, 1, 0 }, 112135076Sscottl { "emph", 0, 1, 0 }, 113134791Sjulian { "strong", 0, 1, 0 }, 114134791Sjulian { "cite", 0, 1, 0 }, 115134791Sjulian { "notfixedwidth", 0, 1, 0 }, 116134791Sjulian { "i", 0, 1, 0 }, 117134791Sjulian { "b", 0, 1, 0 }, 118134791Sjulian { "r", 0, 1, 0 }, 119134791Sjulian { "slanted", 0, 1, 0 }, 120134791Sjulian { "sansserif", 0, 1, 0 }, 121135470Sdas 122104964Sjeff { "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 257element 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 468element *xml_element_list = NULL; 469 470 471typedef 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 487replace_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 516int xml_in_menu_entry = 0; 517int xml_in_menu_entry_comment = 0; 518int xml_node_open = 0; 519int xml_node_level = -1; 520int xml_in_para = 0; 521int xml_just_after_element = 0; 522int xml_keep_space = 0; 523 524int xml_no_indent = 0; 525 526int xml_no_para = 0; 527char *xml_node_id = NULL; 528int xml_sort_index = 0; 529 530int xml_in_xref_token = 0; 531int xml_in_bookinfo = 0; 532int xml_in_book_title = 0; 533int 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. */ 537int 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. */ 541static int xml_in_footnote = 0; 542 543static int xml_after_table_term = 0; 544static int book_started = 0; 545static int first_section_opened = 0; 546 547static int xml_in_tableitem[256]; 548static int xml_in_item[256]; 549static int xml_table_level = 0; 550 551static int xml_in_def_item[256]; 552static int xml_definition_level = 0; 553int xml_after_def_term = 0; 554 555static int in_table_title = 0; 556 557static int in_indexentry = 0; 558static int in_secondary = 0; 559static int in_indexterm = 0; 560 561char * 562xml_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 582int 583xml_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 595void 596xml_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/* */ 654static int element_stack[256]; 655static int element_stack_index = 0; 656 657static int 658xml_current_element (void) 659{ 660 return element_stack[element_stack_index-1]; 661} 662 663static void 664xml_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 673static void 674xml_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 683int 684xml_current_stack_index (void) 685{ 686 return element_stack_index; 687} 688 689void 690xml_end_current_element (void) 691{ 692 xml_insert_element (xml_current_element (), END); 693} 694 695static void 696xml_indent (void) 697{ 698 if (xml_indentation_increment > 0) 699 { 700 int i; 701 if (output_paragraph[output_paragraph_offset-1] != '\n') 702 insert ('\n'); 703 for (i = 0; i < element_stack_index * xml_indentation_increment; i++) 704 insert (' '); 705 } 706} 707 708void 709xml_start_para (void) 710{ 711 if (xml_in_para || xml_in_footnote 712 || !xml_element_list[xml_current_element()].contains_para) 713 return; 714 715 while (output_paragraph[output_paragraph_offset-1] == '\n') 716 output_paragraph_offset--; 717 xml_indent (); 718 719 insert_string ("<para"); 720 if (xml_no_indent) 721 insert_string (" role=\"continues\""); 722 insert_string (">"); 723 xml_no_indent = 0; 724 xml_in_para = 1; 725} 726 727void 728xml_end_para (void) 729{ 730 if (!xml_in_para || xml_in_footnote) 731 return; 732 733 while (cr_or_whitespace(output_paragraph[output_paragraph_offset-1])) 734 output_paragraph_offset--; 735 736 insert_string ("</para>"); 737 if (xml_indentation_increment > 0) 738 insert ('\n'); 739 xml_in_para = 0; 740} 741 742void 743xml_end_document (void) 744{ 745 if (xml_node_open) 746 { 747 if (xml_node_level != -1) 748 { 749 xml_close_sections (xml_node_level); 750 xml_node_level = -1; 751 } 752 xml_insert_element (NODE, END); 753 } 754 else 755 xml_close_sections (xml_node_level); 756 757 xml_insert_element (TEXINFO, END); 758 if (xml_indentation_increment == 0) 759 insert ('\n'); 760 insert_string ("<!-- Keep this comment at the end of the file\n\ 761Local variables:\n\ 762mode: sgml\n\ 763sgml-indent-step:1\n\ 764sgml-indent-data:nil\n\ 765End:\n\ 766-->\n"); 767 if (element_stack_index != 0) 768 error ("Element stack index : %d\n", element_stack_index); 769} 770 771/* MUST be 0 or 1, not true or false values */ 772static int start_element_inserted = 1; 773 774/* NOTE: We use `elt' rather than `element' in the argument list of 775 the next function, since otherwise the Solaris SUNWspro compiler 776 barfs because `element' is a typedef declared near the beginning of 777 this file. */ 778void 779#if defined (VA_FPRINTF) && __STDC__ 780xml_insert_element_with_attribute (int elt, int arg, char *format, ...) 781#else 782xml_insert_element_with_attribute (elt, arg, format, va_alist) 783 int elt; 784 int arg; 785 char *format; 786 va_dcl 787#endif 788{ 789 /* Look at the replace_elements table to see if we have to change the element */ 790 if (xml_sort_index) 791 return; 792 if (docbook) 793 { 794 replace_element *element_list = replace_elements; 795 while (element_list->element_to_replace >= 0) 796 { 797 if ( ( (arg == START) && 798 (element_list->element_containing == xml_current_element ()) && 799 (element_list->element_to_replace == elt) ) || 800 ( (arg == END) && 801 (element_list->element_containing == element_stack[element_stack_index-1-start_element_inserted]) && 802 (element_list->element_to_replace == elt) ) ) 803 { 804 elt = element_list->element_replacing; 805 break; 806 } 807 element_list ++; 808 } 809 810 /* Forget the element */ 811 if (elt < 0) 812 { 813 if (arg == START) 814 start_element_inserted = 0; 815 else 816 /* Replace the default value, for the next time */ 817 start_element_inserted = 1; 818 return; 819 } 820 } 821 822 if (!book_started) 823 return; 824 825 if (!xml_dont_touch_items_defs && arg == START) 826 { 827 if (xml_after_table_term && elt != TABLETERM && xml_table_level 828 && !xml_in_item[xml_table_level]) 829 { 830 xml_after_table_term = 0; 831 xml_insert_element (ITEM, START); 832 xml_in_item[xml_table_level] = 1; 833 } 834 else if (xml_after_def_term && elt != DEFINITIONTERM) 835 { 836 xml_after_def_term = 0; 837 xml_insert_element (DEFINITIONITEM, START); 838 xml_in_def_item[xml_definition_level] = 1; 839 } 840 } 841 842 if (docbook && !only_macro_expansion && (in_menu || in_detailmenu)) 843 return; 844 845 if (executing_string && arg == END) 846 switch (elt) 847 { 848 case TABLEITEM: 849 xml_in_tableitem[xml_table_level] = 0; 850 break; 851 case ITEM: 852 xml_in_item[xml_table_level] = 0; 853 break; 854 case DEFINITIONTERM: 855 xml_in_def_item[xml_definition_level] = 0; 856 break; 857 } 858 859 /* We are special-casing FIGURE element for docbook. It does appear in 860 the tag stack, but not in the output. This is to make element replacement 861 work beautifully. */ 862 if (docbook && elt == FLOAT) 863 { 864 if (arg == START) 865 xml_push_current_element (elt); 866 else 867 xml_pop_current_element (); 868 return; 869 } 870 871 if (!xml_element_list[elt].name || !strlen (xml_element_list[elt].name)) 872 { 873 /*printf ("Warning: Inserting empty element %d\n", elt);*/ 874 return; 875 } 876 877 if (arg == START && !xml_in_para && !xml_no_para 878 && xml_element_list[elt].contained_in_para) 879 xml_start_para (); 880 881 if (arg == START && xml_in_para && !xml_element_list[elt].contained_in_para) 882 xml_end_para (); 883 884 if (arg == END && xml_in_para && !xml_element_list[elt].contained_in_para) 885 xml_end_para (); 886 887 if (docbook && xml_table_level && !in_table_title 888 && !xml_in_tableitem[xml_table_level] && !xml_in_item[xml_table_level] 889 && arg == START && elt != TABLEITEM && elt != TABLETERM 890 && !in_indexterm && xml_current_element() == TABLE) 891 { 892 in_table_title = 1; 893 xml_insert_element (TITLE, START); 894 } 895 896 if (arg == START && !xml_in_para && !xml_keep_space 897 && !xml_element_list[elt].contained_in_para) 898 xml_indent (); 899 900 if (arg == START) 901 xml_push_current_element (elt); 902 else 903 xml_pop_current_element (); 904 905 /* Eat one newline before </example> and the like. */ 906 if (!docbook && arg == END 907 && (xml_element_list[elt].keep_space || elt == GROUP) 908 && output_paragraph[output_paragraph_offset-1] == '\n') 909 output_paragraph_offset--; 910 911 /* And eat whitespace before </entry> in @multitables. */ 912 if (arg == END && elt == ENTRY) 913 while (cr_or_whitespace(output_paragraph[output_paragraph_offset-1])) 914 output_paragraph_offset--; 915 916 /* Indent elements that can contain <para>. */ 917 if (arg == END && !xml_in_para && !xml_keep_space 918 && xml_element_list[elt].contains_para) 919 xml_indent (); 920 921 /* Here are the elements we want indented. These do not contain <para> 922 directly. */ 923 if (arg == END && (elt == MENUENTRY || elt == ITEMIZE || elt == ENUMERATE 924 || elt == TABLEITEM || elt == TABLE 925 || elt == MULTITABLE || elt == TGROUP || elt == THEAD || elt == TBODY 926 || elt == ROW || elt == INFORMALFIGURE 927 || (!docbook && (elt == DEFINITION || elt == DEFINITIONTERM)))) 928 xml_indent (); 929 930 insert ('<'); 931 if (arg == END) 932 insert ('/'); 933 insert_string (xml_element_list[elt].name); 934 935 /* printf ("%s ", xml_element_list[elt].name);*/ 936 937 if (format) 938 { 939 char temp_string[2000]; /* xx no fixed limits */ 940#ifdef VA_SPRINTF 941 va_list ap; 942#endif 943 944 VA_START (ap, format); 945#ifdef VA_SPRINTF 946 VA_SPRINTF (temp_string, format, ap); 947#else 948 sprintf (temp_string, format, a1, a2, a3, a4, a5, a6, a7, a8); 949#endif 950 insert (' '); 951 insert_string (temp_string); 952 va_end (ap); 953 } 954 955 if (arg == START && xml_node_id && elt != NODENAME) 956 { 957 insert_string (" id=\""); 958 insert_string (xml_node_id); 959 insert ('"'); 960 free (xml_node_id); 961 xml_node_id = NULL; 962 } 963 964 if (xml_element_list[elt].keep_space) 965 { 966 if (arg == START) 967 { 968 if (!docbook) 969 insert_string (" xml:space=\"preserve\""); 970 xml_keep_space++; 971 } 972 else 973 xml_keep_space--; 974 } 975 976 insert ('>'); 977 978 if (!xml_in_para && !xml_element_list[elt].contained_in_para 979 && xml_element_list[elt].contains_para && xml_indentation_increment > 0) 980 insert ('\n'); 981 982 xml_just_after_element = 1; 983} 984 985/* See the NOTE before xml_insert_element_with_attribute, for why we 986 use `elt' rather than `element' here. */ 987void 988xml_insert_element (int elt, int arg) 989{ 990 xml_insert_element_with_attribute (elt, arg, NULL); 991} 992 993void 994xml_insert_entity (char *entity_name) 995{ 996 int saved_escape_html = escape_html; 997 998 if (!book_started) 999 return; 1000 if (docbook && !only_macro_expansion && (in_menu || in_detailmenu)) 1001 return; 1002 1003 if (!xml_in_para && !xml_no_para && !only_macro_expansion 1004 && xml_element_list[xml_current_element ()].contains_para 1005 && !in_fixed_width_font) 1006 xml_start_para (); 1007 1008 escape_html = 0; 1009 add_char ('&'); 1010 escape_html = saved_escape_html; 1011 insert_string (entity_name); 1012 add_char (';'); 1013} 1014 1015typedef struct _xml_section xml_section; 1016struct _xml_section { 1017 int level; 1018 char *name; 1019 xml_section *prev; 1020}; 1021 1022xml_section *last_section = NULL; 1023 1024void 1025xml_begin_node (void) 1026{ 1027 first_section_opened = 1; 1028 if (xml_in_abstract) 1029 { 1030 xml_insert_element (ABSTRACT, END); 1031 xml_in_abstract = 0; 1032 } 1033 if (xml_in_bookinfo) 1034 { 1035 xml_insert_element (BOOKINFO, END); 1036 xml_in_bookinfo = 0; 1037 } 1038 if (xml_node_open && ! docbook) 1039 { 1040 if (xml_node_level != -1) 1041 { 1042 xml_close_sections (xml_node_level); 1043 xml_node_level = -1; 1044 } 1045 xml_insert_element (NODE, END); 1046 } 1047 xml_insert_element (NODE, START); 1048 xml_node_open = 1; 1049} 1050 1051void 1052xml_close_sections (int level) 1053{ 1054 if (!first_section_opened) 1055 { 1056 if (xml_in_abstract) 1057 { 1058 xml_insert_element (ABSTRACT, END); 1059 xml_in_abstract = 0; 1060 } 1061 if (xml_in_bookinfo) 1062 { 1063 xml_insert_element (BOOKINFO, END); 1064 xml_in_bookinfo = 0; 1065 } 1066 first_section_opened = 1; 1067 } 1068 1069 while (last_section && last_section->level >= level) 1070 { 1071 xml_section *temp = last_section; 1072 xml_insert_element (xml_element(last_section->name), END); 1073 temp = last_section; 1074 last_section = last_section->prev; 1075 free (temp->name); 1076 free (temp); 1077 } 1078} 1079 1080void 1081xml_open_section (int level, char *name) 1082{ 1083 xml_section *sect = (xml_section *) xmalloc (sizeof (xml_section)); 1084 1085 sect->level = level; 1086 sect->name = xmalloc (1 + strlen (name)); 1087 strcpy (sect->name, name); 1088 sect->prev = last_section; 1089 last_section = sect; 1090 1091 if (xml_node_open && xml_node_level == -1) 1092 xml_node_level = level; 1093} 1094 1095void 1096xml_start_menu_entry (char *tem) 1097{ 1098 char *string; 1099 discard_until ("* "); 1100 1101 /* The line number was already incremented in reader_loop when we 1102 saw the newline, and discard_until has now incremented again. */ 1103 line_number--; 1104 1105 if (xml_in_menu_entry) 1106 { 1107 if (xml_in_menu_entry_comment) 1108 { 1109 xml_insert_element (MENUCOMMENT, END); 1110 xml_in_menu_entry_comment=0; 1111 } 1112 xml_insert_element (MENUENTRY, END); 1113 xml_in_menu_entry=0; 1114 } 1115 xml_insert_element (MENUENTRY, START); 1116 xml_in_menu_entry=1; 1117 1118 xml_insert_element (MENUNODE, START); 1119 string = expansion (tem, 0); 1120 add_word (string); 1121 xml_insert_element (MENUNODE, END); 1122 free (string); 1123 1124 /* The menu item may use macros, so expand them now. */ 1125 xml_insert_element (MENUTITLE, START); 1126 only_macro_expansion++; 1127 get_until_in_line (1, ":", &string); 1128 only_macro_expansion--; 1129 execute_string ("%s", string); /* get escaping done */ 1130 xml_insert_element (MENUTITLE, END); 1131 free (string); 1132 1133 if (looking_at ("::")) 1134 discard_until (":"); 1135 else 1136 { /* discard the node name */ 1137 get_until_in_line (0, ".", &string); 1138 free (string); 1139 } 1140 input_text_offset++; /* discard the second colon or the period */ 1141 skip_whitespace_and_newlines(); 1142 xml_insert_element (MENUCOMMENT, START); 1143 xml_in_menu_entry_comment ++; 1144} 1145 1146void 1147xml_end_menu (void) 1148{ 1149 if (xml_in_menu_entry) 1150 { 1151 if (xml_in_menu_entry_comment) 1152 { 1153 xml_insert_element (MENUCOMMENT, END); 1154 xml_in_menu_entry_comment --; 1155 } 1156 xml_insert_element (MENUENTRY, END); 1157 xml_in_menu_entry--; 1158 } 1159 xml_insert_element (MENU, END); 1160} 1161 1162static int xml_last_character; 1163 1164void 1165xml_add_char (int character) 1166{ 1167 if (!book_started) 1168 return; 1169 if (docbook && !only_macro_expansion && (in_menu || in_detailmenu)) 1170 return; 1171 1172 if (docbook && xml_table_level && !in_table_title 1173 && !xml_in_item[xml_table_level] && !xml_in_tableitem[xml_table_level] 1174 && !cr_or_whitespace (character) && !in_indexterm) 1175 { 1176 in_table_title = 1; 1177 xml_insert_element (TITLE, START); 1178 } 1179 1180 if (!first_section_opened && !xml_in_abstract && !xml_in_book_title 1181 && !xml_no_para && character != '\r' && character != '\n' 1182 && character != ' ' && !is_in_insertion_of_type (copying)) 1183 { 1184 if (!xml_in_bookinfo) 1185 { 1186 xml_insert_element (BOOKINFO, START); 1187 xml_in_bookinfo = 1; 1188 } 1189 xml_insert_element (ABSTRACT, START); 1190 xml_in_abstract = 1; 1191 } 1192 1193 if (!xml_sort_index && !xml_in_xref_token && !xml_dont_touch_items_defs) 1194 { 1195 if (xml_after_table_term && xml_table_level 1196 && !xml_in_item[xml_table_level]) 1197 { 1198 xml_after_table_term = 0; 1199 xml_insert_element (ITEM, START); 1200 xml_in_item[xml_table_level] = 1; 1201 } 1202 else if (xml_after_def_term) 1203 { 1204 xml_after_def_term = 0; 1205 xml_insert_element (DEFINITIONITEM, START); 1206 xml_in_def_item[xml_definition_level] = 1; 1207 } 1208 } 1209 1210 if (xml_just_after_element && !xml_in_para && !inhibit_paragraph_indentation) 1211 { 1212 if (character == '\r' || character == '\n' || character == '\t' || character == ' ') 1213 return; 1214 xml_just_after_element = 0; 1215 } 1216 1217 if (xml_element_list[xml_current_element()].contains_para 1218 && !xml_in_para && !only_macro_expansion && !xml_no_para 1219 && !cr_or_whitespace (character) && !in_fixed_width_font) 1220 xml_start_para (); 1221 1222 if (xml_in_para && character == '\n' && xml_last_character == '\n' 1223 && !only_macro_expansion && !xml_no_para 1224 && xml_element_list[xml_current_element()].contains_para ) 1225 { 1226 xml_end_para (); 1227 xml_just_after_element = 1; 1228 return; 1229 } 1230 1231 if (xml_in_menu_entry_comment && character == '\n' && xml_last_character == '\n') 1232 { 1233 xml_insert_element (MENUCOMMENT, END); 1234 xml_in_menu_entry_comment = 0; 1235 xml_insert_element (MENUENTRY, END); 1236 xml_in_menu_entry = 0; 1237 } 1238 1239 if (xml_in_menu_entry_comment && whitespace(character) 1240 && cr_or_whitespace(xml_last_character)) 1241 return; 1242 1243 if (character == '\n' && !xml_in_para && !inhibit_paragraph_indentation) 1244 return; 1245 1246 xml_last_character = character; 1247 1248 if (character == '&' && escape_html) 1249 insert_string ("&"); 1250 else if (character == '<' && escape_html) 1251 insert_string ("<"); 1252 else if (character == '\n' && !xml_keep_space) 1253 { 1254 if (!xml_in_para && xml_just_after_element && !multitable_active) 1255 return; 1256 else 1257 insert (docbook ? '\n' : ' '); 1258 } 1259 else 1260 insert (character); 1261 1262 return; 1263} 1264 1265void 1266xml_insert_footnote (char *note) 1267{ 1268 if (!xml_in_para) 1269 xml_start_para (); 1270 1271 xml_in_footnote = 1; 1272 xml_insert_element (FOOTNOTE, START); 1273 insert_string ("<para>"); 1274 execute_string ("%s", note); 1275 insert_string ("</para>"); 1276 xml_insert_element (FOOTNOTE, END); 1277 xml_in_footnote = 0; 1278} 1279 1280/* We need to keep the quotation stack ourself, because insertion_stack 1281 loses item_function when we are closing the block, so we don't know 1282 what to close then. */ 1283typedef struct quotation_elt 1284{ 1285 struct quotation_elt *next; 1286 char *type; 1287} QUOTATION_ELT; 1288 1289static QUOTATION_ELT *quotation_stack = NULL; 1290 1291void 1292xml_insert_quotation (char *type, int arg) 1293{ 1294 int quotation_started = 0; 1295 1296 if (arg == START) 1297 { 1298 QUOTATION_ELT *new = xmalloc (sizeof (QUOTATION_ELT)); 1299 new->type = xstrdup (type); 1300 new->next = quotation_stack; 1301 quotation_stack = new; 1302 } 1303 else 1304 type = quotation_stack->type; 1305 1306 /* Make use of special quotation styles of Docbook if we can. */ 1307 if (docbook && strlen(type)) 1308 { 1309 /* Let's assume it started. */ 1310 quotation_started = 1; 1311 1312 if (strcasecmp (type, "tip") == 0) 1313 xml_insert_element (TIP, arg); 1314 else if (strcasecmp (type, "note") == 0) 1315 xml_insert_element (NOTE, arg); 1316 else if (strcasecmp (type, "important") == 0) 1317 xml_insert_element (IMPORTANT, arg); 1318 else if (strcasecmp (type, "warning") == 0) 1319 xml_insert_element (WARNING, arg); 1320 else if (strcasecmp (type, "caution") == 0) 1321 xml_insert_element (CAUTION, arg); 1322 else 1323 /* Didn't find a known quotation type :\ */ 1324 quotation_started = 0; 1325 } 1326 1327 if (!quotation_started) 1328 { 1329 xml_insert_element (QUOTATION, arg); 1330 if (strlen(type) && arg == START) 1331 execute_string ("@b{%s:} ", type); 1332 } 1333 1334 if (arg == END) 1335 { 1336 QUOTATION_ELT *temp = quotation_stack; 1337 if (temp == NULL) 1338 return; 1339 quotation_stack = quotation_stack->next; 1340 free(temp->type); 1341 free(temp); 1342 } 1343} 1344 1345/* Starting generic docbook floats. Just starts elt with correct label 1346 and id attributes, and inserts title. */ 1347void 1348xml_begin_docbook_float (int elt) 1349{ 1350 if (current_float_used_title ()) /* in a nested float */ 1351 { 1352 xml_insert_element (elt, START); /* just insert the tag */ 1353 return; 1354 } 1355 1356 1357 /* OK, need the title, tag, etc. */ 1358 if (elt == CARTOUCHE) /* no labels on <sidebar> */ 1359 { 1360 if (strlen (current_float_id ()) == 0) 1361 xml_insert_element (elt, START); 1362 else 1363 xml_insert_element_with_attribute (elt, START, 1364 "id=\"%s\"", xml_id (current_float_id ())); 1365 } 1366 else if (strlen (current_float_id ()) == 0) 1367 xml_insert_element_with_attribute (elt, START, "label=\"\""); 1368 else 1369 xml_insert_element_with_attribute (elt, START, 1370 "id=\"%s\" label=\"%s\"", xml_id (current_float_id ()), 1371 current_float_number ()); 1372 1373 xml_insert_element (TITLE, START); 1374 execute_string ("%s", current_float_title ()); 1375 xml_insert_element (TITLE, END); 1376 1377 current_float_set_title_used (); /* mark this title, tag, etc used */ 1378} 1379 1380/* 1381 * Lists and Tables 1382 */ 1383void 1384xml_begin_table (int type, char *item_function) 1385{ 1386 switch (type) 1387 { 1388 case ftable: 1389 case vtable: 1390 case table: 1391 /*if (docbook)*/ /* 05-08 */ 1392 { 1393 xml_insert_element (TABLE, START); 1394 xml_table_level ++; 1395 xml_in_tableitem[xml_table_level] = 0; 1396 xml_in_item[xml_table_level] = 0; 1397 xml_after_table_term = 0; 1398 } 1399 break; 1400 case itemize: 1401 if (!docbook) 1402 { 1403 xml_insert_element (ITEMIZE, START); 1404 xml_table_level ++; 1405 xml_in_item[xml_table_level] = 0; 1406 xml_insert_element (ITEMFUNCTION, START); 1407 if (*item_function == COMMAND_PREFIX 1408 && item_function[strlen (item_function) - 1] != '}' 1409 && command_needs_braces (item_function + 1)) 1410 execute_string ("%s{}", item_function); 1411 else 1412 execute_string ("%s", item_function); 1413 xml_insert_element (ITEMFUNCTION, END); 1414 } 1415 else 1416 { 1417 xml_insert_element_with_attribute (ITEMIZE, START, 1418 "mark=\"%s\"", 1419 (*item_function == COMMAND_PREFIX) ? 1420 &item_function[1] : item_function); 1421 xml_table_level ++; 1422 xml_in_item[xml_table_level] = 0; 1423 } 1424 break; 1425 } 1426} 1427 1428void 1429xml_end_table (int type) 1430{ 1431 switch (type) 1432 { 1433 case ftable: 1434 case vtable: 1435 case table: 1436 if (xml_in_item[xml_table_level]) 1437 { 1438 xml_insert_element (ITEM, END); 1439 xml_in_item[xml_table_level] = 0; 1440 } 1441 if (xml_in_tableitem[xml_table_level]) 1442 { 1443 xml_insert_element (TABLEITEM, END); 1444 xml_in_tableitem[xml_table_level] = 0; 1445 } 1446 xml_insert_element (TABLE, END); 1447 xml_after_table_term = 0; 1448 xml_table_level --; 1449 1450 break; 1451 case itemize: 1452 if (xml_in_item[xml_table_level]) 1453 { 1454 xml_insert_element (ITEM, END); 1455 xml_in_item[xml_table_level] = 0; 1456 } 1457 /* gnat-style manual contains an itemized list without items! */ 1458 if (in_table_title) 1459 { 1460 xml_insert_element (TITLE, END); 1461 in_table_title = 0; 1462 } 1463 xml_insert_element (ITEMIZE, END); 1464 xml_table_level --; 1465 break; 1466 } 1467} 1468 1469void 1470xml_begin_item (void) 1471{ 1472 if (xml_in_item[xml_table_level]) 1473 xml_insert_element (ITEM, END); 1474 1475 xml_insert_element (ITEM, START); 1476 xml_in_item[xml_table_level] = 1; 1477} 1478 1479void 1480xml_begin_table_item (void) 1481{ 1482 if (!xml_after_table_term) 1483 { 1484 if (xml_in_item[xml_table_level]) 1485 xml_insert_element (ITEM, END); 1486 if (xml_in_tableitem[xml_table_level]) 1487 xml_insert_element (TABLEITEM, END); 1488 1489 if (in_table_title) 1490 { 1491 in_table_title = 0; 1492 xml_insert_element (TITLE, END); 1493 } 1494 xml_insert_element (TABLEITEM, START); 1495 } 1496 xml_insert_element (TABLETERM, START); 1497 xml_in_tableitem[xml_table_level] = 1; 1498 xml_in_item[xml_table_level] = 0; 1499 xml_after_table_term = 0; 1500} 1501 1502void 1503xml_continue_table_item (void) 1504{ 1505 xml_insert_element (TABLETERM, END); 1506 xml_after_table_term = 1; 1507 xml_in_item[xml_table_level] = 0; 1508} 1509 1510void 1511xml_begin_enumerate (char *enum_arg) 1512{ 1513 if (!docbook) 1514 xml_insert_element_with_attribute (ENUMERATE, START, "first=\"%s\"", enum_arg); 1515 else 1516 { 1517 if (isdigit (*enum_arg)) 1518 { 1519 int enum_val = atoi (enum_arg); 1520 1521 /* Have to check the value, not just the first digit. */ 1522 if (enum_val == 0) 1523 xml_insert_element_with_attribute (ENUMERATE, START, 1524 "numeration=\"arabic\" role=\"0\"", NULL); 1525 else if (enum_val == 1) 1526 xml_insert_element_with_attribute (ENUMERATE, START, 1527 "numeration=\"arabic\"", NULL); 1528 else 1529 xml_insert_element_with_attribute (ENUMERATE, START, 1530 "continuation=\"continues\" numeration=\"arabic\"", NULL); 1531 } 1532 else if (isupper (*enum_arg)) 1533 { 1534 if (enum_arg[0] == 'A') 1535 xml_insert_element_with_attribute (ENUMERATE, START, 1536 "numeration=\"upperalpha\"", NULL); 1537 else 1538 xml_insert_element_with_attribute (ENUMERATE, START, 1539 "continuation=\"continues\" numeration=\"upperalpha\"", NULL); 1540 } 1541 else 1542 { 1543 if (enum_arg[0] == 'a') 1544 xml_insert_element_with_attribute (ENUMERATE, START, 1545 "numeration=\"loweralpha\"", NULL); 1546 else 1547 xml_insert_element_with_attribute (ENUMERATE, START, 1548 "continuation=\"continues\" numeration=\"loweralpha\"", NULL); 1549 } 1550 } 1551 xml_table_level ++; 1552 xml_in_item[xml_table_level] = 0; 1553} 1554 1555void 1556xml_end_enumerate (void) 1557{ 1558 if (xml_in_item[xml_table_level]) 1559 { 1560 xml_insert_element (ITEM, END); 1561 xml_in_item[xml_table_level] = 0; 1562 } 1563 xml_insert_element (ENUMERATE, END); 1564 xml_table_level --; 1565} 1566 1567static void 1568xml_insert_text_file (char *name_arg) 1569{ 1570 char *fullname = xmalloc (strlen (name_arg) + 4 + 1); 1571 FILE *image_file; 1572 strcpy (fullname, name_arg); 1573 strcat (fullname, ".txt"); 1574 image_file = fopen (fullname, "r"); 1575 if (image_file) 1576 { 1577 int ch; 1578 int save_inhibit_indentation = inhibit_paragraph_indentation; 1579 int save_filling_enabled = filling_enabled; 1580 1581 xml_insert_element (TEXTOBJECT, START); 1582 xml_insert_element (DISPLAY, START); 1583 1584 inhibit_paragraph_indentation = 1; 1585 filling_enabled = 0; 1586 last_char_was_newline = 0; 1587 1588 /* Maybe we need to remove the final newline if the image 1589 file is only one line to allow in-line images. On the 1590 other hand, they could just make the file without a 1591 final newline. */ 1592 while ((ch = getc (image_file)) != EOF) 1593 add_char (ch); 1594 1595 inhibit_paragraph_indentation = save_inhibit_indentation; 1596 filling_enabled = save_filling_enabled; 1597 1598 xml_insert_element (DISPLAY, END); 1599 xml_insert_element (TEXTOBJECT, END); 1600 1601 if (fclose (image_file) != 0) 1602 perror (fullname); 1603 } 1604 else 1605 warning (_("@image file `%s' unreadable: %s"), fullname, 1606 strerror (errno)); 1607 1608 free (fullname); 1609} 1610 1611/* If NAME.EXT is accessible or FORCE is nonzero, insert a docbook 1612 imagedata element for FMT. Return 1 if inserted something, 0 else. */ 1613 1614static int 1615try_docbook_image (const char *name, const char *ext, const char *fmt, 1616 int force) 1617{ 1618 int used = 0; 1619 char *fullname = xmalloc (strlen (name) + 1 + strlen (ext) + 1); 1620 sprintf (fullname, "%s.%s", name, ext); 1621 1622 if (force || access (fullname, R_OK) == 0) 1623 { 1624 xml_insert_element (IMAGEOBJECT, START); 1625 xml_insert_element_with_attribute (IMAGEDATA, START, 1626 "fileref=\"%s\" format=\"%s\"", fullname, fmt); 1627 xml_insert_element (IMAGEDATA, END); 1628 xml_insert_element (IMAGEOBJECT, END); 1629 used = 1; 1630 } 1631 1632 free (fullname); 1633 return used; 1634} 1635 1636 1637void 1638xml_insert_docbook_image (char *name_arg) 1639{ 1640 int found = 0; 1641 int elt = xml_in_para ? INLINEIMAGE : MEDIAOBJECT; 1642 1643 if (is_in_insertion_of_type (floatenv)) 1644 xml_begin_docbook_float (INFORMALFIGURE); 1645 else if (!xml_in_para) 1646 xml_insert_element (INFORMALFIGURE, START); 1647 1648 xml_no_para++; 1649 1650 xml_insert_element (elt, START); 1651 1652 /* A selected few from http://docbook.org/tdg/en/html/imagedata.html. */ 1653 if (try_docbook_image (name_arg, "eps", "EPS", 0)) 1654 found++; 1655 if (try_docbook_image (name_arg, "gif", "GIF", 0)) 1656 found++; 1657 if (try_docbook_image (name_arg, "jpg", "JPG", 0)) 1658 found++; 1659 if (try_docbook_image (name_arg, "jpeg", "JPEG", 0)) 1660 found++; 1661 if (try_docbook_image (name_arg, "pdf", "PDF", 0)) 1662 found++; 1663 if (try_docbook_image (name_arg, "png", "PNG", 0)) 1664 found++; 1665 if (try_docbook_image (name_arg, "svg", "SVG", 0)) 1666 found++; 1667 1668 /* If no luck so far, just assume we'll eventually have a jpg. */ 1669 if (!found) 1670 try_docbook_image (name_arg, "jpg", "JPG", 1); 1671 1672 xml_insert_text_file (name_arg); 1673 xml_insert_element (elt, END); 1674 1675 xml_no_para--; 1676 1677 if (elt == MEDIAOBJECT) 1678 xml_insert_element (INFORMALFIGURE, END); 1679} 1680 1681void 1682xml_asterisk (void) 1683{ 1684} 1685 1686 1687/* 1688 * INDEX 1689 */ 1690/* Used to separate primary and secondary entries in an index -- we need 1691 to have real multilivel indexing support, not just string analysis. */ 1692#define INDEX_SEP "@this string will never appear@" /* was , */ 1693 1694typedef struct 1695{ 1696 char *from; 1697 char *to; 1698} XML_SYNONYM; 1699 1700static XML_SYNONYM **xml_synonyms = NULL; 1701static int xml_synonyms_count = 0; 1702 1703void 1704xml_insert_indexterm (char *indexterm, char *index) 1705{ 1706 /* @index commands can appear between @item and @itemx, @deffn and @deffnx. */ 1707 if (!docbook) 1708 { 1709 /* Check to see if we need to do index redirection per @synindex. */ 1710 int i; 1711 for (i = 0; i < xml_synonyms_count; i++) 1712 { 1713 if (STREQ (xml_synonyms[i]->from, index)) 1714 index = xstrdup (xml_synonyms[i]->to); 1715 } 1716 1717 xml_dont_touch_items_defs++; 1718 xml_insert_element_with_attribute (INDEXTERM, START, "index=\"%s\"", index); 1719 in_indexterm = 1; 1720 execute_string ("%s", indexterm); 1721 xml_insert_element (INDEXTERM, END); 1722 in_indexterm = 0; 1723 xml_dont_touch_items_defs--; 1724 } 1725 else 1726 { 1727 char *primary = NULL, *secondary = NULL; 1728 if (strstr (indexterm+1, INDEX_SEP)) 1729 { 1730 primary = xmalloc (strlen (indexterm) + 1); 1731 strcpy (primary, indexterm); 1732 secondary = strstr (primary+1, INDEX_SEP); 1733 *secondary = '\0'; 1734 secondary += strlen (INDEX_SEP); 1735 } 1736 xml_insert_element_with_attribute (INDEXTERM, START, "role=\"%s\"", index); 1737 in_indexterm = 1; 1738 xml_insert_element (PRIMARY, START); 1739 if (primary) 1740 execute_string ("%s", primary); 1741 else 1742 execute_string ("%s", indexterm); 1743 xml_insert_element (PRIMARY, END); 1744 if (primary) 1745 { 1746 xml_insert_element (SECONDARY, START); 1747 execute_string ("%s", secondary); 1748 xml_insert_element (SECONDARY, END); 1749 } 1750 xml_insert_element (INDEXTERM, END); 1751 in_indexterm = 0; 1752 } 1753} 1754 1755 1756int xml_last_section_output_position = 0; 1757static char last_division_letter = ' '; 1758static char index_primary[2000]; /** xx no fixed limit */ 1759static int indexdivempty = 0; 1760 1761static void 1762xml_close_indexentry (void) 1763{ 1764 if (!in_indexentry) 1765 return; 1766 if (in_secondary) 1767 xml_insert_element (SECONDARYIE, END); 1768 xml_insert_element (INDEXENTRY, END); 1769 in_secondary = 0; 1770 in_indexentry = 0; 1771} 1772 1773void 1774xml_begin_index (void) 1775{ 1776 typedef struct xml_index_title { 1777 struct xml_index_title *next; 1778 char *title; 1779 } XML_INDEX_TITLE; 1780 1781 static XML_INDEX_TITLE *xml_index_titles = NULL; 1782 1783 if (!handling_delayed_writes) 1784 { /* We assume that we just opened a section, and so that the last output is 1785 <SECTION ID="node-name"><TITLE>Title</TITLE> 1786 where SECTION can be CHAPTER, ... */ 1787 1788 XML_INDEX_TITLE *new = xmalloc (sizeof (XML_INDEX_TITLE)); 1789 xml_section *temp = last_section; 1790 1791 int l = output_paragraph_offset-xml_last_section_output_position; 1792 char *tmp = xmalloc (l+1); 1793 char *p = tmp; 1794 strncpy (tmp, (char *) output_paragraph, l); 1795 1796 /* We remove <SECTION */ 1797 tmp[l] = '\0'; 1798 while (*p != '<') 1799 p++; 1800 while (*p != ' ') 1801 p++; 1802 /* ... and its label attribute. */ 1803 if (strncmp (p, " label=", 7) == 0) 1804 { 1805 p++; 1806 while (*p != ' ') 1807 p++; 1808 } 1809 1810 output_paragraph_offset = xml_last_section_output_position; 1811 xml_last_section_output_position = 0; 1812 1813 xml_pop_current_element (); /* remove section element from elements stack */ 1814 1815 if (last_section) 1816 last_section = last_section->prev; /* remove section from sections stack */ 1817 if (temp) 1818 { 1819 free (temp->name); 1820 free (temp); 1821 } 1822 1823 new->title = xstrdup (p); 1824 new->next = xml_index_titles; 1825 xml_index_titles = new; 1826 } 1827 else 1828 { 1829 static int xml_index_titles_reversed = 0; 1830 1831 if (!xml_index_titles_reversed) 1832 { 1833 xml_index_titles = (XML_INDEX_TITLE *) reverse_list 1834 ((GENERIC_LIST *) xml_index_titles); 1835 xml_index_titles_reversed = 1; 1836 } 1837 1838 /* We put <INDEX> */ 1839 xml_insert_element (PRINTINDEX, START); 1840 if (xml_index_titles) 1841 { 1842 /* Remove the final > */ 1843 output_paragraph_offset--; 1844 /* and put ID="node-name"><TITLE>Title</TITLE> */ 1845 insert_string (xml_index_titles->title); 1846 free (xml_index_titles->title); 1847 xml_index_titles = xml_index_titles->next; 1848 } 1849 1850 if (xml_index_divisions) 1851 { 1852 xml_insert_element (INDEXDIV, START); 1853 indexdivempty = 1; 1854 } 1855 } 1856} 1857 1858void 1859xml_end_index (void) 1860{ 1861 xml_close_indexentry (); 1862 if (xml_index_divisions) 1863 xml_insert_element (INDEXDIV, END); 1864 xml_insert_element (PRINTINDEX, END); 1865} 1866 1867static void 1868xml_index_divide (char *entry) 1869{ 1870 char c; 1871 if (strlen (entry) > (strlen (xml_element_list[CODE].name) + 2) && 1872 strncmp (entry+1, xml_element_list[CODE].name, strlen (xml_element_list[CODE].name)) == 0) 1873 c = entry[strlen (xml_element_list[CODE].name)+2]; 1874 else 1875 c = entry[0]; 1876 if (tolower (c) != last_division_letter && isalpha (c)) 1877 { 1878 last_division_letter = tolower (c); 1879 xml_close_indexentry (); 1880 if (!indexdivempty) 1881 { 1882 xml_insert_element (INDEXDIV, END); 1883 xml_insert_element (INDEXDIV, START); 1884 } 1885 xml_insert_element (TITLE, START); 1886 insert (toupper (c)); 1887 xml_insert_element (TITLE, END); 1888 } 1889} 1890 1891void 1892xml_insert_indexentry (char *entry, char *node) 1893{ 1894 char *primary = NULL, *secondary; 1895 if (xml_index_divisions) 1896 xml_index_divide (entry); 1897 1898 indexdivempty = 0; 1899 if (strstr (entry+1, INDEX_SEP)) 1900 { 1901 primary = xmalloc (strlen (entry) + 1); 1902 strcpy (primary, entry); 1903 secondary = strstr (primary+1, INDEX_SEP); 1904 *secondary = '\0'; 1905 secondary += strlen (INDEX_SEP); 1906 1907 if (in_secondary && strcmp (primary, index_primary) == 0) 1908 { 1909 xml_insert_element (SECONDARYIE, END); 1910 xml_insert_element (SECONDARYIE, START); 1911 execute_string ("%s", secondary); 1912 } 1913 else 1914 { 1915 xml_close_indexentry (); 1916 xml_insert_element (INDEXENTRY, START); 1917 in_indexentry = 1; 1918 xml_insert_element (PRIMARYIE, START); 1919 execute_string ("%s", primary); 1920 xml_insert_element (PRIMARYIE, END); 1921 xml_insert_element (SECONDARYIE, START); 1922 execute_string ("%s", secondary); 1923 in_secondary = 1; 1924 } 1925 } 1926 else 1927 { 1928 xml_close_indexentry (); 1929 xml_insert_element (INDEXENTRY, START); 1930 in_indexentry = 1; 1931 xml_insert_element (PRIMARYIE, START); 1932 execute_string ("%s", entry); 1933 } 1934 add_word (", "); 1935 1936 /* Don't link to @unnumbered sections directly. 1937 We are disabling warnings temporarily, otherwise these xrefs 1938 will cause bogus warnings about missing punctuation. */ 1939 { 1940 extern int print_warnings; 1941 int save_print_warnings = print_warnings; 1942 print_warnings = 0; 1943 execute_string ("%cxref{%s}", COMMAND_PREFIX, xstrdup (node)); 1944 print_warnings = save_print_warnings; 1945 } 1946 1947 if (primary) 1948 { 1949 strcpy (index_primary, primary); 1950 /* xml_insert_element (SECONDARYIE, END);*/ 1951 /* *(secondary-1) = ',';*/ /* necessary ? */ 1952 free (primary); 1953 } 1954 else 1955 xml_insert_element (PRIMARYIE, END); 1956 1957 /* xml_insert_element (INDEXENTRY, END); */ 1958} 1959 1960void 1961xml_synindex (char *from, char *to) 1962{ 1963 int i, slot; 1964 1965 slot = -1; 1966 for (i = 0; i < xml_synonyms_count; i++) 1967 if (!xml_synonyms[i]) 1968 { 1969 slot = i; 1970 break; 1971 } 1972 1973 if (slot < 0) 1974 { 1975 slot = xml_synonyms_count; 1976 xml_synonyms_count++; 1977 1978 xml_synonyms = (XML_SYNONYM **) xrealloc (xml_synonyms, 1979 (xml_synonyms_count + 1) * sizeof (XML_SYNONYM *)); 1980 } 1981 1982 xml_synonyms[slot] = xmalloc (sizeof (XML_SYNONYM)); 1983 xml_synonyms[slot]->from = xstrdup (from); 1984 xml_synonyms[slot]->to = xstrdup (to); 1985} 1986 1987/* 1988 * MULTITABLE 1989 */ 1990 1991static int multitable_columns_count; 1992static int *multitable_column_widths; 1993 1994void 1995xml_begin_multitable (int ncolumns, int *column_widths) 1996{ 1997 int i; 1998 if (docbook) 1999 { 2000 if (is_in_insertion_of_type (floatenv)) 2001 xml_begin_docbook_float (MULTITABLE); 2002 else 2003 xml_insert_element (MULTITABLE, START); 2004 2005 multitable_columns_count = ncolumns; 2006 multitable_column_widths = xmalloc (sizeof (int) * ncolumns); 2007 memcpy (multitable_column_widths, column_widths, 2008 sizeof (int) * ncolumns); 2009 2010 xml_no_para = 1; 2011 } 2012 else 2013 { 2014 xml_insert_element (MULTITABLE, START); 2015 for (i=0; i<ncolumns; i++) 2016 { 2017 xml_insert_element (COLSPEC, START); 2018 add_word_args ("%d", column_widths[i]); 2019 xml_insert_element (COLSPEC, END); 2020 } 2021 xml_no_para = 1; 2022 } 2023} 2024 2025static void 2026xml_begin_multitable_group (void) 2027{ 2028 int i; 2029 2030 xml_insert_element_with_attribute (TGROUP, START, "cols=\"%d\"", 2031 multitable_columns_count); 2032 2033 for (i=0; i < multitable_columns_count; i++) 2034 { 2035 xml_insert_element_with_attribute (COLSPEC, START, 2036 "colwidth=\"%d*\"", multitable_column_widths[i]); 2037 xml_insert_element (COLSPEC, END); 2038 } 2039} 2040 2041void 2042xml_end_multitable_row (int first_row) 2043{ 2044 if (!first_row) 2045 { 2046 xml_insert_element (ENTRY, END); 2047 xml_insert_element (ROW, END); 2048 } 2049 2050 if (headitem_flag) 2051 { 2052 if (!first_row) 2053 { 2054 if (after_headitem) 2055 xml_insert_element (THEAD, END); 2056 else 2057 xml_insert_element (TBODY, END); 2058 xml_insert_element (TGROUP, END); 2059 } 2060 2061 xml_begin_multitable_group (); 2062 xml_insert_element (THEAD, START); 2063 } 2064 else if (first_row) 2065 { 2066 xml_begin_multitable_group (); 2067 xml_insert_element (TBODY, START); 2068 } 2069 else if (after_headitem) 2070 { 2071 xml_insert_element (THEAD, END); 2072 xml_insert_element (TBODY, START); 2073 } 2074 else if (first_row) 2075 xml_insert_element (TBODY, START); 2076 2077 xml_insert_element (ROW, START); 2078 xml_insert_element (ENTRY, START); 2079} 2080 2081void 2082xml_end_multitable_column (void) 2083{ 2084 xml_insert_element (ENTRY, END); 2085 xml_insert_element (ENTRY, START); 2086} 2087 2088void 2089xml_end_multitable (void) 2090{ 2091 xml_insert_element (ENTRY, END); 2092 xml_insert_element (ROW, END); 2093 2094 if (after_headitem) 2095 { 2096 if (docbook) 2097 warning (_("@headitem as the last item of @multitable produces invalid Docbook documents")); 2098 xml_insert_element (THEAD, END); 2099 } 2100 else 2101 xml_insert_element (TBODY, END); 2102 2103 if (docbook) 2104 xml_insert_element (TGROUP, END); 2105 2106 xml_insert_element (MULTITABLE, END); 2107 xml_no_para = 0; 2108} 2109 2110/* 2111 * Parameters in @def definitions 2112 */ 2113 2114#define DEFUN_SELF_DELIMITING(c) \ 2115 ((c) == '(' || (c) == ')' || (c) == '[' || (c) == ']') 2116 2117void 2118xml_process_defun_args (char **defun_args, int auto_var_p) 2119{ 2120 int pending_space = 0; 2121 int just_after_paramtype = 0; 2122 2123 for (;;) 2124 { 2125 char *defun_arg = *defun_args++; 2126 2127 if (defun_arg == NULL) 2128 break; 2129 2130 if (defun_arg[0] == ' ') 2131 { 2132 pending_space = 1; 2133 continue; 2134 } 2135 2136 if (pending_space) 2137 { 2138 add_char (' '); 2139 pending_space = 0; 2140 } 2141 2142 if (DEFUN_SELF_DELIMITING (defun_arg[0])) 2143 { 2144 xml_insert_element (DEFDELIMITER, START); 2145 add_char (defun_arg[0]); 2146 xml_insert_element (DEFDELIMITER, END); 2147 just_after_paramtype = 0; 2148 } 2149 else if (defun_arg[0] == '&') 2150 { 2151 xml_insert_element (DEFPARAM, START); 2152 add_word (defun_arg); 2153 xml_insert_element (DEFPARAM, END); 2154 just_after_paramtype = 0; 2155 } 2156 else if (defun_arg[0] == COMMAND_PREFIX || just_after_paramtype) 2157 { 2158 xml_insert_element (DEFPARAM, START); 2159 execute_string ("%s", defun_arg); 2160 xml_insert_element (DEFPARAM, END); 2161 just_after_paramtype = 0; 2162 } 2163 else if (defun_arg[0] == ',' || defun_arg[0] == ';') 2164 { 2165 xml_insert_element (DEFDELIMITER, START); 2166 add_word (defun_arg); 2167 xml_insert_element (DEFDELIMITER, END); 2168 just_after_paramtype = 0; 2169 } 2170 else if (auto_var_p) 2171 { 2172 xml_insert_element (DEFPARAM, START); 2173 add_word (defun_arg); 2174 xml_insert_element (DEFPARAM, END); 2175 just_after_paramtype = 0; 2176 } 2177 else 2178 { 2179 xml_insert_element (DEFPARAMTYPE, START); 2180 add_word (defun_arg); 2181 xml_insert_element (DEFPARAMTYPE, END); 2182 just_after_paramtype = 1; 2183 } 2184 } 2185} 2186 2187void 2188xml_begin_definition (void) 2189{ 2190 xml_insert_element (DEFINITION, START); 2191 xml_definition_level ++; 2192 xml_in_def_item[xml_definition_level] = 0; 2193} 2194 2195void 2196xml_end_definition (void) 2197{ 2198 if (xml_in_def_item[xml_definition_level]) 2199 { 2200 xml_insert_element (DEFINITIONITEM, END); 2201 xml_in_def_item[xml_definition_level] = 0; 2202 } 2203 xml_after_def_term = 0; 2204 xml_insert_element (DEFINITION, END); 2205 xml_definition_level --; 2206} 2207 2208void 2209xml_begin_def_term (int base_type, const char *category, 2210 char *defined_name, char *type_name, char *type_name2) 2211{ 2212 xml_after_def_term = 0; 2213 xml_insert_element (DEFINITIONTERM, START); 2214 2215 /* Index entry */ 2216 switch (base_type) 2217 { 2218 case deffn: 2219 case deftypefn: 2220 execute_string ("@findex %s\n", defined_name); 2221 break; 2222 case defvr: 2223 case deftypevr: 2224 case defcv: 2225 execute_string ("@vindex %s\n", defined_name); 2226 break; 2227 case deftypecv: 2228 case deftypeivar: 2229 execute_string ("@vindex %s %s %s\n", defined_name, _("of"), type_name); 2230 break; 2231 case deftypemethod: 2232 case defop: 2233 case deftypeop: 2234 execute_string ("@findex %s %s %s\n", defined_name, _("on"), type_name); 2235 break; 2236 case deftp: 2237 execute_string ("@tindex %s\n", defined_name); 2238 break; 2239 } 2240 2241 /* Start with category. */ 2242 xml_insert_element (DEFCATEGORY, START); 2243 execute_string (docbook ? "--- %s:" : "%s", category); 2244 xml_insert_element (DEFCATEGORY, END); 2245 add_char(' '); 2246 2247 /* Output type name first for typed definitions. */ 2248 switch (base_type) 2249 { 2250 case deffn: 2251 case defvr: 2252 case deftp: 2253 break; 2254 2255 case deftypefn: 2256 case deftypevr: 2257 xml_insert_element (DEFTYPE, START); 2258 execute_string ("%s", type_name); 2259 xml_insert_element (DEFTYPE, END); 2260 add_char (' '); 2261 break; 2262 2263 case deftypecv: 2264 case deftypeivar: 2265 case deftypemethod: 2266 case deftypeop: 2267 xml_insert_element (DEFTYPE, START); 2268 execute_string ("%s", type_name2); 2269 xml_insert_element (DEFTYPE, END); 2270 add_char (' '); 2271 break; 2272 2273 default: 2274 xml_insert_element (DEFCLASS, START); 2275 execute_string ("%s", type_name); 2276 xml_insert_element (DEFCLASS, END); 2277 add_char (' '); 2278 break; 2279 } 2280 2281 /* Categorize rest of the definitions. */ 2282 switch (base_type) 2283 { 2284 case deffn: 2285 case deftypefn: 2286 xml_insert_element (DEFFUNCTION, START); 2287 execute_string ("%s", defined_name); 2288 xml_insert_element (DEFFUNCTION, END); 2289 break; 2290 2291 case defvr: 2292 case deftypevr: 2293 xml_insert_element (DEFVARIABLE, START); 2294 execute_string ("%s", defined_name); 2295 xml_insert_element (DEFVARIABLE, END); 2296 break; 2297 2298 case deftp: 2299 xml_insert_element (DEFDATATYPE, START); 2300 execute_string ("%s", defined_name); 2301 xml_insert_element (DEFDATATYPE, END); 2302 break; 2303 2304 case defcv: 2305 case deftypecv: 2306 case deftypeivar: 2307 xml_insert_element (DEFCLASSVAR, START); 2308 execute_string ("%s", defined_name); 2309 xml_insert_element (DEFCLASSVAR, END); 2310 break; 2311 2312 case defop: 2313 case deftypeop: 2314 case deftypemethod: 2315 /* Operation / Method */ 2316 xml_insert_element (DEFOPERATION, START); 2317 execute_string ("%s", defined_name); 2318 xml_insert_element (DEFOPERATION, END); 2319 break; 2320 } 2321} 2322 2323void 2324xml_end_def_term (void) 2325{ 2326 xml_insert_element (DEFINITIONTERM, END); 2327 xml_after_def_term = 1; 2328} 2329