xml.c 62 KB

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