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