cmds.c revision 100513
1/* cmds.c -- Texinfo commands. 2 $Id: cmds.c,v 1.79 2002/03/28 16:35:29 karl Exp $ 3 4 Copyright (C) 1998, 99, 2000, 01, 02 Free Software Foundation, Inc. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software Foundation, 18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 19 20#include "system.h" 21#include "cmds.h" 22#include "defun.h" 23#include "files.h" 24#include "footnote.h" 25#include "insertion.h" 26#include "lang.h" 27#include "macro.h" 28#include "makeinfo.h" 29#include "node.h" 30#include "sectioning.h" 31#include "toc.h" 32#include "xml.h" 33 34#ifdef TM_IN_SYS_TIME 35#include <sys/time.h> 36#else 37#include <time.h> 38#endif 39 40 41void insert_self (), insert_space (), cm_ignore_line (), cm_ignore_arg (); 42 43void 44 cm_TeX (), cm_acronym (), cm_asterisk (), cm_b (), cm_bullet (), cm_cite (), 45 cm_code (), cm_copyright (), cm_ctrl (), cm_dfn (), cm_dircategory (), 46 cm_direntry (), cm_dmn (), cm_dots (), cm_emph (), cm_enddots (), cm_i (), 47 cm_image (), cm_kbd (), cm_key (), cm_no_op (), 48 cm_novalidate (), cm_not_fixed_width (), cm_r (), 49 cm_strong (), cm_var (), cm_sc (), cm_w (), cm_email (), cm_url (), 50 cm_verb (), cm_copying (), cm_insert_copying (), 51 cm_documentdescription (); 52 53void 54 cm_anchor (), cm_node (), cm_menu (), cm_xref (), cm_ftable (), 55 cm_vtable (), cm_pxref (), cm_inforef (), cm_uref (), cm_email (), 56 cm_quotation (), cm_display (), cm_smalldisplay (), cm_itemize (), 57 cm_enumerate (), cm_tab (), cm_table (), cm_itemx (), cm_noindent (), 58 cm_setfilename (), cm_br (), cm_sp (), cm_page (), cm_group (), 59 cm_center (), cm_ref (), cm_include (), cm_bye (), cm_item (), cm_end (), 60 cm_kindex (), cm_cindex (), cm_findex (), cm_pindex (), cm_vindex (), 61 cm_tindex (), cm_synindex (), cm_printindex (), cm_minus (), 62 cm_example (), cm_smallexample (), cm_smalllisp (), cm_lisp (), 63 cm_format (), cm_smallformat (), cm_exdent (), cm_defindex (), 64 cm_defcodeindex (), cm_result (), cm_expansion (), cm_equiv (), 65 cm_print (), cm_error (), cm_point (), cm_today (), cm_flushleft (), 66 cm_flushright (), cm_finalout (), cm_cartouche (), cm_detailmenu (), 67 cm_multitable (), cm_settitle (), cm_titlefont (), cm_tt (), 68 cm_verbatim (), cm_verbatiminclude (); 69 70/* Conditionals. */ 71void cm_set (), cm_clear (), cm_ifset (), cm_ifclear (); 72void cm_value (), cm_ifeq (); 73 74/* Options. */ 75static void cm_paragraphindent (), cm_exampleindent (); 76 77/* Internals. */ 78static void cm_obsolete (); 79 80/* A random string. */ 81static const char small_tag[] = "small"; 82 83/* The dispatch table. */ 84COMMAND command_table[] = { 85 { "\t", insert_space, NO_BRACE_ARGS }, 86 { "\n", insert_space, NO_BRACE_ARGS }, 87 { " ", insert_space, NO_BRACE_ARGS }, 88 { "!", insert_self, NO_BRACE_ARGS }, 89 { "\"", cm_accent_umlaut, MAYBE_BRACE_ARGS }, 90 { "'", cm_accent_acute, MAYBE_BRACE_ARGS }, 91 { "*", cm_asterisk, NO_BRACE_ARGS }, 92 { ",", cm_accent_cedilla, MAYBE_BRACE_ARGS }, 93 { "-", cm_no_op, NO_BRACE_ARGS }, 94 { ".", insert_self, NO_BRACE_ARGS }, 95 { ":", cm_no_op, NO_BRACE_ARGS }, 96 { "=", cm_accent, MAYBE_BRACE_ARGS }, 97 { "?", insert_self, NO_BRACE_ARGS }, 98 { "@", insert_self, NO_BRACE_ARGS }, 99 { "\\", insert_self, NO_BRACE_ARGS }, 100 { "^", cm_accent_hat, MAYBE_BRACE_ARGS }, 101 { "`", cm_accent_grave, MAYBE_BRACE_ARGS }, 102 { "{", insert_self, NO_BRACE_ARGS }, 103 { "|", cm_no_op, NO_BRACE_ARGS }, 104 { "}", insert_self, NO_BRACE_ARGS }, 105 { "~", cm_accent_tilde, MAYBE_BRACE_ARGS }, 106 { "AA", cm_special_char, BRACE_ARGS }, 107 { "AE", cm_special_char, BRACE_ARGS }, 108 { "H", cm_accent, MAYBE_BRACE_ARGS }, 109 { "L", cm_special_char, BRACE_ARGS }, 110 { "O", cm_special_char, BRACE_ARGS }, 111 { "OE", cm_special_char, BRACE_ARGS }, 112 { "TeX", cm_TeX, BRACE_ARGS }, 113 { "aa", cm_special_char, BRACE_ARGS }, 114 { "acronym", cm_acronym, BRACE_ARGS }, 115 { "ae", cm_special_char, BRACE_ARGS }, 116 { "afivepaper", cm_ignore_line, NO_BRACE_ARGS }, 117 { "afourlatex", cm_ignore_line, NO_BRACE_ARGS }, 118 { "afourpaper", cm_ignore_line, NO_BRACE_ARGS }, 119 { "afourwide", cm_ignore_line, NO_BRACE_ARGS }, 120 { "alias", cm_alias, NO_BRACE_ARGS }, 121 { "anchor", cm_anchor, BRACE_ARGS }, 122 { "appendix", cm_appendix, NO_BRACE_ARGS }, 123 { "appendixsection", cm_appendixsec, NO_BRACE_ARGS }, 124 { "appendixsec", cm_appendixsec, NO_BRACE_ARGS }, 125 { "appendixsubsec", cm_appendixsubsec, NO_BRACE_ARGS }, 126 { "appendixsubsubsec", cm_appendixsubsubsec, NO_BRACE_ARGS }, 127 { "asis", cm_no_op, BRACE_ARGS }, 128 { "b", cm_b, BRACE_ARGS }, 129 { "bullet", cm_bullet, BRACE_ARGS }, 130 { "bye", cm_bye, NO_BRACE_ARGS }, 131 { "c", cm_ignore_line, NO_BRACE_ARGS }, 132 { "cartouche", cm_cartouche, NO_BRACE_ARGS }, 133 { "center", cm_center, NO_BRACE_ARGS }, 134 { "centerchap", cm_unnumbered, NO_BRACE_ARGS }, 135 { "chapheading", cm_chapheading, NO_BRACE_ARGS }, 136 { "chapter", cm_chapter, NO_BRACE_ARGS }, 137 { "cindex", cm_cindex, NO_BRACE_ARGS }, 138 { "cite", cm_cite, BRACE_ARGS }, 139 { "clear", cm_clear, NO_BRACE_ARGS }, 140 { "code", cm_code, BRACE_ARGS }, 141 { "command", cm_code, BRACE_ARGS }, 142 { "comment", cm_ignore_line, NO_BRACE_ARGS }, 143 { "contents", cm_contents, NO_BRACE_ARGS }, 144 { "copying", cm_copying, NO_BRACE_ARGS }, 145 { "copyright", cm_copyright, BRACE_ARGS }, 146 { "ctrl", cm_obsolete, BRACE_ARGS }, 147 { "defcodeindex", cm_defcodeindex, NO_BRACE_ARGS }, 148 { "defcv", cm_defun, NO_BRACE_ARGS }, 149 { "defcvx", cm_defun, NO_BRACE_ARGS }, 150 { "deffn", cm_defun, NO_BRACE_ARGS }, 151 { "deffnx", cm_defun, NO_BRACE_ARGS }, 152 { "defindex", cm_defindex, NO_BRACE_ARGS }, 153 { "definfoenclose", cm_definfoenclose, NO_BRACE_ARGS }, 154 { "defivar", cm_defun, NO_BRACE_ARGS }, 155 { "defivarx", cm_defun, NO_BRACE_ARGS }, 156 { "defmac", cm_defun, NO_BRACE_ARGS }, 157 { "defmacx", cm_defun, NO_BRACE_ARGS }, 158 { "defmethod", cm_defun, NO_BRACE_ARGS }, 159 { "defmethodx", cm_defun, NO_BRACE_ARGS }, 160 { "defop", cm_defun, NO_BRACE_ARGS }, 161 { "defopt", cm_defun, NO_BRACE_ARGS }, 162 { "defoptx", cm_defun, NO_BRACE_ARGS }, 163 { "defopx", cm_defun, NO_BRACE_ARGS }, 164 { "defspec", cm_defun, NO_BRACE_ARGS }, 165 { "defspecx", cm_defun, NO_BRACE_ARGS }, 166 { "deftp", cm_defun, NO_BRACE_ARGS }, 167 { "deftpx", cm_defun, NO_BRACE_ARGS }, 168 { "deftypefn", cm_defun, NO_BRACE_ARGS }, 169 { "deftypefnx", cm_defun, NO_BRACE_ARGS }, 170 { "deftypefun", cm_defun, NO_BRACE_ARGS }, 171 { "deftypefunx", cm_defun, NO_BRACE_ARGS }, 172 { "deftypeivar", cm_defun, NO_BRACE_ARGS }, 173 { "deftypeivarx", cm_defun, NO_BRACE_ARGS }, 174 { "deftypemethod", cm_defun, NO_BRACE_ARGS }, 175 { "deftypemethodx", cm_defun, NO_BRACE_ARGS }, 176 { "deftypeop", cm_defun, NO_BRACE_ARGS }, 177 { "deftypeopx", cm_defun, NO_BRACE_ARGS }, 178 { "deftypevar", cm_defun, NO_BRACE_ARGS }, 179 { "deftypevarx", cm_defun, NO_BRACE_ARGS }, 180 { "deftypevr", cm_defun, NO_BRACE_ARGS }, 181 { "deftypevrx", cm_defun, NO_BRACE_ARGS }, 182 { "defun", cm_defun, NO_BRACE_ARGS }, 183 { "defunx", cm_defun, NO_BRACE_ARGS }, 184 { "defvar", cm_defun, NO_BRACE_ARGS }, 185 { "defvarx", cm_defun, NO_BRACE_ARGS }, 186 { "defvr", cm_defun, NO_BRACE_ARGS }, 187 { "defvrx", cm_defun, NO_BRACE_ARGS }, 188 { "detailmenu", cm_detailmenu, NO_BRACE_ARGS }, 189 { "dfn", cm_dfn, BRACE_ARGS }, 190 { "dircategory", cm_dircategory, NO_BRACE_ARGS }, 191 { "direntry", cm_direntry, NO_BRACE_ARGS }, 192 { "display", cm_display, NO_BRACE_ARGS }, 193 { "dmn", cm_no_op, BRACE_ARGS }, 194 { "documentdescription", cm_documentdescription, NO_BRACE_ARGS }, 195 { "documentencoding", cm_documentencoding, NO_BRACE_ARGS }, 196 { "documentlanguage", cm_documentlanguage, NO_BRACE_ARGS }, 197 { "dotaccent", cm_accent, MAYBE_BRACE_ARGS }, 198 { "dotless", cm_dotless, BRACE_ARGS }, 199 { "dots", cm_dots, BRACE_ARGS }, 200 { "email", cm_email, BRACE_ARGS }, 201 { "emph", cm_emph, BRACE_ARGS }, 202 { "end", cm_end, NO_BRACE_ARGS }, 203 { "enddots", cm_enddots, BRACE_ARGS }, 204 { "enumerate", cm_enumerate, NO_BRACE_ARGS }, 205 { "env", cm_code, BRACE_ARGS }, 206 { "equiv", cm_equiv, BRACE_ARGS }, 207 { "error", cm_error, BRACE_ARGS }, 208 { "evenfooting", cm_ignore_line, NO_BRACE_ARGS }, 209 { "evenheading", cm_ignore_line, NO_BRACE_ARGS }, 210 { "everyfooting", cm_ignore_line, NO_BRACE_ARGS }, 211 { "everyheading", cm_ignore_line, NO_BRACE_ARGS }, 212 { "example", cm_example, NO_BRACE_ARGS }, 213 { "exampleindent", cm_exampleindent, NO_BRACE_ARGS }, 214 { "exclamdown", cm_special_char, BRACE_ARGS }, 215 { "exdent", cm_exdent, NO_BRACE_ARGS }, 216 { "expansion", cm_expansion, BRACE_ARGS }, 217 { "file", cm_code, BRACE_ARGS }, 218 { "finalout", cm_no_op, NO_BRACE_ARGS }, 219 { "findex", cm_findex, NO_BRACE_ARGS }, 220 { "flushleft", cm_flushleft, NO_BRACE_ARGS }, 221 { "flushright", cm_flushright, NO_BRACE_ARGS }, 222 { "footnote", cm_footnote, NO_BRACE_ARGS}, /* self-arg eater */ 223 { "footnotestyle", cm_footnotestyle, NO_BRACE_ARGS }, 224 { "format", cm_format, NO_BRACE_ARGS }, 225 { "ftable", cm_ftable, NO_BRACE_ARGS }, 226 { "group", cm_group, NO_BRACE_ARGS }, 227 { "heading", cm_heading, NO_BRACE_ARGS }, 228 { "headings", cm_ignore_line, 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 { "ifhtml", cm_ifhtml, NO_BRACE_ARGS }, 235 { "ifinfo", cm_ifinfo, NO_BRACE_ARGS }, 236 { "ifnothtml", cm_ifnothtml, NO_BRACE_ARGS }, 237 { "ifnotinfo", cm_ifnotinfo, NO_BRACE_ARGS }, 238 { "ifnotplaintext", cm_ifnotplaintext, NO_BRACE_ARGS }, 239 { "ifnottex", cm_ifnottex, NO_BRACE_ARGS }, 240 { "ifplaintext", cm_ifplaintext, NO_BRACE_ARGS }, 241 { "ifset", cm_ifset, NO_BRACE_ARGS }, 242 { "iftex", cm_iftex, NO_BRACE_ARGS }, 243 { "ignore", command_name_condition, NO_BRACE_ARGS }, 244 { "image", cm_image, BRACE_ARGS }, 245 { "include", cm_include, NO_BRACE_ARGS }, 246 { "inforef", cm_inforef, BRACE_ARGS }, 247 { "insertcopying", cm_insert_copying, NO_BRACE_ARGS }, 248 { "item", cm_item, NO_BRACE_ARGS }, 249 { "itemize", cm_itemize, NO_BRACE_ARGS }, 250 { "itemx", cm_itemx, NO_BRACE_ARGS }, 251 { "kbd", cm_kbd, BRACE_ARGS }, 252 { "kbdinputstyle", cm_ignore_line, NO_BRACE_ARGS }, 253 { "key", cm_key, BRACE_ARGS }, 254 { "kindex", cm_kindex, NO_BRACE_ARGS }, 255 { "l", cm_special_char, BRACE_ARGS }, 256 { "lisp", cm_lisp, NO_BRACE_ARGS }, 257 { "lowersections", cm_lowersections, NO_BRACE_ARGS }, 258 { "macro", cm_macro, NO_BRACE_ARGS }, 259 { "majorheading", cm_majorheading, NO_BRACE_ARGS }, 260 { "math", cm_no_op, BRACE_ARGS }, 261 { "menu", cm_menu, NO_BRACE_ARGS }, 262 { "minus", cm_minus, BRACE_ARGS }, 263 { "multitable", cm_multitable, NO_BRACE_ARGS }, 264 { "need", cm_ignore_line, NO_BRACE_ARGS }, 265 { "node", cm_node, NO_BRACE_ARGS }, 266 { "noindent", cm_noindent, NO_BRACE_ARGS }, 267 { "noindent", cm_novalidate, NO_BRACE_ARGS }, 268 { "nwnode", cm_node, NO_BRACE_ARGS }, 269 { "o", cm_special_char, BRACE_ARGS }, 270 { "oddfooting", cm_ignore_line, NO_BRACE_ARGS }, 271 { "oddheading", cm_ignore_line, NO_BRACE_ARGS }, 272 { "oe", cm_special_char, BRACE_ARGS }, 273 { "option", cm_code, BRACE_ARGS }, 274 { "page", cm_no_op, NO_BRACE_ARGS }, 275 { "pagesizes", cm_ignore_line, NO_BRACE_ARGS }, 276 { "paragraphindent", cm_paragraphindent, NO_BRACE_ARGS }, 277 { "pindex", cm_pindex, NO_BRACE_ARGS }, 278 { "point", cm_point, BRACE_ARGS }, 279 { "pounds", cm_special_char, BRACE_ARGS }, 280 { "print", cm_print, BRACE_ARGS }, 281 { "printindex", cm_printindex, NO_BRACE_ARGS }, 282 { "pxref", cm_pxref, BRACE_ARGS }, 283 { "questiondown", cm_special_char, BRACE_ARGS }, 284 { "quotation", cm_quotation, NO_BRACE_ARGS }, 285 { "r", cm_r, BRACE_ARGS }, 286 { "raisesections", cm_raisesections, NO_BRACE_ARGS }, 287 { "ref", cm_ref, BRACE_ARGS }, 288 { "refill", cm_no_op, NO_BRACE_ARGS }, 289 { "result", cm_result, BRACE_ARGS }, 290 { "ringaccent", cm_accent, MAYBE_BRACE_ARGS }, 291 { "rmacro", cm_rmacro, NO_BRACE_ARGS }, 292 { "samp", cm_code, BRACE_ARGS }, 293 { "sc", cm_sc, BRACE_ARGS }, 294 { "section", cm_section, NO_BRACE_ARGS }, 295 { "set", cm_set, NO_BRACE_ARGS }, 296 { "setchapternewpage", cm_ignore_line, NO_BRACE_ARGS }, 297 { "setchapterstyle", cm_obsolete, NO_BRACE_ARGS }, 298 { "setcontentsaftertitlepage", cm_no_op, NO_BRACE_ARGS }, 299 { "setfilename", cm_setfilename, NO_BRACE_ARGS }, 300 { "setshortcontentsaftertitlepage", cm_no_op, NO_BRACE_ARGS }, 301 { "settitle", cm_settitle, NO_BRACE_ARGS }, 302 { "shortcontents", cm_shortcontents, NO_BRACE_ARGS }, 303 { "shorttitlepage", cm_ignore_line, NO_BRACE_ARGS }, 304 { "smallbook", cm_ignore_line, NO_BRACE_ARGS }, 305 { "smalldisplay", cm_smalldisplay, NO_BRACE_ARGS }, 306 { "smallexample", cm_smallexample, NO_BRACE_ARGS }, 307 { "smallformat", cm_smallformat, NO_BRACE_ARGS }, 308 { "smalllisp", cm_smalllisp, NO_BRACE_ARGS }, 309 { "sp", cm_sp, NO_BRACE_ARGS }, 310 { "ss", cm_special_char, BRACE_ARGS }, 311 { "strong", cm_strong, BRACE_ARGS }, 312 { "subheading", cm_subheading, NO_BRACE_ARGS }, 313 { "subsection", cm_subsection, NO_BRACE_ARGS }, 314 { "subsubheading", cm_subsubheading, NO_BRACE_ARGS }, 315 { "subsubsection", cm_subsubsection, NO_BRACE_ARGS }, 316 { "summarycontents", cm_shortcontents, NO_BRACE_ARGS }, 317 { "syncodeindex", cm_synindex, NO_BRACE_ARGS }, 318 { "synindex", cm_synindex, NO_BRACE_ARGS }, 319 { "t", cm_tt, BRACE_ARGS }, 320 { "tab", cm_tab, NO_BRACE_ARGS }, 321 { "table", cm_table, NO_BRACE_ARGS }, 322 { "tex", cm_tex, NO_BRACE_ARGS }, 323 { "tieaccent", cm_accent, MAYBE_BRACE_ARGS }, 324 { "tindex", cm_tindex, NO_BRACE_ARGS }, 325 { "titlefont", cm_titlefont, BRACE_ARGS }, 326 { "titlepage", command_name_condition, 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_url, 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 { "w", cm_w, BRACE_ARGS }, 348 { "xref", cm_xref, BRACE_ARGS }, 349 350 /* Deprecated commands. These used to be for italics. */ 351 { "iappendix", cm_ideprecated, NO_BRACE_ARGS }, 352 { "iappendixsec", cm_ideprecated, NO_BRACE_ARGS }, 353 { "iappendixsection", cm_ideprecated, NO_BRACE_ARGS }, 354 { "iappendixsubsec", cm_ideprecated, NO_BRACE_ARGS }, 355 { "iappendixsubsubsec", cm_ideprecated, NO_BRACE_ARGS }, 356 { "ichapter", cm_ideprecated, NO_BRACE_ARGS }, 357 { "isection", cm_ideprecated, NO_BRACE_ARGS }, 358 { "isubsection", cm_ideprecated, NO_BRACE_ARGS }, 359 { "isubsubsection", cm_ideprecated, NO_BRACE_ARGS }, 360 { "iunnumbered", cm_ideprecated, NO_BRACE_ARGS }, 361 { "iunnumberedsec", cm_ideprecated, NO_BRACE_ARGS }, 362 { "iunnumberedsubsec", cm_ideprecated, NO_BRACE_ARGS }, 363 { "iunnumberedsubsubsec", cm_ideprecated, NO_BRACE_ARGS }, 364 365 /* Now @include does what this was used to. */ 366 { "infoinclude", cm_obsolete, NO_BRACE_ARGS }, 367 { "titlespec", cm_obsolete, NO_BRACE_ARGS }, 368 369 { NULL, NULL, NO_BRACE_ARGS } 370}; 371 372/* The bulk of the Texinfo commands. */ 373 374/* Commands which insert their own names. */ 375void 376insert_self (arg) 377 int arg; 378{ 379 if (arg == START) 380 add_word (command); 381} 382 383void 384insert_space (arg) 385 int arg; 386{ 387 if (arg == START) 388 { 389 if (xml && !docbook) 390 xml_insert_entity ("space"); 391 else 392 add_char (' '); 393 } 394} 395 396/* Force a line break in the output. */ 397void 398cm_asterisk () 399{ 400 if (html) 401 add_word ("<br>"); 402 else if (xml && !docbook) 403 xml_insert_entity ("linebreak"); 404 else if (docbook) 405 xml_asterisk (); 406 else 407 { 408 close_single_paragraph (); 409 cm_noindent (); 410 } 411} 412 413/* Insert ellipsis. */ 414void 415cm_dots (arg) 416 int arg; 417{ 418 if (arg == START) 419 { 420 if (xml && !docbook) 421 xml_insert_entity ("dots"); 422 else if (docbook) 423 xml_insert_entity ("hellip"); 424 else 425 add_word (html ? "<small>...</small>" : "..."); 426 } 427} 428 429/* Insert ellipsis for sentence end. */ 430void 431cm_enddots (arg) 432 int arg; 433{ 434 if (arg == START) 435 { 436 if (xml && !docbook) 437 xml_insert_entity ("enddots"); 438 else if (docbook) 439 { 440 xml_insert_entity ("hellip"); 441 add_char ('.'); 442 } 443 else 444 add_word (html ? "<small>...</small>." : "...."); 445 } 446} 447 448void 449cm_bullet (arg) 450 int arg; 451{ 452 if (arg == START) 453 { 454 if (html) 455 add_word ("•"); 456 else if (xml && !docbook) 457 xml_insert_entity ("bullet"); 458 else if (docbook) 459 xml_insert_entity ("bull"); 460 else 461 add_char ('*'); 462 } 463} 464 465void 466cm_minus (arg) 467 int arg; 468{ 469 if (arg == START) 470 { 471 if (xml) 472 xml_insert_entity ("minus"); 473 else 474 add_char ('-'); 475 } 476} 477 478/* Insert "TeX". */ 479void 480cm_TeX (arg) 481 int arg; 482{ 483 if (arg == START) 484 { 485 if (xml && ! docbook) 486 xml_insert_entity ("tex"); 487 else 488 add_word ("TeX"); 489 } 490} 491 492/* Copyright symbol. */ 493void 494cm_copyright (arg) 495 int arg; 496{ 497 if (arg == START) 498 { 499 if (html) 500 add_word ("©"); 501 else if (xml && !docbook) 502 xml_insert_entity ("copyright"); 503 else if (docbook) 504 xml_insert_entity ("copy"); 505 else 506 add_word ("(C)"); 507 } 508} 509 510void 511cm_today (arg) 512 int arg; 513{ 514 static char *months[12] = 515 { N_("January"), N_("February"), N_("March"), N_("April"), N_("May"), 516 N_("June"), N_("July"), N_("August"), N_("September"), N_("October"), 517 N_("November"), N_("December") }; 518 if (arg == START) 519 { 520 time_t timer = time (0); 521 struct tm *ts = localtime (&timer); 522 add_word_args ("%d %s %d", ts->tm_mday, _(months[ts->tm_mon]), 523 ts->tm_year + 1900); 524 } 525} 526 527void 528cm_acronym (arg) 529 int arg; 530{ 531 if (html) 532 insert_html_tag (arg, small_tag); 533 else if (xml) 534 xml_insert_element (ACRONYM, arg); 535} 536 537void 538cm_tt (arg) 539 int arg; 540{ 541 /* @t{} is a no-op in Info. */ 542 if (html) 543 insert_html_tag (arg, "tt"); 544 else if (xml) 545 xml_insert_element (TT, arg); 546} 547 548void 549cm_code (arg) 550 int arg; 551{ 552 if (xml) 553 xml_insert_element (CODE, arg); 554 else 555 { 556 extern int printing_index; 557 558 if (arg == START) 559 { 560 in_fixed_width_font++; 561 562 if (html) 563 insert_html_tag (arg, "code"); 564 else if (!printing_index) 565 add_char ('`'); 566 } 567 else if (html) 568 insert_html_tag (arg, "code"); 569 else 570 { 571 if (!printing_index) 572 add_meta_char ('\''); 573 } 574 } 575} 576 577void 578cm_kbd (arg) 579 int arg; 580{ 581 if (xml) 582 xml_insert_element (KBD, arg); 583 else if (html) 584 { /* Seems like we should increment in_fixed_width_font for Info 585 format too, but then the quote-omitting special case gets 586 confused. Punt. */ 587 if (arg == START) 588 in_fixed_width_font++; 589 insert_html_tag (arg, "kbd"); 590 } 591 else 592 { /* People use @kbd in an example to get the "user input" font. 593 We don't want quotes in that case. */ 594 if (!in_fixed_width_font) 595 cm_code (arg); 596 } 597} 598 599void 600cm_url (arg, start, end) 601{ 602 if (xml) 603 xml_insert_element (URL, arg); 604 else if (html) 605 { 606 if (arg == START) 607 add_word ("<<code>"); 608 else 609 add_word ("</code>>"); 610 } 611 else 612 if (arg == START) 613 add_word ("<"); 614 else 615 add_word (">"); 616} 617 618void 619cm_key (arg) 620 int arg; 621{ 622 if (xml) 623 xml_insert_element (KEY, arg); 624 else if (html) 625 add_word (arg == START ? "<" : ">"); 626 else 627 add_char (arg == START ? '<' : '>'); 628} 629 630/* Handle a command that switches to a non-fixed-width font. */ 631void 632not_fixed_width (arg) 633 int arg; 634{ 635 if (arg == START) 636 in_fixed_width_font = 0; 637} 638 639/* @var in makeinfo just uppercases the text. */ 640void 641cm_var (arg, start_pos, end_pos) 642 int arg, start_pos, end_pos; 643{ 644 if (xml) 645 xml_insert_element (VAR, arg); 646 else 647 { 648 not_fixed_width (arg); 649 650 if (html) 651 insert_html_tag (arg, "var"); 652 else if (arg == END) 653 { 654 while (start_pos < end_pos) 655 { 656 unsigned char c = output_paragraph[start_pos]; 657 if (strchr ("[](),", c)) 658 warning (_("unlikely character %c in @var"), c); 659 output_paragraph[start_pos] = coerce_to_upper (c); 660 start_pos++; 661 } 662 } 663 } 664} 665 666void 667cm_sc (arg, start_pos, end_pos) 668 int arg, start_pos, end_pos; 669{ 670 if (xml) 671 xml_insert_element (SC, arg); 672 else 673 { 674 not_fixed_width (arg); 675 676 if (arg == START) 677 { 678 if (html) 679 insert_html_tag (arg, small_tag); 680 } 681 else 682 { 683 int all_upper; 684 685 if (html) 686 start_pos += sizeof (small_tag) + 2 - 1; /* skip <small> */ 687 688 /* Avoid the warning below if there's no text inside @sc{}, or 689 when processing menus under --no-headers. */ 690 all_upper = start_pos < end_pos; 691 692 while (start_pos < end_pos) 693 { 694 unsigned char c = output_paragraph[start_pos]; 695 if (!isupper (c)) 696 all_upper = 0; 697 output_paragraph[start_pos] = coerce_to_upper (c); 698 start_pos++; 699 } 700 if (all_upper) 701 warning (_("@sc argument all uppercase, thus no effect")); 702 703 if (html) 704 insert_html_tag (arg, small_tag); 705 } 706 } 707} 708 709void 710cm_dfn (arg, position) 711 int arg, position; 712{ 713 if (xml) 714 xml_insert_element (DFN, arg); 715 else 716 { 717 if (html) 718 insert_html_tag (arg, "dfn"); 719 else if (arg == START) 720 add_char ('"'); 721 else 722 add_meta_char ('"'); 723 } 724} 725 726void 727cm_emph (arg) 728 int arg; 729{ 730 if (xml) 731 xml_insert_element (EMPH, arg); 732 else if (html) 733 insert_html_tag (arg, "em"); 734 else 735 add_char ('_'); 736} 737 738void 739cm_verb (arg) 740 int arg; 741{ 742 int character; 743 int delimiter; 744 int seen_end = 0; 745 746 in_fixed_width_font++; 747 /* are these necessary ? */ 748 last_char_was_newline = 0; 749 750 if (html) 751 add_word ("<pre>"); 752 753 if (input_text_offset < input_text_length) 754 { 755 character = curchar (); 756 if (character == '{') 757 input_text_offset++; 758 else 759 line_error (_("`{' expected, but saw `%c'"), character); 760 } 761 762 if (input_text_offset < input_text_length) 763 { 764 delimiter = curchar (); 765 input_text_offset++; 766 } 767 768 while (input_text_offset < input_text_length) 769 { 770 character = curchar (); 771 772 if (character == '\n') 773 line_number++; 774 /* 775 Assume no newlines in END_VERBATIM 776 */ 777 else if (character == delimiter) 778 { 779 seen_end = 1; 780 input_text_offset++; 781 break; 782 } 783 784 add_char (character); 785 input_text_offset++; 786 } 787 788 if (!seen_end) 789 warning (_("end of file inside verb block")); 790 791 if (input_text_offset < input_text_length) 792 { 793 character = curchar (); 794 if (character == '}') 795 input_text_offset++; 796 else 797 line_error (_("`}' expected, but saw `%c'"), character); 798 } 799 800 if (html) 801 add_word ("</pre>"); 802} 803 804void 805cm_strong (arg, position) 806 int arg, position; 807{ 808 if (xml) 809 xml_insert_element (STRONG, arg); 810 else if (html) 811 insert_html_tag (arg, "strong"); 812 else 813 add_char ('*'); 814} 815 816void 817cm_cite (arg, position) 818 int arg, position; 819{ 820 if (xml) 821 xml_insert_element (CITE, arg); 822 else if (html) 823 insert_html_tag (arg, "cite"); 824 else 825 { 826 if (arg == START) 827 add_char ('`'); 828 else 829 add_char ('\''); 830 } 831} 832 833/* No highlighting, but argument switches fonts. */ 834void 835cm_not_fixed_width (arg, start, end) 836 int arg, start, end; 837{ 838 if (xml) 839 xml_insert_element (NOTFIXEDWIDTH, arg); 840 not_fixed_width (arg); 841} 842 843void 844cm_i (arg) 845 int arg; 846{ 847 if (xml) 848 xml_insert_element (I, arg); 849 else if (html) 850 insert_html_tag (arg, "i"); 851 else 852 not_fixed_width (arg); 853} 854 855void 856cm_b (arg) 857 int arg; 858{ 859 if (xml) 860 xml_insert_element (B, arg); 861 else if (html) 862 insert_html_tag (arg, "b"); 863 else 864 not_fixed_width (arg); 865} 866 867void 868cm_r (arg) 869 int arg; 870{ 871 if (xml) 872 xml_insert_element (R, arg); 873 else 874 { 875 extern int printing_index; 876 877 /* People use @r{} in index entries like this: 878 879 @findex foo@r{, some text} 880 881 This is supposed to produce output as if the entry were saying 882 "@code{foo}, some text", since the "fn" index is typeset as 883 @code. The following attempts to do the same in HTML. Note that 884 this relies on the fact that only @code bumps up the variable 885 in_fixed_width_font while processing index entries in HTML mode. */ 886 if (html && printing_index) 887 { 888 int level = in_fixed_width_font; 889 890 while (level--) 891 insert_html_tag (arg == START ? END : START, "code"); 892 } 893 894 not_fixed_width (arg); 895 } 896} 897 898void 899cm_titlefont (arg) 900 int arg; 901{ 902 if (xml) 903 xml_insert_element (TITLEFONT, arg); 904 else 905 not_fixed_width (arg); 906} 907 908/* Various commands are no-op's. */ 909void 910cm_no_op () 911{ 912} 913 914 915/* For proofing single chapters, etc. */ 916void 917cm_novalidate () 918{ 919 validating = 0; 920} 921 922 923/* Prevent the argument from being split across two lines. */ 924void 925cm_w (arg, start, end) 926 int arg, start, end; 927{ 928 if (arg == START) 929 non_splitting_words++; 930 else 931 non_splitting_words--; 932} 933 934 935/* Explain that this command is obsolete, thus the user shouldn't 936 do anything with it. */ 937static void 938cm_obsolete (arg, start, end) 939 int arg, start, end; 940{ 941 if (arg == START) 942 warning (_("%c%s is obsolete"), COMMAND_PREFIX, command); 943} 944 945 946/* This says to inhibit the indentation of the next paragraph, but 947 not of following paragraphs. */ 948void 949cm_noindent () 950{ 951 if (!inhibit_paragraph_indentation) 952 inhibit_paragraph_indentation = -1; 953} 954 955/* I don't know exactly what to do with this. Should I allow 956 someone to switch filenames in the middle of output? Since the 957 file could be partially written, this doesn't seem to make sense. 958 Another option: ignore it, since they don't *really* want to 959 switch files. Finally, complain, or at least warn. It doesn't 960 really matter, anyway, since this doesn't get executed. */ 961void 962cm_setfilename () 963{ 964 char *filename; 965 get_rest_of_line (1, &filename); 966 /* warning ("`@%s %s' encountered and ignored", command, filename); */ 967 if (xml) 968 add_word_args ("<setfilename>%s</setfilename>", filename); 969 free (filename); 970} 971 972void 973cm_settitle () 974{ 975 if (xml) 976 { 977 xml_begin_document (current_output_filename); 978 xml_insert_element (SETTITLE, START); 979 get_rest_of_line (0, &title); 980 execute_string ("%s", title); 981 xml_insert_element (SETTITLE, END); 982 } 983 else 984 get_rest_of_line (0, &title); 985} 986 987 988/* Ignore argument in braces. */ 989void 990cm_ignore_arg (arg, start_pos, end_pos) 991 int arg, start_pos, end_pos; 992{ 993 if (arg == END) 994 output_paragraph_offset = start_pos; 995} 996 997/* Ignore argument on rest of line. */ 998void 999cm_ignore_line () 1000{ 1001 discard_until ("\n"); 1002} 1003 1004/* Insert the number of blank lines passed as argument. */ 1005void 1006cm_sp () 1007{ 1008 int lines; 1009 char *line; 1010 1011 get_rest_of_line (1, &line); 1012 1013 if (sscanf (line, "%d", &lines) != 1 || lines <= 0) 1014 line_error (_("@sp requires a positive numeric argument, not `%s'"), line); 1015 else 1016 { 1017 if (xml) 1018 { 1019 xml_insert_element_with_attribute (SP, START, "lines=\"%s\"", line); 1020 /* insert_string (line);*/ 1021 xml_insert_element (SP, END); 1022 } 1023 else 1024 { 1025 /* Must disable filling since otherwise multiple newlines is like 1026 multiple spaces. Must close paragraph since that's what the 1027 manual says and that's what TeX does. */ 1028 int save_filling_enabled = filling_enabled; 1029 filling_enabled = 0; 1030 1031 /* close_paragraph generates an extra blank line. */ 1032 close_single_paragraph (); 1033 1034 if (lines && html && !executing_string) 1035 html_output_head (); 1036 1037 while (lines--) 1038 { 1039 if (html) 1040 insert_string ("<br><p>\n"); 1041 else 1042 add_char ('\n'); 1043 } 1044 1045 filling_enabled = save_filling_enabled; 1046 } 1047 } 1048 free (line); 1049} 1050 1051/* @dircategory LINE outputs INFO-DIR-SECTION LINE, unless --no-headers. */ 1052void 1053cm_dircategory () 1054{ 1055 char *line; 1056 1057 if (html || docbook) 1058 cm_ignore_line (); 1059 else if (xml) 1060 { 1061 xml_insert_element (DIRCATEGORY, START); 1062 get_rest_of_line (1, &line); 1063 insert_string (line); 1064 free (line); 1065 xml_insert_element (DIRCATEGORY, END); 1066 } 1067 else 1068 { 1069 get_rest_of_line (1, &line); 1070 1071 if (!no_headers && !html) 1072 { 1073 kill_self_indent (-1); /* make sure there's no indentation */ 1074 insert_string ("INFO-DIR-SECTION "); 1075 insert_string (line); 1076 insert ('\n'); 1077 } 1078 1079 free (line); 1080 } 1081} 1082 1083/* Start a new line with just this text on it. 1084 Then center the line of text. 1085 */ 1086void 1087cm_center () 1088{ 1089 if (xml) 1090 { 1091 unsigned char *line; 1092 xml_insert_element (CENTER, START); 1093 get_rest_of_line (0, (char **)&line); 1094 execute_string ("%s", (char *)line); 1095 free (line); 1096 xml_insert_element (CENTER, END); 1097 } 1098 else 1099 { 1100 int i, start, length; 1101 unsigned char *line; 1102 int save_indented_fill = indented_fill; 1103 int save_filling_enabled = filling_enabled; 1104 int fudge_factor = 1; 1105 1106 filling_enabled = indented_fill = 0; 1107 cm_noindent (); 1108 start = output_paragraph_offset; 1109 1110 if (html) 1111 add_word ("<div align=\"center\">"); 1112 1113 inhibit_output_flushing (); 1114 get_rest_of_line (0, (char **)&line); 1115 execute_string ("%s", (char *)line); 1116 free (line); 1117 uninhibit_output_flushing (); 1118 if (html) 1119 add_word ("</div>"); 1120 1121 else 1122 { 1123 i = output_paragraph_offset - 1; 1124 while (i > (start - 1) && output_paragraph[i] == '\n') 1125 i--; 1126 1127 output_paragraph_offset = ++i; 1128 length = output_paragraph_offset - start; 1129 1130 if (length < (fill_column - fudge_factor)) 1131 { 1132 line = xmalloc (1 + length); 1133 memcpy (line, (char *)(output_paragraph + start), length); 1134 1135 i = (fill_column - fudge_factor - length) / 2; 1136 output_paragraph_offset = start; 1137 1138 while (i--) 1139 insert (' '); 1140 1141 for (i = 0; i < length; i++) 1142 insert (line[i]); 1143 1144 free (line); 1145 } 1146 } 1147 1148 insert ('\n'); 1149 filling_enabled = save_filling_enabled; 1150 indented_fill = save_indented_fill; 1151 } 1152} 1153 1154/* Show what an expression returns. */ 1155void 1156cm_result (arg) 1157 int arg; 1158{ 1159 if (arg == END) 1160 add_word (html ? "=>" : "=>"); 1161} 1162 1163/* What an expression expands to. */ 1164void 1165cm_expansion (arg) 1166 int arg; 1167{ 1168 if (arg == END) 1169 add_word (html ? "==>" : "==>"); 1170} 1171 1172/* Indicates two expressions are equivalent. */ 1173void 1174cm_equiv (arg) 1175 int arg; 1176{ 1177 if (arg == END) 1178 add_word ("=="); 1179} 1180 1181/* What an expression may print. */ 1182void 1183cm_print (arg) 1184 int arg; 1185{ 1186 if (arg == END) 1187 add_word ("-|"); 1188} 1189 1190/* An error signaled. */ 1191void 1192cm_error (arg) 1193 int arg; 1194{ 1195 if (arg == END) 1196 add_word (html ? "error-->" : "error-->"); 1197} 1198 1199/* The location of point in an example of a buffer. */ 1200void 1201cm_point (arg) 1202 int arg; 1203{ 1204 if (arg == END) 1205 add_word ("-!-"); 1206} 1207 1208/* @exdent: Start a new line with just this text on it. 1209 The text is outdented one level if possible. */ 1210void 1211cm_exdent () 1212{ 1213 char *line; 1214 int save_indent = current_indent; 1215 int save_in_fixed_width_font = in_fixed_width_font; 1216 1217 /* Read argument */ 1218 get_rest_of_line (0, &line); 1219 1220 /* Exdent the output. Actually this may be a no-op. */ 1221 if (current_indent) 1222 current_indent -= default_indentation_increment; 1223 1224 /* @exdent arg is supposed to be in roman. */ 1225 in_fixed_width_font = 0; 1226 1227 /* The preceding newline already inserted the `current_indent'. 1228 Remove one level's worth. */ 1229 kill_self_indent (default_indentation_increment); 1230 1231 if (html) 1232 add_word ("<br>"); 1233 1234 /* Can't close_single_paragraph, then we lose preceding blank lines. */ 1235 flush_output (); 1236 execute_string ("%s", line); 1237 free (line); 1238 1239 if (html) 1240 add_word ("<br>"); 1241 close_single_paragraph (); 1242 1243 current_indent = save_indent; 1244 in_fixed_width_font = save_in_fixed_width_font; 1245} 1246 1247/* 1248 Read include-filename, process the include-file: 1249 verbatim_include == 0: process through reader_loop 1250 verbatim_include != 0: process through handle_verbatim_environment 1251 */ 1252static void 1253handle_include (verbatim_include) 1254 int verbatim_include; 1255{ 1256 char *filename; 1257 1258 if (macro_expansion_output_stream && !executing_string) 1259 me_append_before_this_command (); 1260 1261 close_paragraph (); 1262 get_rest_of_line (0, &filename); 1263 1264 if (macro_expansion_output_stream && !executing_string) 1265 remember_itext (input_text, input_text_offset); 1266 1267 pushfile (); 1268 1269 /* In verbose mode we print info about including another file. */ 1270 if (verbose_mode) 1271 { 1272 int i = 0; 1273 FSTACK *stack = filestack; 1274 1275 for (i = 0, stack = filestack; stack; stack = stack->next, i++); 1276 1277 i *= 2; 1278 1279 printf ("%*s", i, ""); 1280 printf ("%c%s `%s'\n", COMMAND_PREFIX, command, filename); 1281 fflush (stdout); 1282 } 1283 1284 if (!find_and_load (filename)) 1285 { 1286 extern int errno; 1287 1288 popfile (); 1289 line_number--; 1290 1291 /* /wh/bar:5: @include/@verbatiminclude `foo': No such file or dir */ 1292 line_error ("%c%s `%s': %s", COMMAND_PREFIX, command, filename, 1293 strerror (errno)); 1294 1295 free (filename); 1296 return; 1297 } 1298 else 1299 { 1300 if (macro_expansion_output_stream && !executing_string) 1301 remember_itext (input_text, input_text_offset); 1302 1303 if (!verbatim_include) 1304 reader_loop (); 1305 else 1306 handle_verbatim_environment (0); 1307 } 1308 free (filename); 1309 popfile (); 1310} 1311 1312 1313/* Include file as if put in @verbatim environment */ 1314void 1315cm_verbatiminclude () 1316{ 1317 handle_include (1); 1318} 1319 1320 1321/* Remember this file, and move onto the next. */ 1322void 1323cm_include () 1324{ 1325 handle_include (0); 1326} 1327 1328 1329/* @bye: Signals end of processing. Easy to make this happen. */ 1330 1331void 1332cm_bye () 1333{ 1334 discard_braces (); /* should not have any unclosed braces left */ 1335 flush_output (); 1336 input_text_offset = input_text_length; 1337} 1338 1339/* @paragraphindent */ 1340 1341static void 1342cm_paragraphindent () 1343{ 1344 char *arg; 1345 1346 get_rest_of_line (1, &arg); 1347 if (set_paragraph_indent (arg) != 0) 1348 line_error (_("Bad argument to %c%s"), COMMAND_PREFIX, command); 1349 1350 free (arg); 1351} 1352 1353/* @exampleindent: change indentation of example-like environments. */ 1354static int 1355set_default_indentation_increment (string) 1356 char *string; 1357{ 1358 if (strcmp (string, "asis") == 0 || strcmp (string, _("asis")) == 0) 1359 ; 1360 else if (strcmp (string, "none") == 0 || strcmp (string, _("none")) == 0) 1361 default_indentation_increment = 0; 1362 else if (sscanf (string, "%d", &default_indentation_increment) != 1) 1363 return -1; 1364 return 0; 1365} 1366 1367static void 1368cm_exampleindent () 1369{ 1370 char *arg; 1371 1372 get_rest_of_line (1, &arg); 1373 if (set_default_indentation_increment (arg) != 0) 1374 line_error (_("Bad argument to %c%s"), COMMAND_PREFIX, command); 1375 1376 free (arg); 1377} 1378