1 /* $NetBSD: cmds.c,v 1.2 2016/01/14 00:34:53 christos 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 (void), 46 cm_firstparagraphindent (void), 47 cm_paragraphindent (void), 48 cm_novalidate (void); 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. */ 375 376 /* Commands which insert their own names. */ 377 void 378 insert_self (int arg) 379 { 380 if (arg == START) 381 add_word (command); 382 } 383 384 void 385 insert_space (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 /* Insert a comma. Useful when a literal , would break our parsing of 397 multiple arguments. */ 398 void 399 cm_comma (int arg) 400 { 401 if (arg == START) 402 add_char (','); 403 } 404 405 406 /* Force a line break in the output. */ 407 void 408 cm_asterisk (void) 409 { 410 if (html) 411 add_word ("<br>"); 412 else if (xml && !docbook) 413 xml_insert_entity ("linebreak"); 414 else if (docbook) 415 xml_asterisk (); 416 else 417 { 418 close_single_paragraph (); 419 cm_noindent (); 420 } 421 } 422 423 /* Insert ellipsis. */ 424 void 425 cm_dots (int arg) 426 { 427 if (arg == START) 428 { 429 if (xml && !docbook) 430 xml_insert_entity ("dots"); 431 else if (docbook) 432 xml_insert_entity ("hellip"); 433 else 434 if (html && !in_fixed_width_font) 435 insert_string ("<small class=\"dots\">...</small>"); 436 else 437 add_word ("..."); 438 } 439 } 440 441 /* Insert ellipsis for sentence end. */ 442 void 443 cm_enddots (int arg) 444 { 445 if (arg == START) 446 { 447 if (xml && !docbook) 448 xml_insert_entity ("enddots"); 449 else if (docbook) 450 { 451 xml_insert_entity ("hellip"); 452 add_char ('.'); 453 } 454 else 455 if (html && !in_fixed_width_font) 456 insert_string ("<small class=\"enddots\">....</small>"); 457 else 458 add_word ("...."); 459 } 460 } 461 462 void 463 cm_bullet (int arg) 464 { 465 if (arg == START) 466 { 467 if (html) 468 add_word ("•"); 469 else if (xml && !docbook) 470 xml_insert_entity ("bullet"); 471 else if (docbook) 472 xml_insert_entity ("bull"); 473 else 474 add_char ('*'); 475 } 476 } 477 478 void 479 cm_minus (int arg) 480 { 481 if (arg == START) 482 { 483 if (xml) 484 xml_insert_entity ("minus"); 485 else if (html) 486 add_word ("−"); 487 else 488 add_char ('-'); 489 } 490 } 491 492 /* Formatting a dimension unit. */ 493 void 494 cm_dmn (int arg) 495 { 496 if (html) 497 insert_html_tag_with_attribute (arg, "span", "class=\"dmn\""); 498 else if (docbook) 499 /* No units in docbook yet. */ 500 ; 501 else if (xml) 502 xml_insert_element (DIMENSION, arg); 503 } 504 505 /* Insert "TeX". */ 506 void 507 cm_TeX (int arg) 508 { 509 static int last_position; 510 511 if (arg == START) 512 { 513 if (xml) 514 xml_insert_entity ("tex"); 515 else 516 add_word ("TeX"); 517 518 last_position = output_paragraph_offset; 519 } 520 else if (last_position != output_paragraph_offset) 521 { 522 warning (_("arguments to @%s ignored"), command); 523 output_paragraph_offset = last_position; 524 } 525 } 526 527 /* Insert "LaTeX". */ 528 void 529 cm_LaTeX (int arg) 530 { 531 static int last_position; 532 533 if (arg == START) 534 { 535 if (xml) 536 xml_insert_entity ("latex"); 537 else 538 add_word ("LaTeX"); 539 540 last_position = output_paragraph_offset; 541 } 542 else if (last_position != output_paragraph_offset) 543 { 544 warning (_("arguments to @%s ignored"), command); 545 output_paragraph_offset = last_position; 546 } 547 } 548 549 /* Copyright symbol. */ 550 void 551 cm_copyright (int arg) 552 { 553 if (arg == START) 554 { 555 if (html) 556 add_word ("©"); 557 else if (xml && !docbook) 558 xml_insert_entity ("copyright"); 559 else if (docbook) 560 xml_insert_entity ("copy"); 561 else 562 add_word ("(C)"); 563 } 564 } 565 566 /* Registered symbol. */ 567 void 568 cm_registeredsymbol (int arg) 569 { 570 if (arg == START) 571 { 572 if (html) 573 add_word ("®"); 574 else if (docbook) 575 xml_insert_entity ("reg"); 576 else if (xml && !docbook) 577 xml_insert_entity ("registered"); 578 else 579 add_word ("(R)"); 580 } 581 } 582 583 void 584 cm_today (int arg) 585 { 586 static char *months[12] = 587 { N_("January"), N_("February"), N_("March"), N_("April"), N_("May"), 588 N_("June"), N_("July"), N_("August"), N_("September"), N_("October"), 589 N_("November"), N_("December") }; 590 if (arg == START) 591 { 592 time_t timer = time (0); 593 struct tm *ts = localtime (&timer); 594 add_word_args ("%d %s %d", ts->tm_mday, _(months[ts->tm_mon]), 595 ts->tm_year + 1900); 596 } 597 } 598 599 void 600 cm_comment (void) 601 { 602 /* For HTML, do not output comments before HTML header is written, 603 otherwise comments before @settitle cause an empty <title> in the 604 header. */ 605 if ((html && html_output_head_p) || xml) 606 { 607 char *line; 608 get_rest_of_line (0, &line); 609 610 if (strlen (line) > 0) 611 { 612 int save_inhibit_indentation = inhibit_paragraph_indentation; 613 int save_paragraph_is_open = paragraph_is_open; 614 int save_escape_html = escape_html; 615 int save_xml_no_para = xml_no_para; 616 int i; 617 618 inhibit_paragraph_indentation = 1; 619 escape_html = 0; 620 xml_no_para = 1; 621 622 /* @c and @comment can appear between @item and @itemx, 623 @deffn and @deffnx. */ 624 xml_dont_touch_items_defs++; 625 626 /* Use insert for HTML, and XML when indentation is enabled. 627 For Docbook, use add_char. */ 628 if (xml && xml_indentation_increment > 0 629 && output_paragraph[output_paragraph_offset-1] != '\n') 630 insert ('\n'); 631 632 /* Crunch double hyphens in comments. */ 633 add_html_block_elt ("<!-- "); 634 for (i = 0; i < strlen (line); i++) 635 if (line[i] != '-' || (i && line[i-1] != '-')) 636 add_char (line[i]); 637 add_word (" -->"); 638 639 if (html) 640 add_char ('\n'); 641 642 inhibit_paragraph_indentation = save_inhibit_indentation; 643 paragraph_is_open = save_paragraph_is_open; 644 escape_html = save_escape_html; 645 xml_no_para = save_xml_no_para; 646 xml_dont_touch_items_defs--; 647 } 648 649 free (line); 650 } 651 else 652 cm_ignore_line (); 653 } 654 655 656 657 /* We keep acronyms with two arguments around, to be able to refer to them 658 later with only one argument. */ 659 static ACRONYM_DESC *acronyms_stack = NULL; 660 661 static void 662 cm_acronym_or_abbr (int arg, int is_abbr) 663 { 664 char *aa, *description; 665 unsigned len; 666 667 /* We do everything at START. */ 668 if (arg == END) 669 return; 670 671 get_until_in_braces (",", &aa); 672 if (input_text[input_text_offset] == ',') 673 input_text_offset++; 674 get_until_in_braces ("}", &description); 675 676 canon_white (aa); 677 canon_white (description); 678 679 /* If not enclosed in braces, strip after comma to be compatible 680 with texinfo.tex. */ 681 if (description[0] != '{' && strchr (description, ',') != NULL) 682 { 683 int i = 0; 684 while (description[i] != ',') 685 i++; 686 /* For now, just terminate the string at comma. */ 687 description[i] = 0; 688 } 689 690 /* Get description out of braces. */ 691 if (description[0] == '{') 692 description++; 693 694 len = strlen (description); 695 if (len && description[len-1] == '}') 696 description[len-1] = 0; 697 698 /* Save new description. */ 699 if (strlen (description) > 0) 700 { 701 ACRONYM_DESC *new = xmalloc (sizeof (ACRONYM_DESC)); 702 703 new->acronym = xstrdup (aa); 704 new->description = xstrdup (description); 705 new->next = acronyms_stack; 706 acronyms_stack = new; 707 } 708 709 if (html) 710 { 711 add_word (is_abbr ? "<abbr" : "<acronym"); 712 713 if (strlen (description) > 0) 714 add_word_args (" title=\"%s\"", text_expansion (description)); 715 else if (acronyms_stack) 716 { 717 /* No second argument, get from previous. Search order is from 718 last to first defined, so we get the most recent version of 719 the description. */ 720 ACRONYM_DESC *temp = acronyms_stack; 721 722 while (temp) 723 { 724 if (STREQ (aa, temp->acronym) 725 && strlen (temp->description) > 0) 726 { 727 add_word_args (" title=\"%s\"", 728 text_expansion (temp->description)); 729 break; 730 } 731 temp = temp->next; 732 } 733 } 734 735 add_char ('>'); 736 execute_string ("%s", aa); 737 add_word (is_abbr ? "</abbr>" : "</acronym>"); 738 } 739 else if (docbook) 740 { 741 xml_insert_element (is_abbr ? ABBREV : ACRONYM, START); 742 execute_string ("%s", aa); 743 xml_insert_element (is_abbr ? ABBREV : ACRONYM, END); 744 } 745 else if (xml) 746 { 747 xml_insert_element (is_abbr ? ABBREV : ACRONYM, START); 748 749 xml_insert_element (is_abbr ? ABBREVWORD : ACRONYMWORD, START); 750 execute_string ("%s", aa); 751 xml_insert_element (is_abbr ? ABBREVWORD : ACRONYMWORD, END); 752 753 if (strlen (description) > 0) 754 { 755 xml_insert_element (is_abbr ? ABBREVDESC : ACRONYMDESC, START); 756 execute_string ("%s", description); 757 xml_insert_element (is_abbr ? ABBREVDESC : ACRONYMDESC, END); 758 } 759 760 xml_insert_element (is_abbr ? ABBREV : ACRONYM, END); 761 } 762 else 763 execute_string ("%s", aa); 764 765 /* Put description into parenthesis after the acronym for all outputs 766 except XML. */ 767 if (strlen (description) > 0 && (!xml || docbook)) 768 add_word_args (" (%s)", description); 769 } 770 771 void 772 cm_acronym (int arg) 773 { 774 cm_acronym_or_abbr (arg, 0); 775 } 776 777 void 778 cm_abbr (int arg) 779 { 780 cm_acronym_or_abbr (arg, 1); 781 } 782 783 void 784 cm_tt (int arg) 785 { 786 /* @t{} is a no-op in Info. */ 787 if (html) 788 insert_html_tag (arg, "tt"); 789 else if (xml) 790 xml_insert_element (TT, arg); 791 } 792 793 void 794 cm_code (int arg) 795 { 796 if (arg == START) 797 in_fixed_width_font++; 798 799 if (xml) 800 { 801 if (STREQ (command, "command")) 802 xml_insert_element (COMMAND_TAG, arg); 803 else if (STREQ (command, "env")) 804 xml_insert_element (ENV, arg); 805 else if (STREQ (command, "file")) 806 xml_insert_element (FILE_TAG, arg); 807 else if (STREQ (command, "option")) 808 xml_insert_element (OPTION, arg); 809 else if (STREQ (command, "samp")) 810 { 811 if (docbook && arg == START) 812 { 813 /* Even though @samp is in_fixed_width_font, it 814 should always start a paragraph. Unfortunately, 815 in_fixed_width_font inhibits that. */ 816 xml_start_para (); 817 xml_insert_entity ("lsquo"); 818 } 819 xml_insert_element (SAMP, arg); 820 if (docbook && arg == END) 821 xml_insert_entity ("rsquo"); 822 } 823 else 824 xml_insert_element (CODE, arg); 825 } 826 else if (html) 827 { 828 if (STREQ (command, "code")) 829 insert_html_tag (arg, "code"); 830 else 831 { /* Use <samp> tag in general to get typewriter. */ 832 if (arg == START) 833 { /* If @samp specifically, add quotes a la TeX output. */ 834 if (STREQ (command, "samp")) add_char ('`'); 835 add_word ("<samp>"); 836 } 837 insert_html_tag_with_attribute (arg, "span", "class=\"%s\"",command); 838 if (arg == END) 839 { 840 add_word ("</samp>"); 841 if (STREQ (command, "samp")) add_char ('\''); 842 } 843 } 844 } 845 else 846 { 847 extern int printing_index; 848 849 if (!printing_index) 850 { 851 if (arg == START) 852 add_char ('`'); 853 else 854 add_meta_char ('\''); 855 } 856 } 857 } 858 859 void 860 cm_kbd (int arg) 861 { 862 if (xml) 863 xml_insert_element (KBD, arg); 864 else if (html) 865 { /* Seems like we should increment in_fixed_width_font for Info 866 format too, but then the quote-omitting special case gets 867 confused. Punt. */ 868 if (arg == START) 869 in_fixed_width_font++; 870 insert_html_tag (arg, "kbd"); 871 } 872 else 873 { /* People use @kbd in an example to get the "user input" font. 874 We don't want quotes in that case. */ 875 if (!in_fixed_width_font) 876 cm_code (arg); 877 } 878 } 879 880 /* Just show a url (http://example.org/..., for example), don't link to it. */ 881 void 882 cm_indicate_url (int arg, int start, int end) 883 { 884 if (xml) 885 xml_insert_element (URL, arg); 886 else if (html) 887 { 888 if (arg == START) 889 add_word ("<"); 890 insert_html_tag (arg, "code"); 891 if (arg != START) 892 add_word (">"); 893 } 894 else 895 if (arg == START) 896 add_word ("<"); 897 else 898 add_word (">"); 899 } 900 901 void 902 cm_key (int arg) 903 { 904 if (xml) 905 xml_insert_element (KEY, arg); 906 else if (html) 907 add_word (arg == START ? "<" : ">"); 908 else 909 add_char (arg == START ? '<' : '>'); 910 } 911 912 /* Handle a command that switches to a non-fixed-width font. */ 913 void 914 not_fixed_width (int arg) 915 { 916 if (arg == START) 917 in_fixed_width_font = 0; 918 } 919 920 /* @var in makeinfo just uppercases the text. */ 921 void 922 cm_var (int arg, int start_pos, int end_pos) 923 { 924 if (xml) 925 xml_insert_element (VAR, arg); 926 else 927 { 928 not_fixed_width (arg); 929 930 if (html) 931 insert_html_tag (arg, "var"); 932 else if (arg == END) 933 { 934 while (start_pos < end_pos) 935 { 936 unsigned char c = output_paragraph[start_pos]; 937 if (strchr ("[](),", c)) 938 warning (_("unlikely character %c in @var"), c); 939 output_paragraph[start_pos] = coerce_to_upper (c); 940 start_pos++; 941 } 942 } 943 } 944 } 945 946 void 947 cm_sc (int arg, int start_pos, int end_pos) 948 { 949 if (xml) 950 xml_insert_element (SC, arg); 951 else 952 { 953 not_fixed_width (arg); 954 955 if (arg == START) 956 { 957 if (html) 958 insert_html_tag_with_attribute (arg, "span", "class=\"sc\""); 959 } 960 else 961 { 962 int all_upper; 963 964 if (html) 965 start_pos += sizeof ("<span class=\"sc\">") - 1; /* skip <span> */ 966 967 /* Avoid the warning below if there's no text inside @sc{}, or 968 when processing menus under --no-headers. */ 969 all_upper = start_pos < end_pos; 970 971 while (start_pos < end_pos) 972 { 973 unsigned char c = output_paragraph[start_pos]; 974 if (!isupper (c)) 975 all_upper = 0; 976 if (!html) 977 output_paragraph[start_pos] = coerce_to_upper (c); 978 start_pos++; 979 } 980 if (all_upper) 981 warning (_("@sc argument all uppercase, thus no effect")); 982 983 if (html) 984 insert_html_tag (arg, "span"); 985 } 986 } 987 } 988 989 void 990 cm_dfn (int arg, int position) 991 { 992 if (xml) 993 xml_insert_element (DFN, arg); 994 else 995 { 996 if (html) 997 insert_html_tag (arg, "dfn"); 998 else if (arg == START) 999 add_char ('"'); 1000 else 1001 add_meta_char ('"'); 1002 } 1003 } 1004 1005 void 1006 cm_emph (int arg) 1007 { 1008 if (xml) 1009 xml_insert_element (EMPH, arg); 1010 else if (html) 1011 insert_html_tag (arg, "em"); 1012 else 1013 add_char ('_'); 1014 } 1015 1016 void 1017 cm_verb (int arg) 1018 { 1019 int character; 1020 int delimiter = 0; /* avoid warning */ 1021 int seen_end = 0; 1022 1023 in_fixed_width_font++; 1024 /* are these necessary ? */ 1025 last_char_was_newline = 0; 1026 1027 if (html) 1028 add_word ("<tt>"); 1029 1030 if (input_text_offset < input_text_length) 1031 { 1032 character = curchar (); 1033 if (character == '{') 1034 input_text_offset++; 1035 else 1036 line_error (_("`{' expected, but saw `%c'"), character); 1037 } 1038 1039 if (input_text_offset < input_text_length) 1040 { 1041 delimiter = curchar (); 1042 input_text_offset++; 1043 } 1044 1045 while (input_text_offset < input_text_length) 1046 { 1047 character = curchar (); 1048 1049 if (character == '\n') 1050 { 1051 line_number++; 1052 if (html) 1053 add_word ("<br>\n"); 1054 } 1055 1056 else if (html && character == '<') 1057 add_word ("<"); 1058 1059 else if (html && character == '&') 1060 add_word ("&"); 1061 1062 else if (character == delimiter && input_text[input_text_offset+1] == '}') 1063 { /* Assume no newlines in END_VERBATIM. */ 1064 seen_end = 1; 1065 input_text_offset++; 1066 break; 1067 } 1068 1069 else 1070 add_char (character); 1071 1072 input_text_offset++; 1073 } 1074 1075 if (!seen_end) 1076 warning (_("end of file inside verb block")); 1077 1078 if (input_text_offset < input_text_length) 1079 { 1080 character = curchar (); 1081 if (character == '}') 1082 input_text_offset++; 1083 else 1084 line_error (_("`}' expected, but saw `%c'"), character); 1085 } 1086 1087 if (html) 1088 add_word ("</tt>"); 1089 1090 in_fixed_width_font--; 1091 } 1092 1093 1094 void 1095 cm_strong (int arg, int start_pos, int end_pos) 1096 { 1097 if (docbook && arg == START) 1098 xml_insert_element_with_attribute (B, arg, "role=\"bold\""); 1099 else if (xml) 1100 xml_insert_element (STRONG, arg); 1101 else if (html) 1102 insert_html_tag (arg, "strong"); 1103 else 1104 add_char ('*'); 1105 1106 if (!xml && !html && !docbook && !no_headers 1107 && arg == END 1108 && end_pos - start_pos >= 6 1109 && (STRNCASEEQ ((char *) output_paragraph + start_pos, "*Note:", 6) 1110 || STRNCASEEQ ((char *) output_paragraph + start_pos, "*Note ", 6))) 1111 { 1112 /* Translators: "Note:" is literal here and should not be 1113 translated. @strong{Nota}, say, does not cause the problem. */ 1114 warning (_("@strong{Note...} produces a spurious cross-reference in Info; reword to avoid that")); 1115 /* Adjust the output to avoid writing the bad xref. */ 1116 output_paragraph[start_pos + 5] = '_'; 1117 } 1118 } 1119 1120 void 1121 cm_cite (int arg, int position) 1122 { 1123 if (xml) 1124 xml_insert_element (CITE, arg); 1125 else if (html) 1126 insert_html_tag (arg, "cite"); 1127 else 1128 { 1129 if (arg == START) 1130 add_char ('`'); 1131 else 1132 add_char ('\''); 1133 } 1134 } 1135 1136 /* No highlighting, but argument switches fonts. */ 1137 void 1138 cm_not_fixed_width (int arg, int start, int end) 1139 { 1140 if (xml) 1141 xml_insert_element (NOTFIXEDWIDTH, arg); 1142 not_fixed_width (arg); 1143 } 1144 1145 void 1146 cm_i (int arg) 1147 { 1148 /* Make use of <lineannotation> of Docbook, if we are 1149 inside an @example or similar. */ 1150 extern int printing_index; 1151 if (docbook && !filling_enabled && !printing_index) 1152 xml_insert_element (LINEANNOTATION, arg); 1153 else if (xml) 1154 xml_insert_element (I, arg); 1155 else if (html) 1156 insert_html_tag (arg, "i"); 1157 else 1158 not_fixed_width (arg); 1159 } 1160 1161 void 1162 cm_slanted (int arg) 1163 { 1164 /* Make use of <lineannotation> of Docbook, if we are 1165 inside an @example or similar. */ 1166 extern int printing_index; 1167 if (docbook && !filling_enabled && !printing_index) 1168 xml_insert_element (LINEANNOTATION, arg); 1169 else if (xml) 1170 xml_insert_element (SLANTED, arg); 1171 else if (html) 1172 insert_html_tag (arg, "i"); 1173 else 1174 not_fixed_width (arg); 1175 } 1176 1177 void 1178 cm_b (int arg) 1179 { 1180 /* See cm_i comments. */ 1181 extern int printing_index; 1182 if (docbook && !filling_enabled && !printing_index) 1183 xml_insert_element (LINEANNOTATION, arg); 1184 else if (docbook && arg == START) 1185 xml_insert_element_with_attribute (B, arg, "role=\"bold\""); 1186 else if (xml) 1187 xml_insert_element (B, arg); 1188 else if (html) 1189 insert_html_tag (arg, "b"); 1190 else 1191 not_fixed_width (arg); 1192 } 1193 1194 void 1195 cm_r (int arg) 1196 { 1197 /* See cm_i comments. */ 1198 extern int printing_index; 1199 if (docbook && !filling_enabled && !printing_index) 1200 xml_insert_element (LINEANNOTATION, arg); 1201 else if (xml) 1202 xml_insert_element (R, arg); 1203 else if (html) 1204 insert_html_tag_with_attribute (arg, "span", "class=\"roman\""); 1205 else 1206 not_fixed_width (arg); 1207 } 1208 1209 void 1210 cm_sansserif (int arg) 1211 { 1212 /* See cm_i comments. */ 1213 extern int printing_index; 1214 if (docbook && !filling_enabled && !printing_index) 1215 xml_insert_element (LINEANNOTATION, arg); 1216 else if (xml) 1217 xml_insert_element (SANSSERIF, arg); 1218 else if (html) 1219 insert_html_tag_with_attribute (arg, "span", "class=\"sansserif\""); 1220 else 1221 not_fixed_width (arg); 1222 } 1223 1224 void 1225 cm_titlefont (int arg) 1226 { 1227 if (xml) 1228 xml_insert_element (TITLEFONT, arg); 1229 else 1230 { 1231 not_fixed_width (arg); 1232 if (html) 1233 { 1234 html_title_written = 1; /* suppress title from @settitle */ 1235 if (arg == START) 1236 add_word ("<h1 class=\"titlefont\">"); 1237 else 1238 add_word ("</h1>\n"); 1239 } 1240 } 1241 } 1242 1243 1244 /* Unfortunately, we cannot interpret @math{} contents like TeX does. We just 1245 pass them through. */ 1246 void 1247 cm_math (int arg) 1248 { 1249 if (xml && !docbook) 1250 xml_insert_element (MATH, arg); 1251 } 1252 1253 /* Various commands are no-op's. */ 1254 void 1255 cm_no_op (void) 1256 { 1257 } 1258 1259 1260 /* For proofing single chapters, etc. */ 1261 void 1262 cm_novalidate (void) 1263 { 1264 validating = 0; 1265 } 1266 1267 1268 /* Prevent the argument from being split across two lines. */ 1269 void 1270 cm_w (int arg) 1271 { 1272 if (arg == START) 1273 non_splitting_words++; 1274 else 1275 { 1276 if (docbook || html || xml) 1277 /* This is so @w{$}Log$ doesn't end up as <dollar>Log<dollar> 1278 in the output. */ 1279 insert_string ("<!-- /@w -->"); 1280 1281 non_splitting_words--; 1282 } 1283 } 1284 1285 1286 /* An unbreakable word space. Same as @w{ } for makeinfo, but different 1287 for TeX (the space stretches and stretches, and does not inhibit 1288 hyphenation). */ 1289 void 1290 cm_tie (int arg) 1291 { 1292 if (arg == START) 1293 { 1294 cm_w (START); 1295 add_char (' '); 1296 } 1297 else 1298 cm_w (END); 1299 } 1300 1301 /* Explain that this command is obsolete, thus the user shouldn't 1302 do anything with it. */ 1303 static void 1304 cm_obsolete (int arg, int start, int end) 1305 { 1306 if (arg == START) 1307 warning (_("%c%s is obsolete"), COMMAND_PREFIX, command); 1308 } 1309 1310 1311 /* Inhibit the indentation of the next paragraph, but not of following 1312 paragraphs. */ 1313 void 1314 cm_noindent (void) 1315 { 1316 if (!inhibit_paragraph_indentation) 1317 inhibit_paragraph_indentation = -1; 1318 } 1319 1320 void 1321 cm_noindent_cmd (void) 1322 { 1323 cm_noindent (); 1324 xml_no_indent = 1; 1325 skip_whitespace_and_newlines(); 1326 1327 if (xml) 1328 xml_start_para (); 1329 else if (html && !paragraph_is_open) 1330 add_html_block_elt ("<p class=\"noindent\">"); 1331 else 1332 { 1333 paragraph_is_open = 0; 1334 start_paragraph (); 1335 } 1336 } 1337 1338 /* Force indentation of the next paragraph. */ 1339 void 1340 cm_indent (void) 1341 { 1342 inhibit_paragraph_indentation = 0; 1343 xml_no_indent = 0; 1344 skip_whitespace_and_newlines(); 1345 1346 if (xml) 1347 xml_start_para (); 1348 else if (html && !paragraph_is_open) 1349 add_html_block_elt ("<p class=\"indent\">"); 1350 else 1351 start_paragraph (); 1352 } 1353 1354 /* I don't know exactly what to do with this. Should I allow 1355 someone to switch filenames in the middle of output? Since the 1356 file could be partially written, this doesn't seem to make sense. 1357 Another option: ignore it, since they don't really want to 1358 switch files. Finally, complain, or at least warn. It doesn't 1359 really matter, anyway, since this doesn't get executed. */ 1360 void 1361 cm_setfilename (void) 1362 { 1363 char *filename; 1364 get_rest_of_line (1, &filename); 1365 /* warning ("`@%s %s' encountered and ignored", command, filename); */ 1366 if (xml) 1367 add_word_args ("<setfilename>%s</setfilename>", filename); 1368 free (filename); 1369 } 1370 1371 void 1372 cm_settitle (void) 1373 { 1374 if (xml) 1375 { 1376 xml_begin_document (current_output_filename); 1377 xml_insert_element (SETTITLE, START); 1378 xml_in_book_title = 1; 1379 get_rest_of_line (0, &title); 1380 execute_string ("%s", title); 1381 xml_in_book_title = 0; 1382 xml_insert_element (SETTITLE, END); 1383 } 1384 else 1385 get_rest_of_line (0, &title); 1386 } 1387 1388 1389 /* Ignore argument in braces. */ 1390 void 1391 cm_ignore_arg (int arg, int start_pos, int end_pos) 1392 { 1393 if (arg == END) 1394 output_paragraph_offset = start_pos; 1395 } 1396 1397 /* Ignore argument on rest of line. */ 1398 void 1399 cm_ignore_line (void) 1400 { 1401 discard_until ("\n"); 1402 } 1403 1404 /* Insert the number of blank lines passed as argument. */ 1405 void 1406 cm_sp (void) 1407 { 1408 int lines; 1409 char *line; 1410 1411 /* Due to tricky stuff in execute_string(), @value{} can't be expanded. 1412 So there is really no reason to enable expansion for @sp parameters. */ 1413 get_rest_of_line (0, &line); 1414 1415 if (sscanf (line, "%d", &lines) != 1 || lines <= 0) 1416 line_error (_("@sp requires a positive numeric argument, not `%s'"), line); 1417 else 1418 { 1419 if (xml) 1420 { 1421 /* @sp can appear between @item and @itemx, @deffn and @deffnx. */ 1422 xml_dont_touch_items_defs++; 1423 xml_insert_element_with_attribute (SP, START, "lines=\"%s\"", line); 1424 /* insert_string (line);*/ 1425 xml_insert_element (SP, END); 1426 xml_dont_touch_items_defs--; 1427 } 1428 else 1429 { 1430 /* Must disable filling since otherwise multiple newlines is like 1431 multiple spaces. Must close paragraph since that's what the 1432 manual says and that's what TeX does. */ 1433 int save_filling_enabled = filling_enabled; 1434 filling_enabled = 0; 1435 1436 /* close_paragraph generates an extra blank line. */ 1437 close_single_paragraph (); 1438 1439 if (lines && html && !executing_string) 1440 html_output_head (); 1441 1442 if (html) 1443 add_html_block_elt ("<pre class=\"sp\">\n"); 1444 1445 while (lines--) 1446 add_char ('\n'); 1447 1448 if (html) 1449 add_html_block_elt ("</pre>\n"); 1450 1451 filling_enabled = save_filling_enabled; 1452 } 1453 } 1454 free (line); 1455 } 1456 1457 /* @dircategory LINE outputs INFO-DIR-SECTION LINE, unless --no-headers. */ 1458 void 1459 cm_dircategory (void) 1460 { 1461 char *line; 1462 1463 if (html || docbook) 1464 cm_ignore_line (); 1465 else if (xml) 1466 { 1467 xml_insert_element (DIRCATEGORY, START); 1468 get_rest_of_line (1, &line); 1469 insert_string (line); 1470 free (line); 1471 xml_insert_element (DIRCATEGORY, END); 1472 } 1473 else 1474 { 1475 get_rest_of_line (1, &line); 1476 1477 if (!no_headers && !html) 1478 { 1479 kill_self_indent (-1); /* make sure there's no indentation */ 1480 insert_string ("INFO-DIR-SECTION "); 1481 insert_string (line); 1482 insert ('\n'); 1483 } 1484 1485 free (line); 1486 } 1487 } 1488 1489 /* Start a new line with just this text on it. 1490 Then center the line of text. 1491 */ 1492 void 1493 cm_center (void) 1494 { 1495 if (xml) 1496 { 1497 char *line; 1498 xml_insert_element (CENTER, START); 1499 get_rest_of_line (0, &line); 1500 execute_string ("%s", line); 1501 free (line); 1502 xml_insert_element (CENTER, END); 1503 } 1504 else 1505 { 1506 int i, start, length; 1507 char *line; 1508 int save_indented_fill = indented_fill; 1509 int save_filling_enabled = filling_enabled; 1510 int fudge_factor = 1; 1511 1512 filling_enabled = indented_fill = 0; 1513 cm_noindent (); 1514 start = output_paragraph_offset; 1515 1516 if (html) 1517 add_html_block_elt ("<div align=\"center\">"); 1518 1519 inhibit_output_flushing (); 1520 get_rest_of_line (0, &line); 1521 execute_string ("%s", line); 1522 free (line); 1523 uninhibit_output_flushing (); 1524 if (html) 1525 add_html_block_elt ("</div>"); 1526 1527 else 1528 { 1529 i = output_paragraph_offset - 1; 1530 while (i > (start - 1) && output_paragraph[i] == '\n') 1531 i--; 1532 1533 output_paragraph_offset = ++i; 1534 length = output_paragraph_offset - start; 1535 1536 if (length < (fill_column - fudge_factor)) 1537 { 1538 line = xmalloc (1 + length); 1539 memcpy (line, (char *)(output_paragraph + start), length); 1540 1541 i = (fill_column - fudge_factor - length) / 2; 1542 output_paragraph_offset = start; 1543 1544 while (i--) 1545 insert (' '); 1546 1547 for (i = 0; i < length; i++) 1548 insert (line[i]); 1549 1550 free (line); 1551 } 1552 } 1553 1554 insert ('\n'); 1555 filling_enabled = save_filling_enabled; 1556 indented_fill = save_indented_fill; 1557 close_single_paragraph (); 1558 if (looking_at("\n")) 1559 insert ('\n'); 1560 } 1561 } 1562 1563 /* Show what an expression returns. */ 1564 void 1565 cm_result (int arg) 1566 { 1567 if (arg == END) 1568 add_word (html ? "=>" : "=>"); 1569 } 1570 1571 /* What an expression expands to. */ 1572 void 1573 cm_expansion (int arg) 1574 { 1575 if (arg == END) 1576 add_word (html ? "==>" : "==>"); 1577 } 1578 1579 /* Indicates two expressions are equivalent. */ 1580 void 1581 cm_equiv (int arg) 1582 { 1583 if (arg == END) 1584 add_word ("=="); 1585 } 1586 1587 /* What an expression may print. */ 1588 void 1589 cm_print (int arg) 1590 { 1591 if (arg == END) 1592 add_word ("-|"); 1593 } 1594 1595 /* An error signaled. */ 1596 void 1597 cm_error (int arg) 1598 { 1599 if (arg == END) 1600 add_word (html ? "error-->" : "error-->"); 1601 } 1602 1603 /* The location of point in an example of a buffer. */ 1604 void 1605 cm_point (int arg) 1606 { 1607 if (arg == END) 1608 add_word ("-!-"); 1609 } 1610 1611 /* @exdent: Start a new line with just this text on it. 1612 The text is outdented one level if possible. */ 1613 void 1614 cm_exdent (void) 1615 { 1616 char *line; 1617 int save_indent = current_indent; 1618 int save_in_fixed_width_font = in_fixed_width_font; 1619 1620 /* Read argument. */ 1621 get_rest_of_line (0, &line); 1622 1623 /* Exdent the output. Actually this may be a no-op. */ 1624 if (current_indent) 1625 current_indent -= default_indentation_increment; 1626 1627 /* @exdent arg is supposed to be in roman. */ 1628 in_fixed_width_font = 0; 1629 1630 /* The preceding newline already inserted the `current_indent'. 1631 Remove one level's worth. */ 1632 kill_self_indent (default_indentation_increment); 1633 1634 if (html) 1635 add_word ("<br>"); 1636 else if (docbook) 1637 xml_insert_element (LINEANNOTATION, START); 1638 else if (xml) 1639 xml_insert_element (EXDENT, START); 1640 1641 /* Can't close_single_paragraph, then we lose preceding blank lines. */ 1642 flush_output (); 1643 execute_string ("%s", line); 1644 free (line); 1645 1646 if (html) 1647 add_word ("<br>"); 1648 else if (xml) 1649 { 1650 xml_insert_element (docbook ? LINEANNOTATION : EXDENT, END); 1651 insert ('\n'); 1652 } 1653 1654 close_single_paragraph (); 1655 1656 current_indent = save_indent; 1657 in_fixed_width_font = save_in_fixed_width_font; 1658 if (!xml) 1659 start_paragraph (); 1660 } 1661 1662 /* 1663 Read include-filename, process the include-file: 1664 verbatim_include == 0: process through reader_loop 1665 verbatim_include != 0: process through handle_verbatim_environment 1666 */ 1667 static void 1668 handle_include (int verbatim_include) 1669 { 1670 char *arg, *filename; 1671 1672 if (macro_expansion_output_stream && !executing_string) 1673 me_append_before_this_command (); 1674 1675 if (!insertion_stack) 1676 close_paragraph (); /* No blank lines etc. if not at outer level. */ 1677 1678 get_rest_of_line (0, &arg); 1679 /* We really only want to expand @value, but it's easier to just do 1680 everything. TeX will only work with @value. */ 1681 filename = text_expansion (arg); 1682 free (arg); 1683 1684 if (macro_expansion_output_stream && !executing_string) 1685 remember_itext (input_text, input_text_offset); 1686 1687 pushfile (); 1688 1689 /* In verbose mode we print info about including another file. */ 1690 if (verbose_mode) 1691 { 1692 int i = 0; 1693 FSTACK *stack = filestack; 1694 1695 for (i = 0, stack = filestack; stack; stack = stack->next, i++); 1696 1697 i *= 2; 1698 1699 printf ("%*s", i, ""); 1700 printf ("%c%s `%s'\n", COMMAND_PREFIX, command, filename); 1701 fflush (stdout); 1702 } 1703 1704 if (!find_and_load (filename, 1)) 1705 { 1706 popfile (); 1707 line_number--; 1708 1709 /* /wh/bar:5: @include/@verbatiminclude `foo': No such file or dir */ 1710 line_error ("%c%s `%s': %s", COMMAND_PREFIX, command, filename, 1711 strerror (errno)); 1712 1713 free (filename); 1714 return; 1715 } 1716 else 1717 { 1718 if (macro_expansion_output_stream && !executing_string) 1719 remember_itext (input_text, input_text_offset); 1720 1721 if (!verbatim_include) 1722 reader_loop (); 1723 else 1724 handle_verbatim_environment (0); 1725 } 1726 free (filename); 1727 popfile (); 1728 } 1729 1730 1731 /* Include file as if put in @verbatim environment */ 1732 void 1733 cm_verbatiminclude (void) 1734 { 1735 handle_include (1); 1736 } 1737 1738 1739 /* Remember this file, and move onto the next. */ 1740 void 1741 cm_include (void) 1742 { 1743 handle_include (0); 1744 } 1745 1746 1747 /* @bye: Signals end of processing. Easy to make this happen. */ 1748 1749 void 1750 cm_bye (void) 1751 { 1752 discard_braces (); /* should not have any unclosed braces left */ 1753 input_text_offset = input_text_length; 1754 } 1755 1756 /* @paragraphindent */ 1757 1758 static void 1759 cm_paragraphindent (void) 1760 { 1761 char *arg; 1762 1763 get_rest_of_line (1, &arg); 1764 if (set_paragraph_indent (arg) != 0) 1765 line_error (_("Bad argument to %c%s"), COMMAND_PREFIX, command); 1766 1767 free (arg); 1768 } 1769 1770 1771 /* @exampleindent: change indentation of example-like environments. */ 1772 static int 1773 set_example_indentation_increment (char *string) 1774 { 1775 if (strcmp (string, "asis") == 0 || strcmp (string, _("asis")) == 0) 1776 ; 1777 else if (strcmp (string, "none") == 0 || strcmp (string, _("none")) == 0) 1778 example_indentation_increment = 0; 1779 else if (sscanf (string, "%d", &example_indentation_increment) != 1) 1780 return -1; 1781 return 0; 1782 } 1783 1784 static void 1785 cm_exampleindent (void) 1786 { 1787 char *arg; 1788 1789 get_rest_of_line (1, &arg); 1790 if (set_example_indentation_increment (arg) != 0) 1791 line_error (_("Bad argument to @%s"), command); 1792 1793 if (input_text[input_text_offset] == '\n') 1794 close_single_paragraph (); 1795 1796 free (arg); 1797 } 1798 1799 1800 /* @firstparagraphindent: suppress indentation in first paragraphs after 1801 headings. */ 1802 static int 1803 set_firstparagraphindent (char *string) 1804 { 1805 if (STREQ (string, "insert") || STREQ (string, _("insert"))) 1806 do_first_par_indent = 1; 1807 else if (STREQ (string, "none") || STREQ (string, _("none"))) 1808 do_first_par_indent = 0; 1809 else 1810 return -1; 1811 return 0; 1812 } 1813 1814 static void 1815 cm_firstparagraphindent (void) 1816 { 1817 char *arg; 1818 1819 get_rest_of_line (1, &arg); 1820 if (set_firstparagraphindent (arg) != 0) 1821 line_error (_("Bad argument to %c%s"), COMMAND_PREFIX, command); 1822 1823 free (arg); 1824 } 1825 1826 /* For DocBook and XML, produce . for `.@:'. This gives the processing 1827 software a fighting chance to treat it specially by not adding extra space. 1828 1829 Do this also for ?, !, and :. */ 1830 void 1831 cm_colon (void) 1832 { 1833 if (xml) 1834 { 1835 if (strchr (".?!:", input_text[input_text_offset-3]) != NULL) 1836 { 1837 /* Erase literal character that's there, except `>', which is 1838 part of the XML tag. */ 1839 if (output_paragraph[output_paragraph_offset-1] != '>') 1840 output_paragraph_offset--; 1841 1842 switch (input_text[input_text_offset-3]) 1843 { 1844 case '.': 1845 xml_insert_entity ("period"); 1846 break; 1847 case '?': 1848 xml_insert_entity ("quest"); 1849 break; 1850 case '!': 1851 xml_insert_entity ("excl"); 1852 break; 1853 case ':': 1854 xml_insert_entity ("colon"); 1855 break; 1856 } 1857 } 1858 } 1859 } 1860 1861 /* Ending sentences explicitly. Currently, only outputs entities for XML 1862 output, for other formats it calls insert_self. */ 1863 void 1864 cm_punct (int arg) 1865 { 1866 if (xml && !docbook) 1867 { 1868 switch (input_text[input_text_offset-1]) 1869 { 1870 case '.': 1871 xml_insert_entity ("eosperiod"); 1872 break; 1873 case '?': 1874 xml_insert_entity ("eosquest"); 1875 break; 1876 case '!': 1877 xml_insert_entity ("eosexcl"); 1878 break; 1879 } 1880 } 1881 else 1882 { 1883 insert_self (arg); 1884 } 1885 } 1886