cmds.c 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193
  1. /* cmds.c -- Texinfo commands.
  2. $Id: cmds.c,v 1.86 2009-03-20 18:33:51 karl Exp $
  3. Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
  4. 2007, 2008, 2009 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. #include "system.h"
  16. #include "mbswidth.h"
  17. #include "cmds.h"
  18. #include "defun.h"
  19. #include "files.h"
  20. #include "footnote.h"
  21. #include "html.h"
  22. #include "index.h"
  23. #include "insertion.h"
  24. #include "lang.h"
  25. #include "macro.h"
  26. #include "makeinfo.h"
  27. #include "node.h"
  28. #include "sectioning.h"
  29. #include "toc.h"
  30. #include "xml.h"
  31. #ifdef TM_IN_SYS_TIME
  32. #include <sys/time.h>
  33. #else
  34. #include <time.h>
  35. #endif
  36. /* Simple commands defined and only called here. */
  37. static void cm_exampleindent (void),
  38. cm_firstparagraphindent (void),
  39. cm_fonttextsize (void),
  40. cm_frenchspacing (void),
  41. cm_geq (int arg),
  42. cm_leq (int arg),
  43. cm_minus (int arg),
  44. cm_novalidate (void),
  45. cm_paragraphindent (void);
  46. /* Internals. */
  47. static void cm_obsolete (int arg, int start, int end),
  48. not_fixed_width (int arg);
  49. /* The dispatch table. */
  50. COMMAND command_table[] = {
  51. { "\t", insert_space, NO_BRACE_ARGS },
  52. { "\n", insert_space, NO_BRACE_ARGS },
  53. { " ", insert_space, NO_BRACE_ARGS },
  54. { "!", cm_punct, NO_BRACE_ARGS },
  55. { "\"", cm_accent_umlaut, MAYBE_BRACE_ARGS },
  56. { "'", cm_accent_acute, MAYBE_BRACE_ARGS },
  57. { "*", cm_asterisk, NO_BRACE_ARGS },
  58. { ",", cm_accent_cedilla, MAYBE_BRACE_ARGS },
  59. { "-", cm_no_op, NO_BRACE_ARGS },
  60. { ".", cm_punct, NO_BRACE_ARGS },
  61. { "/", cm_no_op, NO_BRACE_ARGS },
  62. { ":", cm_colon, NO_BRACE_ARGS },
  63. { "=", cm_accent, MAYBE_BRACE_ARGS },
  64. { "?", cm_punct, NO_BRACE_ARGS },
  65. { "@", insert_self, NO_BRACE_ARGS },
  66. { "\\", insert_self, NO_BRACE_ARGS },
  67. { "^", cm_accent_hat, MAYBE_BRACE_ARGS },
  68. { "`", cm_accent_grave, MAYBE_BRACE_ARGS },
  69. { "{", insert_self, NO_BRACE_ARGS },
  70. { "|", cm_no_op, NO_BRACE_ARGS },
  71. { "}", insert_self, NO_BRACE_ARGS },
  72. { "~", cm_accent_tilde, MAYBE_BRACE_ARGS },
  73. { "AA", cm_special_char, BRACE_ARGS },
  74. { "AE", cm_special_char, BRACE_ARGS },
  75. { "DH", cm_no_op, BRACE_ARGS },
  76. { "H", cm_accent, MAYBE_BRACE_ARGS },
  77. { "L", cm_special_char, BRACE_ARGS },
  78. { "LaTeX", cm_LaTeX, BRACE_ARGS },
  79. { "O", cm_special_char, BRACE_ARGS },
  80. { "OE", cm_special_char, BRACE_ARGS },
  81. { "TeX", cm_TeX, BRACE_ARGS },
  82. { "TH", cm_no_op, BRACE_ARGS },
  83. { "aa", cm_special_char, BRACE_ARGS },
  84. { "abbr", cm_abbr, BRACE_ARGS },
  85. { "acronym", cm_acronym, BRACE_ARGS },
  86. { "ae", cm_special_char, BRACE_ARGS },
  87. { "afivepaper", cm_ignore_line, NO_BRACE_ARGS },
  88. { "afourlatex", cm_ignore_line, NO_BRACE_ARGS },
  89. { "afourpaper", cm_ignore_line, NO_BRACE_ARGS },
  90. { "afourwide", cm_ignore_line, NO_BRACE_ARGS },
  91. { "alias", cm_alias, NO_BRACE_ARGS },
  92. { "allowcodebreaks", cm_ignore_line, NO_BRACE_ARGS },
  93. { "anchor", cm_anchor, BRACE_ARGS },
  94. { "appendix", cm_appendix, NO_BRACE_ARGS },
  95. { "appendixsection", cm_appendixsec, NO_BRACE_ARGS },
  96. { "appendixsec", cm_appendixsec, NO_BRACE_ARGS },
  97. { "appendixsubsec", cm_appendixsubsec, NO_BRACE_ARGS },
  98. { "appendixsubsubsec", cm_appendixsubsubsec, NO_BRACE_ARGS },
  99. { "arrow", cm_arrow, BRACE_ARGS },
  100. { "asis", cm_no_op, BRACE_ARGS },
  101. { "author", cm_author, NO_BRACE_ARGS },
  102. { "b", cm_b, BRACE_ARGS },
  103. { "bullet", cm_bullet, BRACE_ARGS },
  104. { "bye", cm_bye, NO_BRACE_ARGS },
  105. { "c", cm_comment, NO_BRACE_ARGS },
  106. { "caption", cm_caption, BRACE_ARGS },
  107. { "cartouche", cm_cartouche, NO_BRACE_ARGS },
  108. { "center", cm_center, NO_BRACE_ARGS },
  109. { "centerchap", cm_unnumbered, NO_BRACE_ARGS },
  110. { "chapheading", cm_chapheading, NO_BRACE_ARGS },
  111. { "chapter", cm_chapter, NO_BRACE_ARGS },
  112. { "cindex", cm_cindex, NO_BRACE_ARGS },
  113. { "cite", cm_cite, BRACE_ARGS },
  114. { "clear", cm_clear, NO_BRACE_ARGS },
  115. { "click", cm_click, BRACE_ARGS },
  116. { "clicksequence", cm_clicksequence, BRACE_ARGS },
  117. { "clickstyle", cm_clickstyle, NO_BRACE_ARGS },
  118. { "code", cm_code, BRACE_ARGS },
  119. { "comma", cm_comma, BRACE_ARGS },
  120. { "command", cm_code, BRACE_ARGS },
  121. { "comment", cm_comment, NO_BRACE_ARGS },
  122. { "contents", cm_contents, NO_BRACE_ARGS },
  123. { "copying", cm_copying, NO_BRACE_ARGS },
  124. { "copyright", cm_copyright, BRACE_ARGS },
  125. { "ctrl", cm_obsolete, BRACE_ARGS },
  126. { "defcodeindex", cm_defcodeindex, NO_BRACE_ARGS },
  127. { "defcv", cm_defun, NO_BRACE_ARGS },
  128. { "defcvx", cm_defun, NO_BRACE_ARGS },
  129. { "deffn", cm_defun, NO_BRACE_ARGS },
  130. { "deffnx", cm_defun, NO_BRACE_ARGS },
  131. { "defindex", cm_defindex, NO_BRACE_ARGS },
  132. { "definfoenclose", cm_definfoenclose, NO_BRACE_ARGS },
  133. { "defivar", cm_defun, NO_BRACE_ARGS },
  134. { "defivarx", cm_defun, NO_BRACE_ARGS },
  135. { "defmac", cm_defun, NO_BRACE_ARGS },
  136. { "defmacx", cm_defun, NO_BRACE_ARGS },
  137. { "defmethod", cm_defun, NO_BRACE_ARGS },
  138. { "defmethodx", cm_defun, NO_BRACE_ARGS },
  139. { "defop", cm_defun, NO_BRACE_ARGS },
  140. { "defopt", cm_defun, NO_BRACE_ARGS },
  141. { "defoptx", cm_defun, NO_BRACE_ARGS },
  142. { "defopx", cm_defun, NO_BRACE_ARGS },
  143. { "defspec", cm_defun, NO_BRACE_ARGS },
  144. { "defspecx", cm_defun, NO_BRACE_ARGS },
  145. { "deftp", cm_defun, NO_BRACE_ARGS },
  146. { "deftpx", cm_defun, NO_BRACE_ARGS },
  147. { "deftypecv", cm_defun, NO_BRACE_ARGS },
  148. { "deftypecvx", cm_defun, NO_BRACE_ARGS },
  149. { "deftypefn", cm_defun, NO_BRACE_ARGS },
  150. { "deftypefnx", cm_defun, NO_BRACE_ARGS },
  151. { "deftypefun", cm_defun, NO_BRACE_ARGS },
  152. { "deftypefunx", cm_defun, NO_BRACE_ARGS },
  153. { "deftypeivar", cm_defun, NO_BRACE_ARGS },
  154. { "deftypeivarx", cm_defun, NO_BRACE_ARGS },
  155. { "deftypemethod", cm_defun, NO_BRACE_ARGS },
  156. { "deftypemethodx", cm_defun, NO_BRACE_ARGS },
  157. { "deftypeop", cm_defun, NO_BRACE_ARGS },
  158. { "deftypeopx", cm_defun, NO_BRACE_ARGS },
  159. { "deftypevar", cm_defun, NO_BRACE_ARGS },
  160. { "deftypevarx", cm_defun, NO_BRACE_ARGS },
  161. { "deftypevr", cm_defun, NO_BRACE_ARGS },
  162. { "deftypevrx", cm_defun, NO_BRACE_ARGS },
  163. { "defun", cm_defun, NO_BRACE_ARGS },
  164. { "defunx", cm_defun, NO_BRACE_ARGS },
  165. { "defvar", cm_defun, NO_BRACE_ARGS },
  166. { "defvarx", cm_defun, NO_BRACE_ARGS },
  167. { "defvr", cm_defun, NO_BRACE_ARGS },
  168. { "defvrx", cm_defun, NO_BRACE_ARGS },
  169. { "detailmenu", cm_detailmenu, NO_BRACE_ARGS },
  170. { "dfn", cm_dfn, BRACE_ARGS },
  171. { "dh", cm_no_op, BRACE_ARGS },
  172. { "dircategory", cm_dircategory, NO_BRACE_ARGS },
  173. { "direntry", cm_direntry, NO_BRACE_ARGS },
  174. { "display", cm_display, NO_BRACE_ARGS },
  175. { "dmn", cm_dmn, BRACE_ARGS },
  176. { "docbook", cm_docbook, NO_BRACE_ARGS },
  177. { "documentdescription", cm_documentdescription, NO_BRACE_ARGS },
  178. { "documentencoding", cm_documentencoding, NO_BRACE_ARGS },
  179. { "documentlanguage", cm_documentlanguage, NO_BRACE_ARGS },
  180. { "dotaccent", cm_accent, MAYBE_BRACE_ARGS },
  181. { "dotless", cm_dotless, BRACE_ARGS },
  182. { "dots", cm_dots, BRACE_ARGS },
  183. { "email", cm_email, BRACE_ARGS },
  184. { "emph", cm_emph, BRACE_ARGS },
  185. { "end", cm_end, NO_BRACE_ARGS },
  186. { "enddots", cm_enddots, BRACE_ARGS },
  187. { "enumerate", cm_enumerate, NO_BRACE_ARGS },
  188. { "env", cm_code, BRACE_ARGS },
  189. { "equiv", cm_equiv, BRACE_ARGS },
  190. { "error", cm_error, BRACE_ARGS },
  191. { "euro", cm_special_char, BRACE_ARGS },
  192. { "evenfooting", cm_ignore_line, NO_BRACE_ARGS },
  193. { "evenfootingmarks", cm_ignore_line, NO_BRACE_ARGS },
  194. { "evenheading", cm_ignore_line, NO_BRACE_ARGS },
  195. { "evenheadingmarks", cm_ignore_line, NO_BRACE_ARGS },
  196. { "everyfooting", cm_ignore_line, NO_BRACE_ARGS },
  197. { "everyfootingmarks", cm_ignore_line, NO_BRACE_ARGS },
  198. { "everyheading", cm_ignore_line, NO_BRACE_ARGS },
  199. { "everyheadingmarks", cm_ignore_line, NO_BRACE_ARGS },
  200. { "example", cm_example, NO_BRACE_ARGS },
  201. { "exampleindent", cm_exampleindent, NO_BRACE_ARGS },
  202. { "exclamdown", cm_special_char, BRACE_ARGS },
  203. { "exdent", cm_exdent, NO_BRACE_ARGS },
  204. { "expansion", cm_expansion, BRACE_ARGS },
  205. { "file", cm_code, BRACE_ARGS },
  206. { "finalout", cm_no_op, NO_BRACE_ARGS },
  207. { "findex", cm_findex, NO_BRACE_ARGS },
  208. { "firstparagraphindent", cm_firstparagraphindent, NO_BRACE_ARGS },
  209. { "float", cm_float, NO_BRACE_ARGS },
  210. { "flushleft", cm_flushleft, NO_BRACE_ARGS },
  211. { "flushright", cm_flushright, NO_BRACE_ARGS },
  212. { "fonttextsize", cm_fonttextsize, NO_BRACE_ARGS },
  213. { "footnote", cm_footnote, NO_BRACE_ARGS}, /* self-arg eater */
  214. { "footnotestyle", cm_footnotestyle, NO_BRACE_ARGS },
  215. { "format", cm_format, NO_BRACE_ARGS },
  216. { "frenchspacing", cm_frenchspacing, NO_BRACE_ARGS },
  217. { "ftable", cm_ftable, NO_BRACE_ARGS },
  218. { "geq", cm_geq, BRACE_ARGS },
  219. { "group", cm_group, NO_BRACE_ARGS },
  220. { "guillemetleft", cm_special_char, BRACE_ARGS },
  221. { "guillemetright", cm_special_char, BRACE_ARGS },
  222. { "guillemotleft", cm_special_char, BRACE_ARGS },
  223. { "guillemotright", cm_special_char, BRACE_ARGS },
  224. { "guilsinglleft", cm_guilsinglleft, BRACE_ARGS },
  225. { "guilsinglright", cm_guilsinglright, BRACE_ARGS },
  226. { "heading", cm_heading, NO_BRACE_ARGS },
  227. { "headings", cm_ignore_line, NO_BRACE_ARGS },
  228. { "headitem", cm_headitem, NO_BRACE_ARGS },
  229. { "html", cm_html, NO_BRACE_ARGS },
  230. { "hyphenation", cm_ignore_arg, BRACE_ARGS },
  231. { "i", cm_i, BRACE_ARGS },
  232. { "ifclear", cm_ifclear, NO_BRACE_ARGS },
  233. { "ifeq", cm_ifeq, NO_BRACE_ARGS },
  234. { "ifdocbook", cm_ifdocbook, NO_BRACE_ARGS },
  235. { "ifhtml", cm_ifhtml, NO_BRACE_ARGS },
  236. { "ifinfo", cm_ifinfo, NO_BRACE_ARGS },
  237. { "ifnotdocbook", cm_ifnotdocbook, NO_BRACE_ARGS },
  238. { "ifnothtml", cm_ifnothtml, NO_BRACE_ARGS },
  239. { "ifnotinfo", cm_ifnotinfo, NO_BRACE_ARGS },
  240. { "ifnotplaintext", cm_ifnotplaintext, NO_BRACE_ARGS },
  241. { "ifnottex", cm_ifnottex, NO_BRACE_ARGS },
  242. { "ifnotxml", cm_ifnotxml, NO_BRACE_ARGS },
  243. { "ifplaintext", cm_ifplaintext, NO_BRACE_ARGS },
  244. { "ifset", cm_ifset, NO_BRACE_ARGS },
  245. { "iftex", cm_iftex, NO_BRACE_ARGS },
  246. { "ifxml", cm_ifxml, NO_BRACE_ARGS },
  247. { "ignore", command_name_condition, NO_BRACE_ARGS },
  248. { "image", cm_image, BRACE_ARGS },
  249. { "include", cm_include, NO_BRACE_ARGS },
  250. { "indent", cm_indent, NO_BRACE_ARGS },
  251. { "indicateurl", cm_indicate_url, BRACE_ARGS },
  252. { "inforef", cm_inforef, BRACE_ARGS },
  253. { "insertcopying", cm_insert_copying, NO_BRACE_ARGS },
  254. { "item", cm_item, NO_BRACE_ARGS },
  255. { "itemize", cm_itemize, NO_BRACE_ARGS },
  256. { "itemx", cm_itemx, NO_BRACE_ARGS },
  257. { "kbd", cm_kbd, BRACE_ARGS },
  258. { "kbdinputstyle", cm_ignore_line, NO_BRACE_ARGS },
  259. { "key", cm_key, BRACE_ARGS },
  260. { "kindex", cm_kindex, NO_BRACE_ARGS },
  261. { "l", cm_special_char, BRACE_ARGS },
  262. { "leq", cm_leq, BRACE_ARGS },
  263. { "lisp", cm_lisp, NO_BRACE_ARGS },
  264. { "listoffloats", cm_listoffloats, NO_BRACE_ARGS },
  265. { "lowersections", cm_lowersections, NO_BRACE_ARGS },
  266. { "macro", cm_macro, NO_BRACE_ARGS },
  267. { "majorheading", cm_majorheading, NO_BRACE_ARGS },
  268. { "math", cm_math, BRACE_ARGS },
  269. { "menu", cm_menu, NO_BRACE_ARGS },
  270. { "minus", cm_minus, BRACE_ARGS },
  271. { "multitable", cm_multitable, NO_BRACE_ARGS },
  272. { "need", cm_ignore_line, NO_BRACE_ARGS },
  273. { "node", cm_node, NO_BRACE_ARGS },
  274. { "noindent", cm_noindent_cmd, NO_BRACE_ARGS },
  275. { "novalidate", cm_novalidate, NO_BRACE_ARGS },
  276. { "nwnode", cm_node, NO_BRACE_ARGS },
  277. { "o", cm_special_char, BRACE_ARGS },
  278. { "oddfooting", cm_ignore_line, NO_BRACE_ARGS },
  279. { "oddfootingmarks", cm_ignore_line, NO_BRACE_ARGS },
  280. { "oddheading", cm_ignore_line, NO_BRACE_ARGS },
  281. { "oddheadingmarks", cm_ignore_line, NO_BRACE_ARGS },
  282. { "oe", cm_special_char, BRACE_ARGS },
  283. { "ogonek", cm_accent, MAYBE_BRACE_ARGS },
  284. { "option", cm_code, BRACE_ARGS },
  285. { "ordf", cm_special_char, BRACE_ARGS },
  286. { "ordm", cm_special_char, BRACE_ARGS },
  287. { "page", cm_no_op, NO_BRACE_ARGS },
  288. { "pagesizes", cm_ignore_line, NO_BRACE_ARGS },
  289. { "paragraphindent", cm_paragraphindent, NO_BRACE_ARGS },
  290. { "pindex", cm_pindex, NO_BRACE_ARGS },
  291. { "point", cm_point, BRACE_ARGS },
  292. { "pounds", cm_special_char, BRACE_ARGS },
  293. { "print", cm_print, BRACE_ARGS },
  294. { "printindex", cm_printindex, NO_BRACE_ARGS },
  295. { "pxref", cm_pxref, BRACE_ARGS },
  296. { "questiondown", cm_special_char, BRACE_ARGS },
  297. { "quotation", cm_quotation, NO_BRACE_ARGS },
  298. { "quotedblbase", cm_quotedblbase, BRACE_ARGS },
  299. { "quotedblleft", cm_quotedblleft, BRACE_ARGS },
  300. { "quotedblright", cm_quotedblright, BRACE_ARGS },
  301. { "quoteleft", cm_quoteleft, BRACE_ARGS },
  302. { "quoteright", cm_quoteright, BRACE_ARGS },
  303. { "quotesinglbase", cm_quotesinglbase, BRACE_ARGS },
  304. { "r", cm_r, BRACE_ARGS },
  305. { "raggedcenter", cm_raggedcenter, NO_BRACE_ARGS },
  306. { "raggedleft", cm_raggedleft, NO_BRACE_ARGS },
  307. { "raggedright", cm_raggedright, NO_BRACE_ARGS },
  308. { "raisesections", cm_raisesections, NO_BRACE_ARGS },
  309. { "ref", cm_ref, BRACE_ARGS },
  310. { "refill", cm_no_op, NO_BRACE_ARGS },
  311. { "registeredsymbol", cm_registeredsymbol, BRACE_ARGS },
  312. { "result", cm_result, BRACE_ARGS },
  313. { "ringaccent", cm_accent, MAYBE_BRACE_ARGS },
  314. { "rmacro", cm_rmacro, NO_BRACE_ARGS },
  315. { "samp", cm_code, BRACE_ARGS },
  316. { "sansserif", cm_sansserif, BRACE_ARGS },
  317. { "sc", cm_sc, BRACE_ARGS },
  318. { "section", cm_section, NO_BRACE_ARGS },
  319. { "set", cm_set, NO_BRACE_ARGS },
  320. { "setchapternewpage", cm_ignore_line, NO_BRACE_ARGS },
  321. { "setchapterstyle", cm_obsolete, NO_BRACE_ARGS },
  322. { "setcontentsaftertitlepage", cm_no_op, NO_BRACE_ARGS },
  323. { "setfilename", cm_setfilename, NO_BRACE_ARGS },
  324. { "setshortcontentsaftertitlepage", cm_no_op, NO_BRACE_ARGS },
  325. { "settitle", cm_settitle, NO_BRACE_ARGS },
  326. { "shortcaption", cm_caption, BRACE_ARGS },
  327. { "shortcontents", cm_contents, NO_BRACE_ARGS },
  328. { "shorttitlepage", cm_ignore_line, NO_BRACE_ARGS },
  329. { "slanted", cm_slanted, BRACE_ARGS },
  330. { "smallbook", cm_ignore_line, NO_BRACE_ARGS },
  331. { "smalldisplay", cm_smalldisplay, NO_BRACE_ARGS },
  332. { "smallexample", cm_smallexample, NO_BRACE_ARGS },
  333. { "smallformat", cm_smallformat, NO_BRACE_ARGS },
  334. { "smalllisp", cm_smalllisp, NO_BRACE_ARGS },
  335. { "sp", cm_sp, NO_BRACE_ARGS },
  336. { "ss", cm_special_char, BRACE_ARGS },
  337. { "strong", cm_strong, BRACE_ARGS },
  338. { "subheading", cm_subheading, NO_BRACE_ARGS },
  339. { "subsection", cm_subsection, NO_BRACE_ARGS },
  340. { "subsubheading", cm_subsubheading, NO_BRACE_ARGS },
  341. { "subsubsection", cm_subsubsection, NO_BRACE_ARGS },
  342. { "subtitle", cm_titlepage_cmds, NO_BRACE_ARGS },
  343. { "summarycontents", cm_contents, NO_BRACE_ARGS },
  344. { "syncodeindex", cm_synindex, NO_BRACE_ARGS },
  345. { "synindex", cm_synindex, NO_BRACE_ARGS },
  346. { "t", cm_tt, BRACE_ARGS },
  347. { "tab", cm_tab, NO_BRACE_ARGS },
  348. { "table", cm_table, NO_BRACE_ARGS },
  349. { "tex", cm_tex, NO_BRACE_ARGS },
  350. { "textdegree", cm_special_char, BRACE_ARGS },
  351. { "th", cm_no_op, BRACE_ARGS },
  352. { "tie", cm_tie, BRACE_ARGS },
  353. { "tieaccent", cm_accent, MAYBE_BRACE_ARGS },
  354. { "tindex", cm_tindex, NO_BRACE_ARGS },
  355. { "title", cm_titlepage_cmds, NO_BRACE_ARGS },
  356. { "titlefont", cm_titlefont, BRACE_ARGS },
  357. { "titlepage", cm_titlepage, NO_BRACE_ARGS },
  358. { "today", cm_today, BRACE_ARGS },
  359. { "top", cm_top, NO_BRACE_ARGS },
  360. { "u", cm_accent, MAYBE_BRACE_ARGS },
  361. { "ubaraccent", cm_accent, MAYBE_BRACE_ARGS },
  362. { "udotaccent", cm_accent, MAYBE_BRACE_ARGS },
  363. { "unmacro", cm_unmacro, NO_BRACE_ARGS },
  364. { "unnumbered", cm_unnumbered, NO_BRACE_ARGS },
  365. { "unnumberedsec", cm_unnumberedsec, NO_BRACE_ARGS },
  366. { "unnumberedsubsec", cm_unnumberedsubsec, NO_BRACE_ARGS },
  367. { "unnumberedsubsubsec", cm_unnumberedsubsubsec, NO_BRACE_ARGS },
  368. { "uref", cm_uref, BRACE_ARGS },
  369. { "url", cm_uref, BRACE_ARGS },
  370. { "v", cm_accent, MAYBE_BRACE_ARGS },
  371. { "value", cm_value, BRACE_ARGS },
  372. { "var", cm_var, BRACE_ARGS },
  373. { "verb", cm_verb, NO_BRACE_ARGS },
  374. { "verbatim", cm_verbatim, NO_BRACE_ARGS },
  375. { "verbatiminclude", cm_verbatiminclude, NO_BRACE_ARGS },
  376. { "vindex", cm_vindex, NO_BRACE_ARGS },
  377. { "vtable", cm_vtable, NO_BRACE_ARGS },
  378. { "vskip", cm_ignore_line, NO_BRACE_ARGS },
  379. { "w", cm_w, BRACE_ARGS },
  380. { "xml", cm_xml, NO_BRACE_ARGS },
  381. { "xref", cm_xref, BRACE_ARGS },
  382. /* Deprecated commands. These used to be for italics. */
  383. { "iappendix", cm_ideprecated, NO_BRACE_ARGS },
  384. { "iappendixsec", cm_ideprecated, NO_BRACE_ARGS },
  385. { "iappendixsection", cm_ideprecated, NO_BRACE_ARGS },
  386. { "iappendixsubsec", cm_ideprecated, NO_BRACE_ARGS },
  387. { "iappendixsubsubsec", cm_ideprecated, NO_BRACE_ARGS },
  388. { "ichapter", cm_ideprecated, NO_BRACE_ARGS },
  389. { "isection", cm_ideprecated, NO_BRACE_ARGS },
  390. { "isubsection", cm_ideprecated, NO_BRACE_ARGS },
  391. { "isubsubsection", cm_ideprecated, NO_BRACE_ARGS },
  392. { "iunnumbered", cm_ideprecated, NO_BRACE_ARGS },
  393. { "iunnumberedsec", cm_ideprecated, NO_BRACE_ARGS },
  394. { "iunnumberedsubsec", cm_ideprecated, NO_BRACE_ARGS },
  395. { "iunnumberedsubsubsec", cm_ideprecated, NO_BRACE_ARGS },
  396. /* Now @include does what this was used to. */
  397. { "infoinclude", cm_obsolete, NO_BRACE_ARGS },
  398. { "titlespec", cm_obsolete, NO_BRACE_ARGS },
  399. { NULL, NULL, NO_BRACE_ARGS }
  400. };
  401. /* The bulk of the Texinfo commands. */
  402. /* Commands which insert their own names. */
  403. void
  404. insert_self (int arg)
  405. {
  406. if (arg == START)
  407. add_word (command);
  408. }
  409. void
  410. insert_space (int arg)
  411. {
  412. if (arg == START)
  413. {
  414. if (xml && !docbook)
  415. xml_insert_entity ("space");
  416. else
  417. add_char (' ');
  418. }
  419. }
  420. /* Insert a comma. Useful when a literal , would break our parsing of
  421. multiple arguments. */
  422. void
  423. cm_comma (int arg)
  424. {
  425. if (arg == START)
  426. add_char (',');
  427. }
  428. /* Force a line break in the output. */
  429. void
  430. cm_asterisk (void)
  431. {
  432. if (html)
  433. add_word ("<br>");
  434. else if (xml && !docbook)
  435. xml_insert_entity ("linebreak");
  436. else if (docbook)
  437. xml_asterisk ();
  438. else
  439. {
  440. close_single_paragraph ();
  441. cm_noindent ();
  442. }
  443. }
  444. /* Insert ellipsis. */
  445. void
  446. cm_dots (int arg)
  447. {
  448. if (arg == START)
  449. {
  450. if (xml && !docbook)
  451. xml_insert_entity ("dots");
  452. else if (docbook)
  453. xml_insert_entity ("hellip");
  454. else
  455. if (html && !in_fixed_width_font)
  456. insert_string ("<small class=\"dots\">...</small>");
  457. else
  458. add_word ("...");
  459. }
  460. }
  461. /* Insert ellipsis for sentence end. */
  462. void
  463. cm_enddots (int arg)
  464. {
  465. if (arg == START)
  466. {
  467. if (xml && !docbook)
  468. xml_insert_entity ("enddots");
  469. else if (docbook)
  470. {
  471. xml_insert_entity ("hellip");
  472. add_char ('.');
  473. }
  474. else
  475. if (html && !in_fixed_width_font)
  476. insert_string ("<small class=\"enddots\">...</small>");
  477. else
  478. add_word ("...");
  479. }
  480. }
  481. void
  482. cm_bullet (int arg)
  483. {
  484. if (arg == START)
  485. {
  486. if (html)
  487. add_word ("&bull;");
  488. else if (xml && !docbook)
  489. xml_insert_entity ("bullet");
  490. else if (docbook)
  491. xml_insert_entity ("bull");
  492. else
  493. add_char ('*');
  494. }
  495. }
  496. static void
  497. cm_geq (int arg)
  498. {
  499. if (arg == START)
  500. {
  501. if (xml)
  502. xml_insert_entity ("ge");
  503. else if (html)
  504. add_word ("&ge;");
  505. else
  506. insert_string (">=");
  507. }
  508. }
  509. static void
  510. cm_leq (int arg)
  511. {
  512. if (arg == START)
  513. {
  514. if (xml)
  515. xml_insert_entity ("le");
  516. else if (html)
  517. add_word ("&le;");
  518. else
  519. insert_string ("<=");
  520. }
  521. }
  522. static void
  523. cm_minus (int arg)
  524. {
  525. if (arg == START)
  526. {
  527. if (xml)
  528. xml_insert_entity ("minus");
  529. else if (html)
  530. add_word ("&minus;");
  531. else
  532. add_char ('-');
  533. }
  534. }
  535. /* Formatting a dimension unit. */
  536. void
  537. cm_dmn (int arg)
  538. {
  539. if (html)
  540. insert_html_tag_with_attribute (arg, "span", "class=\"dmn\"");
  541. else if (docbook)
  542. /* No units in docbook yet. */
  543. ;
  544. else if (xml)
  545. xml_insert_element (DIMENSION, arg);
  546. }
  547. /* Insert "TeX". */
  548. void
  549. cm_TeX (int arg)
  550. {
  551. static int last_position;
  552. if (arg == START)
  553. {
  554. if (xml)
  555. xml_insert_entity ("tex");
  556. else
  557. add_word ("TeX");
  558. last_position = output_paragraph_offset;
  559. }
  560. else if (last_position != output_paragraph_offset)
  561. {
  562. warning (_("arguments to @%s ignored"), command);
  563. output_paragraph_offset = last_position;
  564. }
  565. }
  566. /* Insert "LaTeX". */
  567. void
  568. cm_LaTeX (int arg)
  569. {
  570. static int last_position;
  571. if (arg == START)
  572. {
  573. if (xml)
  574. xml_insert_entity ("latex");
  575. else
  576. add_word ("LaTeX");
  577. last_position = output_paragraph_offset;
  578. }
  579. else if (last_position != output_paragraph_offset)
  580. {
  581. warning (_("arguments to @%s ignored"), command);
  582. output_paragraph_offset = last_position;
  583. }
  584. }
  585. /* Copyright symbol. */
  586. void
  587. cm_copyright (int arg)
  588. {
  589. if (arg == START)
  590. {
  591. if (html)
  592. add_word ("&copy;");
  593. else if (xml && !docbook)
  594. xml_insert_entity ("copyright");
  595. else if (docbook)
  596. xml_insert_entity ("copy");
  597. else
  598. add_word ("(C)");
  599. }
  600. }
  601. /* Registered symbol. */
  602. void
  603. cm_registeredsymbol (int arg)
  604. {
  605. if (arg == START)
  606. {
  607. if (html)
  608. add_word ("&reg;");
  609. else if (docbook)
  610. xml_insert_entity ("reg");
  611. else if (xml && !docbook)
  612. xml_insert_entity ("registered");
  613. else
  614. add_word ("(R)");
  615. }
  616. }
  617. /* Left single guillemet (single left-pointing angle quotation mark). */
  618. void
  619. cm_guilsinglleft (int arg)
  620. {
  621. if (arg == START)
  622. {
  623. if (html)
  624. add_word ("&lsaquo;");
  625. else if (xml && !docbook)
  626. xml_insert_entity ("lsaquo");
  627. else
  628. add_word ("<");
  629. }
  630. }
  631. /* Right single guillemet (single right-pointing angle quotation mark). */
  632. void
  633. cm_guilsinglright (int arg)
  634. {
  635. if (arg == START)
  636. {
  637. if (html)
  638. add_word ("&rsaquo;");
  639. else if (xml && !docbook)
  640. xml_insert_entity ("rsaquo");
  641. else
  642. add_word (">");
  643. }
  644. }
  645. /* Double low-9 quotation mark. */
  646. void
  647. cm_quotedblbase (int arg)
  648. {
  649. if (arg == START)
  650. {
  651. if (html)
  652. add_word ("&bdquo;");
  653. else if (docbook)
  654. xml_insert_entity ("ldquor");
  655. else if (xml && !docbook)
  656. xml_insert_entity ("bdquo");
  657. else
  658. add_word ("\"");
  659. }
  660. }
  661. /* Left double quotation mark. */
  662. void
  663. cm_quotedblleft (int arg)
  664. {
  665. if (arg == START)
  666. {
  667. if (html)
  668. add_word ("&ldquo;");
  669. else if (docbook)
  670. xml_insert_entity ("ldquo");
  671. else if (xml && !docbook)
  672. xml_insert_entity ("ldquo");
  673. else
  674. add_word ("\"");
  675. }
  676. }
  677. /* Right double quotation mark. */
  678. void
  679. cm_quotedblright (int arg)
  680. {
  681. if (arg == START)
  682. {
  683. if (html)
  684. add_word ("&rdquo;");
  685. else if (docbook)
  686. xml_insert_entity ("rdquo");
  687. else if (xml && !docbook)
  688. xml_insert_entity ("rdquo");
  689. else
  690. add_word ("\"");
  691. }
  692. }
  693. /* Left single quotation mark. */
  694. void
  695. cm_quoteleft (int arg)
  696. {
  697. if (arg == START)
  698. {
  699. if (html)
  700. add_word ("&lsquo;");
  701. else if (docbook)
  702. xml_insert_entity ("lsquo");
  703. else if (xml && !docbook)
  704. xml_insert_entity ("lsquo");
  705. else
  706. add_word ("`");
  707. }
  708. }
  709. /* Right single quotation mark. */
  710. void
  711. cm_quoteright (int arg)
  712. {
  713. if (arg == START)
  714. {
  715. if (html)
  716. add_word ("&rsquo;");
  717. else if (docbook)
  718. xml_insert_entity ("rsquo");
  719. else if (xml && !docbook)
  720. xml_insert_entity ("rsquo");
  721. else
  722. add_word ("'");
  723. }
  724. }
  725. /* Single low-9 quotation mark. */
  726. void
  727. cm_quotesinglbase (int arg)
  728. {
  729. if (arg == START)
  730. {
  731. if (html)
  732. add_word ("&sbquo;");
  733. else if (docbook)
  734. xml_insert_entity ("lsquor");
  735. else if (xml && !docbook)
  736. xml_insert_entity ("sbquo");
  737. else
  738. add_word (",");
  739. }
  740. }
  741. void
  742. cm_today (int arg)
  743. {
  744. static char *months[12] =
  745. { N_("January"), N_("February"), N_("March"), N_("April"), N_("May"),
  746. N_("June"), N_("July"), N_("August"), N_("September"), N_("October"),
  747. N_("November"), N_("December") };
  748. if (arg == START)
  749. {
  750. time_t timer = time (0);
  751. struct tm *ts = localtime (&timer);
  752. add_word_args ("%d %s %d", ts->tm_mday, _(months[ts->tm_mon]),
  753. ts->tm_year + 1900);
  754. }
  755. }
  756. void
  757. cm_comment (void)
  758. {
  759. /* For HTML, do not output comments before HTML header is written,
  760. otherwise comments before @settitle cause an empty <title> in the
  761. header. */
  762. if ((html && output_head_p) || xml)
  763. {
  764. char *line;
  765. get_rest_of_line (0, &line);
  766. if (strlen (line) > 0)
  767. {
  768. int save_inhibit_indentation = inhibit_paragraph_indentation;
  769. int save_paragraph_is_open = paragraph_is_open;
  770. int save_escape_html = escape_html;
  771. int save_xml_no_para = xml_no_para;
  772. int i;
  773. inhibit_paragraph_indentation = 1;
  774. escape_html = 0;
  775. xml_no_para = 1;
  776. /* @c and @comment can appear between @item and @itemx,
  777. @deffn and @deffnx. */
  778. xml_dont_touch_items_defs++;
  779. /* Use insert for HTML, and XML when indentation is enabled.
  780. For Docbook, use add_char. */
  781. if (xml && xml_indentation_increment > 0
  782. && output_paragraph_offset > 0
  783. && output_paragraph[output_paragraph_offset-1] != '\n')
  784. insert ('\n');
  785. /* Crunch double hyphens in comments. */
  786. add_html_block_elt ("<!-- ");
  787. for (i = 0; i < strlen (line); i++)
  788. if (line[i] != '-' || (i && line[i-1] != '-'))
  789. add_char (line[i]);
  790. add_word (" -->");
  791. if (html)
  792. add_char ('\n');
  793. inhibit_paragraph_indentation = save_inhibit_indentation;
  794. paragraph_is_open = save_paragraph_is_open;
  795. escape_html = save_escape_html;
  796. xml_no_para = save_xml_no_para;
  797. xml_dont_touch_items_defs--;
  798. }
  799. free (line);
  800. }
  801. else
  802. cm_ignore_line ();
  803. }
  804. /* We keep acronyms with two arguments around, to be able to refer to them
  805. later with only one argument. */
  806. static ACRONYM_DESC *acronyms_stack = NULL;
  807. static void
  808. cm_acronym_or_abbr (int arg, int is_abbr)
  809. {
  810. char *aa, *description;
  811. unsigned len;
  812. /* We do everything at START. */
  813. if (arg == END)
  814. return;
  815. get_until_in_braces (",", &aa);
  816. if (input_text[input_text_offset] == ',')
  817. input_text_offset++;
  818. get_until_in_braces ("}", &description);
  819. canon_white (aa);
  820. canon_white (description);
  821. /* If not enclosed in braces, strip after comma to be compatible
  822. with texinfo.tex. */
  823. if (description[0] != '{' && strchr (description, ',') != NULL)
  824. {
  825. int i = 0;
  826. while (description[i] != ',')
  827. i++;
  828. /* For now, just terminate the string at comma. */
  829. description[i] = 0;
  830. }
  831. /* Get description out of braces. */
  832. if (description[0] == '{')
  833. description++;
  834. len = strlen (description);
  835. if (len && description[len-1] == '}')
  836. description[len-1] = 0;
  837. /* Save new description. */
  838. if (strlen (description) > 0)
  839. {
  840. ACRONYM_DESC *new = xmalloc (sizeof (ACRONYM_DESC));
  841. new->acronym = xstrdup (aa);
  842. new->description = xstrdup (description);
  843. new->next = acronyms_stack;
  844. acronyms_stack = new;
  845. }
  846. if (html)
  847. {
  848. add_word (is_abbr ? "<abbr" : "<acronym");
  849. if (strlen (description) > 0)
  850. add_word_args (" title=\"%s\"", text_expansion (description));
  851. else if (acronyms_stack)
  852. {
  853. /* No second argument, get from previous. Search order is from
  854. last to first defined, so we get the most recent version of
  855. the description. */
  856. ACRONYM_DESC *temp = acronyms_stack;
  857. while (temp)
  858. {
  859. if (STREQ (aa, temp->acronym)
  860. && strlen (temp->description) > 0)
  861. {
  862. add_word_args (" title=\"%s\"",
  863. text_expansion (temp->description));
  864. break;
  865. }
  866. temp = temp->next;
  867. }
  868. }
  869. add_char ('>');
  870. execute_string ("%s", aa);
  871. add_word (is_abbr ? "</abbr>" : "</acronym>");
  872. }
  873. else if (docbook)
  874. {
  875. xml_insert_element (is_abbr ? ABBREV : ACRONYM, START);
  876. execute_string ("%s", aa);
  877. xml_insert_element (is_abbr ? ABBREV : ACRONYM, END);
  878. }
  879. else if (xml)
  880. {
  881. xml_insert_element (is_abbr ? ABBREV : ACRONYM, START);
  882. xml_insert_element (is_abbr ? ABBREVWORD : ACRONYMWORD, START);
  883. execute_string ("%s", aa);
  884. xml_insert_element (is_abbr ? ABBREVWORD : ACRONYMWORD, END);
  885. if (strlen (description) > 0)
  886. {
  887. xml_insert_element (is_abbr ? ABBREVDESC : ACRONYMDESC, START);
  888. execute_string ("%s", description);
  889. xml_insert_element (is_abbr ? ABBREVDESC : ACRONYMDESC, END);
  890. }
  891. xml_insert_element (is_abbr ? ABBREV : ACRONYM, END);
  892. }
  893. else
  894. execute_string ("%s", aa);
  895. /* Put description into parenthesis after the acronym for all outputs
  896. except XML. */
  897. if (strlen (description) > 0 && (!xml || docbook))
  898. add_word_args (" (%s)", description);
  899. }
  900. void
  901. cm_acronym (int arg)
  902. {
  903. cm_acronym_or_abbr (arg, 0);
  904. }
  905. void
  906. cm_abbr (int arg)
  907. {
  908. cm_acronym_or_abbr (arg, 1);
  909. }
  910. void
  911. cm_tt (int arg)
  912. {
  913. /* @t{} is a no-op in Info. */
  914. if (html)
  915. insert_html_tag (arg, "tt");
  916. else if (xml)
  917. xml_insert_element (TT, arg);
  918. }
  919. void
  920. cm_code (int arg)
  921. {
  922. if (arg == START)
  923. in_fixed_width_font++;
  924. if (xml)
  925. {
  926. if (STREQ (command, "command"))
  927. xml_insert_element (COMMAND_TAG, arg);
  928. else if (STREQ (command, "env"))
  929. xml_insert_element (ENV, arg);
  930. else if (STREQ (command, "file"))
  931. xml_insert_element (FILE_TAG, arg);
  932. else if (STREQ (command, "option"))
  933. xml_insert_element (OPTION, arg);
  934. else if (STREQ (command, "samp"))
  935. {
  936. if (docbook && arg == START)
  937. {
  938. /* Even though @samp is in_fixed_width_font, it
  939. should always start a paragraph. Unfortunately,
  940. in_fixed_width_font inhibits that. */
  941. xml_start_para ();
  942. xml_insert_entity ("lsquo");
  943. }
  944. xml_insert_element (SAMP, arg);
  945. if (docbook && arg == END)
  946. xml_insert_entity ("rsquo");
  947. }
  948. else
  949. xml_insert_element (CODE, arg);
  950. }
  951. else if (html)
  952. {
  953. if (STREQ (command, "code"))
  954. insert_html_tag (arg, "code");
  955. else
  956. { /* Use <samp> tag in general to get typewriter. */
  957. if (arg == START)
  958. { /* If @samp specifically, add quotes a la TeX output. */
  959. if (STREQ (command, "samp"))
  960. add_word ("&lsquo;");
  961. insert_html_tag (arg, "samp");
  962. }
  963. insert_html_tag_with_attribute (arg, "span", "class=\"%s\"",command);
  964. if (arg == END)
  965. {
  966. insert_html_tag (arg, "samp");
  967. if (STREQ (command, "samp"))
  968. add_word ("&rsquo;");
  969. }
  970. }
  971. }
  972. else
  973. {
  974. if (!printing_index)
  975. {
  976. if (arg == START)
  977. add_char ('`');
  978. else
  979. add_meta_char ('\'');
  980. }
  981. }
  982. }
  983. void
  984. cm_kbd (int arg)
  985. {
  986. if (xml)
  987. xml_insert_element (KBD, arg);
  988. else if (html)
  989. { /* Seems like we should increment in_fixed_width_font for Info
  990. format too, but then the quote-omitting special case gets
  991. confused. Punt. */
  992. if (arg == START)
  993. in_fixed_width_font++;
  994. insert_html_tag (arg, "kbd");
  995. }
  996. else
  997. { /* People use @kbd in an example to get the "user input" font.
  998. We don't want quotes in that case. */
  999. if (!in_fixed_width_font)
  1000. cm_code (arg);
  1001. }
  1002. }
  1003. /* Just show a url (http://example.org/..., for example), don't link to it. */
  1004. void
  1005. cm_indicate_url (int arg, int start, int end)
  1006. {
  1007. if (xml)
  1008. xml_insert_element (URL, arg);
  1009. else if (html)
  1010. {
  1011. if (arg == START)
  1012. add_word ("&lt;");
  1013. insert_html_tag (arg, "code");
  1014. if (arg != START)
  1015. add_word ("&gt;");
  1016. }
  1017. else
  1018. if (arg == START)
  1019. add_word ("<");
  1020. else
  1021. add_word (">");
  1022. }
  1023. void
  1024. cm_key (int arg)
  1025. {
  1026. if (xml)
  1027. xml_insert_element (KEY, arg);
  1028. else if (html)
  1029. add_word (arg == START ? "&lt;" : "&gt;");
  1030. else
  1031. add_char (arg == START ? '<' : '>');
  1032. }
  1033. /* Handle a command that switches to a non-fixed-width font. */
  1034. void
  1035. not_fixed_width (int arg)
  1036. {
  1037. if (arg == START)
  1038. in_fixed_width_font = 0;
  1039. }
  1040. /* @var in makeinfo just uppercases the text. */
  1041. void
  1042. cm_var (int arg, int start_pos, int end_pos)
  1043. {
  1044. if (xml)
  1045. xml_insert_element (VAR, arg);
  1046. else
  1047. {
  1048. not_fixed_width (arg);
  1049. if (html)
  1050. insert_html_tag (arg, "var");
  1051. else if (arg == END)
  1052. {
  1053. while (start_pos < end_pos)
  1054. {
  1055. unsigned char c = output_paragraph[start_pos];
  1056. if (strchr ("[](),", c))
  1057. warning (_("unlikely character %c in @var"), c);
  1058. output_paragraph[start_pos] = coerce_to_upper (c);
  1059. start_pos++;
  1060. }
  1061. }
  1062. }
  1063. }
  1064. void
  1065. cm_sc (int arg, int start_pos, int end_pos)
  1066. {
  1067. if (xml)
  1068. xml_insert_element (SC, arg);
  1069. else
  1070. {
  1071. not_fixed_width (arg);
  1072. if (arg == START)
  1073. {
  1074. if (html)
  1075. insert_html_tag_with_attribute (arg, "span", "class=\"sc\"");
  1076. }
  1077. else
  1078. {
  1079. int all_upper;
  1080. if (html)
  1081. start_pos += sizeof ("<span class=\"sc\">") - 1; /* skip <span> */
  1082. /* Avoid the warning below if there's no text inside @sc{}, or
  1083. when processing menus under --no-headers. */
  1084. all_upper = start_pos < end_pos;
  1085. while (start_pos < end_pos)
  1086. {
  1087. unsigned char c = output_paragraph[start_pos];
  1088. if (!isupper (c))
  1089. all_upper = 0;
  1090. if (!html)
  1091. output_paragraph[start_pos] = coerce_to_upper (c);
  1092. start_pos++;
  1093. }
  1094. if (all_upper)
  1095. warning (_("@sc argument all uppercase, thus no effect"));
  1096. if (html)
  1097. insert_html_tag (arg, "span");
  1098. }
  1099. }
  1100. }
  1101. void
  1102. cm_dfn (int arg, int position)
  1103. {
  1104. if (xml)
  1105. xml_insert_element (DFN, arg);
  1106. else
  1107. {
  1108. if (html)
  1109. insert_html_tag (arg, "dfn");
  1110. else if (arg == START)
  1111. add_char ('"');
  1112. else
  1113. add_meta_char ('"');
  1114. }
  1115. }
  1116. void
  1117. cm_emph (int arg)
  1118. {
  1119. if (xml)
  1120. xml_insert_element (EMPH, arg);
  1121. else if (html)
  1122. insert_html_tag (arg, "em");
  1123. else
  1124. add_char ('_');
  1125. }
  1126. void
  1127. cm_verb (int arg)
  1128. {
  1129. int character;
  1130. int delimiter = 0; /* avoid warning */
  1131. int seen_end = 0;
  1132. in_fixed_width_font++;
  1133. /* are these necessary ? */
  1134. last_char_was_newline = 0;
  1135. if (html)
  1136. add_word ("<tt>");
  1137. if (input_text_offset < input_text_length)
  1138. {
  1139. character = curchar ();
  1140. if (character == '{')
  1141. input_text_offset++;
  1142. else
  1143. line_error (_("`{' expected, but saw `%c'"), character);
  1144. }
  1145. if (input_text_offset < input_text_length)
  1146. {
  1147. delimiter = curchar ();
  1148. input_text_offset++;
  1149. }
  1150. while (input_text_offset < input_text_length)
  1151. {
  1152. character = curchar ();
  1153. if (character == '\n')
  1154. {
  1155. line_number++;
  1156. if (html)
  1157. add_word ("<br>\n");
  1158. }
  1159. else if (html && character == '<')
  1160. add_word ("&lt;");
  1161. else if (html && character == '&')
  1162. add_word ("&amp;");
  1163. else if (character == delimiter && input_text[input_text_offset+1] == '}')
  1164. { /* Assume no newlines in END_VERBATIM. */
  1165. seen_end = 1;
  1166. input_text_offset++;
  1167. break;
  1168. }
  1169. else
  1170. add_char (character);
  1171. input_text_offset++;
  1172. }
  1173. if (!seen_end)
  1174. warning (_("end of file inside verb block"));
  1175. if (input_text_offset < input_text_length)
  1176. {
  1177. character = curchar ();
  1178. if (character == '}')
  1179. input_text_offset++;
  1180. else
  1181. line_error (_("`}' expected, but saw `%c'"), character);
  1182. }
  1183. if (html)
  1184. add_word ("</tt>");
  1185. in_fixed_width_font--;
  1186. }
  1187. void
  1188. cm_strong (int arg, int start_pos, int end_pos)
  1189. {
  1190. if (docbook && arg == START)
  1191. xml_insert_element_with_attribute (B, arg, "role=\"bold\"");
  1192. else if (xml)
  1193. xml_insert_element (STRONG, arg);
  1194. else if (html)
  1195. insert_html_tag (arg, "strong");
  1196. else
  1197. add_char ('*');
  1198. if (!xml && !html && !docbook && !no_headers
  1199. && arg == END
  1200. && end_pos - start_pos >= 6
  1201. && (STRNCASEEQ ((char *) output_paragraph + start_pos, "*Note:", 6)
  1202. || STRNCASEEQ ((char *) output_paragraph + start_pos, "*Note ", 6))
  1203. )
  1204. {
  1205. /* Translators: "Note:" is literal here and should not be
  1206. translated. A document with @strong{Nota}, say, is fine. */
  1207. warning (_("@strong{Note...} produces a spurious cross-reference in Info; reword to avoid that"));
  1208. /* Adjust the output to avoid writing the bad xref. */
  1209. output_paragraph[start_pos + 5] = '_';
  1210. }
  1211. }
  1212. void
  1213. cm_cite (int arg, int position)
  1214. {
  1215. if (xml)
  1216. xml_insert_element (CITE, arg);
  1217. else if (html)
  1218. insert_html_tag (arg, "cite");
  1219. else
  1220. {
  1221. if (arg == START)
  1222. add_char ('`');
  1223. else if (!looking_at ("}'"))
  1224. /* In the simple case of, e.g., ... @cite{Foo}'s ...
  1225. don't output a double ''. */
  1226. add_char ('\'');
  1227. }
  1228. }
  1229. /* No highlighting, but argument switches fonts. */
  1230. void
  1231. cm_not_fixed_width (int arg, int start, int end)
  1232. {
  1233. if (xml)
  1234. xml_insert_element (NOTFIXEDWIDTH, arg);
  1235. not_fixed_width (arg);
  1236. }
  1237. void
  1238. cm_i (int arg)
  1239. {
  1240. /* Make use of <lineannotation> of Docbook, if we are
  1241. inside an @example or similar. */
  1242. if (docbook && !filling_enabled && !printing_index)
  1243. xml_insert_element (LINEANNOTATION, arg);
  1244. else if (xml)
  1245. xml_insert_element (I, arg);
  1246. else if (html)
  1247. insert_html_tag (arg, "i");
  1248. else
  1249. not_fixed_width (arg);
  1250. }
  1251. void
  1252. cm_slanted (int arg)
  1253. {
  1254. /* Make use of <lineannotation> of Docbook, if we are
  1255. inside an @example or similar. */
  1256. if (docbook && !filling_enabled && !printing_index)
  1257. xml_insert_element (LINEANNOTATION, arg);
  1258. else if (xml)
  1259. xml_insert_element (SLANTED, arg);
  1260. else if (html)
  1261. insert_html_tag (arg, "i");
  1262. else
  1263. not_fixed_width (arg);
  1264. }
  1265. void
  1266. cm_b (int arg)
  1267. {
  1268. /* See cm_i comments. */
  1269. if (docbook && !filling_enabled && !printing_index)
  1270. xml_insert_element (LINEANNOTATION, arg);
  1271. else if (docbook && arg == START)
  1272. xml_insert_element_with_attribute (B, arg, "role=\"bold\"");
  1273. else if (xml)
  1274. xml_insert_element (B, arg);
  1275. else if (html)
  1276. insert_html_tag (arg, "b");
  1277. else
  1278. not_fixed_width (arg);
  1279. }
  1280. void
  1281. cm_r (int arg)
  1282. {
  1283. /* See cm_i comments. */
  1284. if (docbook && !filling_enabled && !printing_index)
  1285. xml_insert_element (LINEANNOTATION, arg);
  1286. else if (xml)
  1287. xml_insert_element (R, arg);
  1288. else if (html)
  1289. insert_html_tag_with_attribute (arg, "span", "class=\"roman\"");
  1290. else
  1291. not_fixed_width (arg);
  1292. }
  1293. void
  1294. cm_sansserif (int arg)
  1295. {
  1296. /* See cm_i comments. */
  1297. if (docbook && !filling_enabled && !printing_index)
  1298. xml_insert_element (LINEANNOTATION, arg);
  1299. else if (xml)
  1300. xml_insert_element (SANSSERIF, arg);
  1301. else if (html)
  1302. insert_html_tag_with_attribute (arg, "span", "class=\"sansserif\"");
  1303. else
  1304. not_fixed_width (arg);
  1305. }
  1306. void
  1307. cm_titlefont (int arg)
  1308. {
  1309. if (xml)
  1310. xml_insert_element (TITLEFONT, arg);
  1311. else
  1312. {
  1313. not_fixed_width (arg);
  1314. if (html)
  1315. {
  1316. html_title_written = 1; /* suppress title from @settitle */
  1317. if (arg == START)
  1318. add_word ("<h1 class=\"titlefont\">");
  1319. else
  1320. add_word ("</h1>\n");
  1321. }
  1322. }
  1323. }
  1324. /* Unfortunately, we cannot interpret @math{} contents like TeX does. We just
  1325. pass them through. */
  1326. void
  1327. cm_math (int arg)
  1328. {
  1329. if (xml && !docbook)
  1330. xml_insert_element (MATH, arg);
  1331. }
  1332. /* Various commands are no-op's. */
  1333. void
  1334. cm_no_op (void)
  1335. {
  1336. }
  1337. /* For proofing single chapters, etc. */
  1338. void
  1339. cm_novalidate (void)
  1340. {
  1341. validating = 0;
  1342. }
  1343. /* Prevent the argument from being split across two lines. */
  1344. void
  1345. cm_w (int arg)
  1346. {
  1347. if (arg == START)
  1348. non_splitting_words++;
  1349. else
  1350. {
  1351. if (docbook || html || xml)
  1352. /* This is so @w{$}Log$ doesn't end up as <dollar>Log<dollar>
  1353. in the output. */
  1354. insert_string ("<!-- /@w -->");
  1355. non_splitting_words--;
  1356. }
  1357. }
  1358. /* An unbreakable word space. Same as @w{ } for makeinfo, but different
  1359. for TeX (the space stretches and stretches, and does not inhibit
  1360. hyphenation). For XML and HTML, insert the non-breaking-space
  1361. character and entity, respectively */
  1362. void
  1363. cm_tie (int arg)
  1364. {
  1365. if (arg == START)
  1366. if (html)
  1367. insert_string ("&nbsp;");
  1368. else if (xml)
  1369. insert_string ("&#xa0;");
  1370. else
  1371. {
  1372. cm_w (START);
  1373. add_char (' ');
  1374. }
  1375. else
  1376. if (!html && !xml) cm_w (END);
  1377. }
  1378. /* Explain that this command is obsolete, thus the user shouldn't
  1379. do anything with it. */
  1380. static void
  1381. cm_obsolete (int arg, int start, int end)
  1382. {
  1383. if (arg == START)
  1384. warning (_("%c%s is obsolete"), COMMAND_PREFIX, command);
  1385. }
  1386. /* Inhibit the indentation of the next paragraph, but not of following
  1387. paragraphs. */
  1388. void
  1389. cm_noindent (void)
  1390. {
  1391. if (!inhibit_paragraph_indentation)
  1392. inhibit_paragraph_indentation = -1;
  1393. }
  1394. void
  1395. cm_noindent_cmd (void)
  1396. {
  1397. cm_noindent ();
  1398. xml_no_indent = 1;
  1399. skip_whitespace_and_newlines();
  1400. if (xml)
  1401. xml_start_para ();
  1402. else if (html && !paragraph_is_open)
  1403. add_html_block_elt ("<p class=\"noindent\">");
  1404. else
  1405. {
  1406. paragraph_is_open = 0;
  1407. start_paragraph ();
  1408. }
  1409. }
  1410. /* Force indentation of the next paragraph. */
  1411. void
  1412. cm_indent (void)
  1413. {
  1414. inhibit_paragraph_indentation = 0;
  1415. xml_no_indent = 0;
  1416. skip_whitespace_and_newlines();
  1417. if (xml)
  1418. xml_start_para ();
  1419. else if (html && !paragraph_is_open)
  1420. add_html_block_elt ("<p class=\"indent\">");
  1421. else
  1422. start_paragraph ();
  1423. }
  1424. /* I don't know exactly what to do with this. Should I allow
  1425. someone to switch filenames in the middle of output? Since the
  1426. file could be partially written, this doesn't seem to make sense.
  1427. Another option: ignore it, since they don't really want to
  1428. switch files. Finally, complain, or at least warn. It doesn't
  1429. really matter, anyway, since this doesn't get executed. */
  1430. void
  1431. cm_setfilename (void)
  1432. {
  1433. char *filename;
  1434. get_rest_of_line (1, &filename);
  1435. /* warning ("`@%s %s' encountered and ignored", command, filename); */
  1436. if (xml)
  1437. add_word_args ("<setfilename>%s</setfilename>", filename);
  1438. free (filename);
  1439. }
  1440. void
  1441. cm_settitle (void)
  1442. {
  1443. if (xml)
  1444. {
  1445. xml_insert_element (SETTITLE, START);
  1446. xml_in_book_title = 1;
  1447. get_rest_of_line (0, &title);
  1448. execute_string ("%s", title);
  1449. xml_in_book_title = 0;
  1450. xml_insert_element (SETTITLE, END);
  1451. }
  1452. else
  1453. get_rest_of_line (0, &title);
  1454. }
  1455. /* Ignore argument in braces. */
  1456. void
  1457. cm_ignore_arg (int arg, int start_pos, int end_pos)
  1458. {
  1459. if (arg == END)
  1460. output_paragraph_offset = start_pos;
  1461. }
  1462. /* Ignore argument on rest of line. */
  1463. void
  1464. cm_ignore_line (void)
  1465. {
  1466. discard_until ("\n");
  1467. }
  1468. /* Insert the number of blank lines passed as argument. */
  1469. void
  1470. cm_sp (void)
  1471. {
  1472. int lines;
  1473. char *line;
  1474. /* Due to tricky stuff in execute_string(), @value{} can't be expanded.
  1475. So there is really no reason to enable expansion for @sp parameters. */
  1476. get_rest_of_line (0, &line);
  1477. if (sscanf (line, "%d", &lines) != 1 || lines <= 0)
  1478. line_error (_("@sp requires a positive numeric argument, not `%s'"), line);
  1479. else
  1480. {
  1481. if (xml)
  1482. {
  1483. /* @sp can appear between @item and @itemx, @deffn and @deffnx. */
  1484. xml_dont_touch_items_defs++;
  1485. xml_insert_element_with_attribute (SP, START, "lines=\"%s\"", line);
  1486. /* insert_string (line);*/
  1487. xml_insert_element (SP, END);
  1488. xml_dont_touch_items_defs--;
  1489. }
  1490. else
  1491. {
  1492. /* Must disable filling since otherwise multiple newlines is like
  1493. multiple spaces. Must close paragraph since that's what the
  1494. manual says and that's what TeX does. */
  1495. int save_filling_enabled = filling_enabled;
  1496. filling_enabled = 0;
  1497. /* close_paragraph generates an extra blank line. */
  1498. close_single_paragraph ();
  1499. if (html)
  1500. add_html_block_elt ("<pre class=\"sp\">\n");
  1501. while (lines--)
  1502. add_char ('\n');
  1503. if (html)
  1504. add_html_block_elt ("</pre>\n");
  1505. filling_enabled = save_filling_enabled;
  1506. }
  1507. }
  1508. free (line);
  1509. }
  1510. /* @dircategory LINE outputs INFO-DIR-SECTION LINE, unless --no-headers. */
  1511. void
  1512. cm_dircategory (void)
  1513. {
  1514. char *line;
  1515. if (html || docbook)
  1516. cm_ignore_line ();
  1517. else if (xml)
  1518. {
  1519. xml_insert_element (DIRCATEGORY, START);
  1520. get_rest_of_line (1, &line);
  1521. insert_string (line);
  1522. free (line);
  1523. xml_insert_element (DIRCATEGORY, END);
  1524. }
  1525. else
  1526. {
  1527. get_rest_of_line (1, &line);
  1528. if (!no_headers && !html)
  1529. {
  1530. /* use add_* instead of insert_* because otherwise the
  1531. file header ("This is ...") will end up inside the
  1532. dir section markers. */
  1533. kill_self_indent (-1); /* make sure there's no indentation */
  1534. cm_noindent (); /* make sure again */
  1535. add_word ("INFO-DIR-SECTION ");
  1536. add_word (line);
  1537. close_single_paragraph (); /* newline */
  1538. }
  1539. free (line);
  1540. }
  1541. }
  1542. /* Start a new line with just this text on it.
  1543. Then center the line of text.
  1544. */
  1545. void
  1546. cm_center (void)
  1547. {
  1548. if (xml)
  1549. {
  1550. char *line;
  1551. xml_insert_element (CENTER, START);
  1552. get_rest_of_line (0, &line);
  1553. execute_string ("%s", line);
  1554. free (line);
  1555. xml_insert_element (CENTER, END);
  1556. }
  1557. else
  1558. {
  1559. int i, start, length, width;
  1560. char *line;
  1561. int save_indented_fill = indented_fill;
  1562. int save_filling_enabled = filling_enabled;
  1563. int fudge_factor = 1;
  1564. filling_enabled = indented_fill = 0;
  1565. cm_noindent ();
  1566. start = output_paragraph_offset;
  1567. if (html)
  1568. add_html_block_elt ("<div align=\"center\">");
  1569. inhibit_output_flushing ();
  1570. get_rest_of_line (0, &line);
  1571. execute_string ("%s", line);
  1572. free (line);
  1573. uninhibit_output_flushing ();
  1574. if (html)
  1575. add_html_block_elt ("</div>");
  1576. else
  1577. {
  1578. i = output_paragraph_offset - 1;
  1579. while (i > (start - 1) && output_paragraph[i] == '\n')
  1580. i--;
  1581. output_paragraph_offset = ++i;
  1582. length = output_paragraph_offset - start;
  1583. width = mbsnwidth ((char *)(output_paragraph + start), length, 0);
  1584. if (width < (fill_column - fudge_factor))
  1585. {
  1586. line = xmalloc (1 + length);
  1587. memcpy (line, (char *)(output_paragraph + start), length);
  1588. i = (fill_column - fudge_factor - width) / 2;
  1589. output_paragraph_offset = start;
  1590. while (i--)
  1591. insert (' ');
  1592. for (i = 0; i < length; i++)
  1593. insert (line[i]);
  1594. free (line);
  1595. }
  1596. }
  1597. insert ('\n');
  1598. filling_enabled = save_filling_enabled;
  1599. indented_fill = save_indented_fill;
  1600. close_single_paragraph ();
  1601. if (looking_at ("\n"))
  1602. insert ('\n');
  1603. }
  1604. }
  1605. /* Define what @click{} does. */
  1606. static char *click_command = "@arrow";
  1607. void
  1608. cm_clickstyle (void)
  1609. {
  1610. click_command = get_item_function ();
  1611. if (looking_at ("\n"))
  1612. {
  1613. input_text_offset++;
  1614. line_number++;
  1615. }
  1616. }
  1617. /* @clicksequence{File @click{} Open} */
  1618. void
  1619. cm_clicksequence (int arg)
  1620. {
  1621. if (xml)
  1622. xml_insert_element (CLICKSEQUENCE, arg);
  1623. }
  1624. void
  1625. cm_click (int arg)
  1626. {
  1627. if (xml)
  1628. xml_insert_element (CLICK, arg);
  1629. else if (arg == END)
  1630. execute_string ("%s{}", click_command);
  1631. }
  1632. /* Generic right arrow, default clickstyle. */
  1633. void
  1634. cm_arrow (int arg)
  1635. {
  1636. if (arg == END)
  1637. if (html || xml)
  1638. xml_insert_entity ("rarr");
  1639. else
  1640. add_word ("->");
  1641. }
  1642. /* Show what an expression returns. */
  1643. void
  1644. cm_result (int arg)
  1645. {
  1646. if (arg == END)
  1647. if (html || xml)
  1648. xml_insert_entity ("rArr");
  1649. else
  1650. add_word ("=>");
  1651. }
  1652. /* What an expression expands to. */
  1653. void
  1654. cm_expansion (int arg)
  1655. {
  1656. if (arg == END)
  1657. add_word (html ? "==&gt;" : "==>");
  1658. }
  1659. /* Indicates two expressions are equivalent. */
  1660. void
  1661. cm_equiv (int arg)
  1662. {
  1663. if (arg == END)
  1664. add_word ("==");
  1665. }
  1666. /* What an expression may print. */
  1667. void
  1668. cm_print (int arg)
  1669. {
  1670. if (arg == END)
  1671. add_word ("-|");
  1672. }
  1673. /* An error signaled. */
  1674. void
  1675. cm_error (int arg)
  1676. {
  1677. if (arg == END)
  1678. add_word (html ? "error--&gt;" : "error-->");
  1679. }
  1680. /* The location of point in an example of a buffer. */
  1681. void
  1682. cm_point (int arg)
  1683. {
  1684. if (arg == END)
  1685. add_word ("-!-");
  1686. }
  1687. /* @exdent: Start a new line with just this text on it.
  1688. The text is outdented one level if possible. */
  1689. void
  1690. cm_exdent (void)
  1691. {
  1692. char *line;
  1693. int save_indent = current_indent;
  1694. int save_in_fixed_width_font = in_fixed_width_font;
  1695. /* Read argument. */
  1696. get_rest_of_line (0, &line);
  1697. /* Exdent the output. Actually this may be a no-op. */
  1698. if (current_indent)
  1699. current_indent -= default_indentation_increment;
  1700. /* @exdent arg is supposed to be in roman. */
  1701. in_fixed_width_font = 0;
  1702. /* The preceding newline already inserted the `current_indent'.
  1703. Remove one level's worth. */
  1704. kill_self_indent (default_indentation_increment);
  1705. if (html)
  1706. add_word ("<br>");
  1707. else if (docbook)
  1708. xml_insert_element (LINEANNOTATION, START);
  1709. else if (xml)
  1710. xml_insert_element (EXDENT, START);
  1711. /* Can't close_single_paragraph, then we lose preceding blank lines. */
  1712. flush_output ();
  1713. execute_string ("%s", line);
  1714. free (line);
  1715. if (html)
  1716. add_word ("<br>");
  1717. else if (xml)
  1718. {
  1719. xml_insert_element (docbook ? LINEANNOTATION : EXDENT, END);
  1720. insert ('\n');
  1721. }
  1722. close_single_paragraph ();
  1723. current_indent = save_indent;
  1724. in_fixed_width_font = save_in_fixed_width_font;
  1725. if (!xml)
  1726. start_paragraph ();
  1727. }
  1728. /*
  1729. Read include-filename, process the include-file:
  1730. verbatim_include == 0: process through reader_loop
  1731. verbatim_include != 0: process through handle_verbatim_environment
  1732. */
  1733. static void
  1734. handle_include (int verbatim_include)
  1735. {
  1736. char *arg, *filename;
  1737. if (macro_expansion_output_stream && !executing_string)
  1738. me_append_before_this_command ();
  1739. if (!insertion_stack)
  1740. close_paragraph (); /* No blank lines etc. if not at outer level. */
  1741. if (macro_expansion_output_stream && verbatim_include)
  1742. {
  1743. me_append_before_this_command ();
  1744. return;
  1745. }
  1746. get_rest_of_line (0, &arg);
  1747. /* We really only want to expand @value, but it's easier to just do
  1748. everything. TeX will only work with @value. */
  1749. {
  1750. int save_in_fixed_width_font = in_fixed_width_font;
  1751. in_fixed_width_font = 1; /* do not change -- to -, etc. */
  1752. filename = text_expansion (arg);
  1753. in_fixed_width_font = save_in_fixed_width_font;
  1754. }
  1755. free (arg);
  1756. if (macro_expansion_output_stream && !executing_string)
  1757. remember_itext (input_text, input_text_offset);
  1758. pushfile ();
  1759. /* In verbose mode we print info about including another file. */
  1760. if (verbose_mode)
  1761. {
  1762. int i = 0;
  1763. FSTACK *stack = filestack;
  1764. for (i = 0, stack = filestack; stack; stack = stack->next, i++);
  1765. i *= 2;
  1766. printf ("%*s", i, "");
  1767. printf ("%c%s `%s'\n", COMMAND_PREFIX, command, filename);
  1768. fflush (stdout);
  1769. }
  1770. if (!find_and_load (filename, 1))
  1771. {
  1772. popfile ();
  1773. line_number--;
  1774. /* /wh/bar:5: @include/@verbatiminclude `foo': No such file or dir */
  1775. line_error ("%c%s `%s': %s", COMMAND_PREFIX, command, filename,
  1776. strerror (errno));
  1777. free (filename);
  1778. return;
  1779. }
  1780. else
  1781. {
  1782. if (macro_expansion_output_stream && !executing_string)
  1783. remember_itext (input_text, input_text_offset);
  1784. if (!verbatim_include)
  1785. reader_loop ();
  1786. else
  1787. handle_verbatim_environment (0);
  1788. }
  1789. free (filename);
  1790. popfile ();
  1791. }
  1792. /* Include file as if put in @verbatim environment */
  1793. void
  1794. cm_verbatiminclude (void)
  1795. {
  1796. handle_include (1);
  1797. }
  1798. /* Remember this file, and move onto the next. */
  1799. void
  1800. cm_include (void)
  1801. {
  1802. handle_include (0);
  1803. }
  1804. /* @bye: Signals end of processing. Easy to make this happen. */
  1805. void
  1806. cm_bye (void)
  1807. {
  1808. discard_braces (); /* should not have any unclosed braces left */
  1809. input_text_offset = input_text_length;
  1810. }
  1811. /* @paragraphindent */
  1812. static void
  1813. cm_paragraphindent (void)
  1814. {
  1815. char *arg;
  1816. get_rest_of_line (1, &arg);
  1817. if (set_paragraph_indent (arg) != 0)
  1818. line_error (_("Bad argument to %c%s"), COMMAND_PREFIX, command);
  1819. free (arg);
  1820. }
  1821. /* @exampleindent: change indentation of example-like environments. */
  1822. static int
  1823. set_example_indentation_increment (char *string)
  1824. {
  1825. if (strcmp (string, "asis") == 0 || strcmp (string, _("asis")) == 0)
  1826. ;
  1827. else if (strcmp (string, "none") == 0 || strcmp (string, _("none")) == 0)
  1828. example_indentation_increment = 0;
  1829. else if (sscanf (string, "%d", &example_indentation_increment) != 1)
  1830. return -1;
  1831. return 0;
  1832. }
  1833. static void
  1834. cm_exampleindent (void)
  1835. {
  1836. char *arg;
  1837. get_rest_of_line (1, &arg);
  1838. if (set_example_indentation_increment (arg) != 0)
  1839. line_error (_("Bad argument to @%s"), command);
  1840. if (input_text[input_text_offset] == '\n')
  1841. close_single_paragraph ();
  1842. free (arg);
  1843. }
  1844. /* @firstparagraphindent: suppress indentation in first paragraphs after
  1845. headings. */
  1846. static int
  1847. set_firstparagraphindent (char *string)
  1848. {
  1849. if (STREQ (string, "insert") || STREQ (string, _("insert")))
  1850. do_first_par_indent = 1;
  1851. else if (STREQ (string, "none") || STREQ (string, _("none")))
  1852. do_first_par_indent = 0;
  1853. else
  1854. return -1;
  1855. return 0;
  1856. }
  1857. static void
  1858. cm_firstparagraphindent (void)
  1859. {
  1860. char *arg;
  1861. get_rest_of_line (1, &arg);
  1862. if (set_firstparagraphindent (arg) != 0)
  1863. line_error (_("Bad argument to @%s: %s"), command, arg);
  1864. free (arg);
  1865. }
  1866. /* For DocBook and XML, produce &period; for `.@:'. This gives the processing
  1867. software a fighting chance to treat it specially by not adding extra space.
  1868. Do this also for ?, !, and :. */
  1869. void
  1870. cm_colon (void)
  1871. {
  1872. if (xml)
  1873. {
  1874. if (strchr (".?!:", input_text[input_text_offset-3]) != NULL)
  1875. {
  1876. /* Erase literal character that's there, except `>', which is
  1877. part of the XML tag. */
  1878. if (output_paragraph_offset > 0
  1879. && output_paragraph[output_paragraph_offset-1] != '>')
  1880. output_paragraph_offset--;
  1881. switch (input_text[input_text_offset-3])
  1882. {
  1883. case '.':
  1884. xml_insert_entity ("period");
  1885. break;
  1886. case '?':
  1887. xml_insert_entity ("quest");
  1888. break;
  1889. case '!':
  1890. xml_insert_entity ("excl");
  1891. break;
  1892. case ':':
  1893. xml_insert_entity ("colon");
  1894. break;
  1895. }
  1896. }
  1897. }
  1898. }
  1899. /* Ending sentences explicitly. Currently, only outputs entities for XML
  1900. output, for other formats it calls insert_self. */
  1901. void
  1902. cm_punct (int arg)
  1903. {
  1904. if (xml && !docbook && input_text_offset > 0)
  1905. {
  1906. switch (input_text[input_text_offset-1])
  1907. {
  1908. case '.':
  1909. xml_insert_entity ("eosperiod");
  1910. break;
  1911. case '?':
  1912. xml_insert_entity ("eosquest");
  1913. break;
  1914. case '!':
  1915. xml_insert_entity ("eosexcl");
  1916. break;
  1917. }
  1918. }
  1919. else
  1920. {
  1921. insert_self (arg);
  1922. }
  1923. }
  1924. /* If @frenchspacing is in effect, avoid outputting extra spaces after
  1925. sentence-ending periods. Actually, we explicitly do this only in one
  1926. tiny case (see add_char in makeinfo.c). Usually we just output
  1927. whatever the user gives us. */
  1928. void
  1929. cm_frenchspacing (void)
  1930. {
  1931. char *val;
  1932. get_rest_of_line (1, &val);
  1933. if (STREQ (val, "on")) {
  1934. french_spacing = 1;
  1935. } else if (STREQ (val, "off")) {
  1936. french_spacing = 0;
  1937. } else {
  1938. line_error (_("Expected @%s on or off, not `%s'"), command, val);
  1939. }
  1940. if (xml && !docbook) {
  1941. xml_insert_element_with_attribute (FRENCHSPACING, START,
  1942. "val=\"%s\"", val);
  1943. xml_insert_element (FRENCHSPACING, END);
  1944. }
  1945. }
  1946. /* Body font size. This is only for TeX, so we're just checking
  1947. validity here. Don't think we should even pass it on to XML. */
  1948. void
  1949. cm_fonttextsize (void)
  1950. {
  1951. char *val;
  1952. get_rest_of_line (1, &val);
  1953. if (! (STREQ (val, "10") || STREQ (val, "off"))) {
  1954. line_error (_("Only @%s 10 or 11 is supported, not `%s'"), command, val);
  1955. }
  1956. }