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